[midPoint] My approach to FreeIPA server using LDAP Connector
Ernedin Zajko
ezajko at root.ba
Thu Mar 26 20:27:46 CET 2020
Hi Gustav,
that would be great, many of us would be very grateful
thanks in advance
On Thu, Mar 26, 2020 at 7:34 PM Pálos Gustáv <gustav.palos at gmail.com> wrote:
>
> Hi,
>
> We created a rest connector to manage users, groups, roles and memberships to keep business login on FreeIPA site. If you need, we can publish it...
>
> Best regards
>
> Gustav
>
> On Thu, 26 Mar 2020, 17:32 Wojciech Staszewski, <wojciech.staszewski at diagnostyka.pl> wrote:
>>
>> My approach to FreeIPA server using LDAP Connector
>>
>> Assumptions:
>>
>> - FreeIPA v4.6.x (or maybe newer),
>> - midPoint v3.9 or newer,
>> - LDAP Connector v2.0 or newer,
>> - Most important: Manage IPA users and group membership only.
>>
>> So, for those who don't know what FreeIPA (or IPA) server is: It is NOT a free beer! :(
>> Link: https://www.freeipa.org/
>>
>> FreeIPA is a bunch of Open Source blocks stuck together, but the most important for us is LDAP, a 389-ds in particular, hidden under the mask.
>> Another important piece is the Kerberos.
>>
>> Therefore the first thoughts is to use LDAP Connector. Well, there is dedicated IPA connector, but is dead I think, or at least its development is stalled long time ago.
>>
>> The challenge:
>>
>> - FreeIPA user account schema contains A LOT of ObjectClasses. Newly created IPA account has 14 ObjectClasses:
>>
>> objectClass: inetOrgPerson
>> objectClass: ipaObject
>> objectClass: mepManagedEntry
>> objectClass: posixGroup
>> objectClass: top
>> objectClass: inetuser
>> objectClass: ipaNTUserAttrs
>> objectClass: ipaObject
>> objectClass: ipaSshGroupOfPubKeys
>> objectClass: ipaSshUser
>> objectClass: krbPrincipalAux
>> objectClass: krbTicketPolicyAux
>> objectClass: mepOriginEntry
>> objectClass: posixAccount
>>
>> - LDAP Connector doesn't like many object classes. Why?, you may ask...
>>
>> Example: ipaNTUserAttrs ObjectClass REQUIRES some attributes, for instance: ipaNTSecurityIdentifier provided in the format below:
>> S-1-5-21-17112102435-2119056689-2123461762-1015
>> The last part: "1015" is an incremental number, everything before is constant.
>> The attribute value must be compound, we have constant first part and calculate next free number for the last part, so we have to read the max value from LDAP and increase it by 1.
>> This value MUST be known at the moment of account creation. The DNA plugin is good for simple tasks, such POSIX UID and GID calculation, but this is something we have to calculate ourselves.
>>
>> There is a lot of problems like that.
>> I tried to configure the LDAP resource to set the "inetOrgPerson" as default ObjectClass and all the rest as auxiliary object classes, and I failed because of so many different errors.
>>
>> Working solution:
>>
>> - The LDAP account has only one ObjectClass defined in midPoint Schema Handling.
>> All the rest is made using "scripting" functionality of the connector AFTER "create account" operation.
>>
>> Problem:
>> If the account is created, and THEN its schema is extended, some requied attributes are still missing,
>> for example "krbExtraData" and "krbPrincipalKey" which are binary data created during password change.
>> But the password is already set.
>>
>> So creation of an LDAP account for IPA must be done in 3 steps:
>> 1. create LDAP account with inetOrgPerson ObjectClass only,
>> 2. extend the account schema - add missing ObjectClasses and all required attributes (scripting functionality),
>> 3. set the password again for the missing Kerberos data (scripting functionality).
>>
>> The account created this way works good, it is visible in FreeIPA User Interface, we can login to our Linux boxes using this account, Kerberos tickets work OK.
>>
>> MidPoint part:
>>
>> 1) Resource XML
>>
>> Almost everything is standard for common LDAP resource, schema handling, mappings, etc. - nothing really sophisticated.
>> These are some the parts worth mentioning:
>>
>> <icfc:configurationProperties>
>> <objectClassesToSynchronize>top</objectClassesToSynchronize>
>> <objectClassesToSynchronize>person</objectClassesToSynchronize>
>> <objectClassesToSynchronize>organizationalPerson</objectClassesToSynchronize>
>> <objectClassesToSynchronize>inetUser</objectClassesToSynchronize>
>> <objectClassesToSynchronize>inetOrgPerson</objectClassesToSynchronize>
>> </icfc:configurationProperties>
>>
>> <schema>
>> <generationConstraints>
>> <generateObjectClass>ri:top</generateObjectClass>
>> <generateObjectClass>ri:person</generateObjectClass>
>> <generateObjectClass>ri:organizationalPerson</generateObjectClass>
>> <generateObjectClass>ri:inetUser</generateObjectClass>
>> <generateObjectClass>ri:inetOrgPerson</generateObjectClass>
>> <generateObjectClass>ri:ipaNTUserAttrs</generateObjectClass>
>> <generateObjectClass>ri:ipaObject</generateObjectClass>
>> <generateObjectClass>ri:ipaSshGroupOfPubKeys</generateObjectClass>
>> <generateObjectClass>ri:ipaSshUser</generateObjectClass>
>> <generateObjectClass>ri:krbPrincipalAux</generateObjectClass>
>> <generateObjectClass>ri:krbTicketPolicyAux</generateObjectClass>
>> <generateObjectClass>ri:mepOriginEntry</generateObjectClass>
>> <generateObjectClass>ri:posixAccount</generateObjectClass>
>> <generateObjectClass>ri:groupOfNames</generateObjectClass>
>> <generateObjectClass>ri:ipaNTGroupAttrs</generateObjectClass>
>> <generateObjectClass>ri:ipaUserGroup</generateObjectClass>
>> <generateObjectClass>ri:nestedGroup</generateObjectClass>
>> <generateObjectClass>ri:posixGroup</generateObjectClass>
>> <generateObjectClass>ri:ipaHostGroup</generateObjectClass>
>> <generateObjectClass>ri:ipaPermission</generateObjectClass>
>> </generationConstraints>
>> </schema>
>>
>> <schemaHandling>
>> <!-- Allmost all attributes require "explicit" fetchStrategy!!! -->
>> <...>
>> <fetchStrategy>explicit</fetchStrategy>
>> </...>
>> </schemaHandling>
>>
>> <scripts>
>> <script>
>> <host>connector</host>
>> <language>Groovy</language>
>> <argument>
>> <name>username</name>
>> <c:path xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="t:ItemPathType">$focus/name</c:path>
>> </argument>
>> <argument>
>> <name>pass</name>
>> <c:path xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="t:ItemPathType">$focus/credentials/password/value</c:path>
>> </argument>
>> <code>
>> println "/opt/midpoint/scripts/freeipa/after_add.sh $username $pass".execute().text</code>
>> <operation>add</operation>
>> <order>after</order>
>> </script>
>> </scripts>
>>
>> 2) The Bash script:
>>
>> #!/bin/bash
>>
>> server='ipaserver.ipa.domain.ltd'
>> user='cn=Directory Manager'
>> password='LDAP PASSWORD'
>> basedn='dc=ipa,dc=domain,dc=ltd'
>> userid=$1
>> pass=$2
>>
>> #last value for ipaNTSecurityIdentifier
>> declare i ipaNTSecurityIdentifier=`ldapsearch -H ldap://$server -x -w $password -D "$user" -b "$basedn" '(objectClass=inetOrgPerson)' ipaNTSecurityIdentifier|grep ipaNTSecurityIdentifier|rev|cut -d "-" -f 1|rev|sort|tail -1`
>> nextNTSecurityIdentifier=S-1-5-21-1453210229-2669001626-2403961664-$(($ipaNTSecurityIdentifier+1))
>>
>> #last UID i GID - Posix
>> declare i olduid=`ldapsearch -H ldap://$server -x -w $password -D "$user" -b "$basedn" '(objectClass=inetOrgPerson)' uidNumber|grep uidNumber|cut -d " " -f 2|tail -1`
>> NEWUID=$(($olduid+1))
>> declare i oldgid=`ldapsearch -H ldap://$server -x -w $password -D "$user" -b "$basedn" '(objectClass=inetOrgPerson)' gidNumber|grep gidNumber|cut -d " " -f 2|tail -1`
>> NEWGID=$(($oldgid+1))
>>
>> cat > /tmp/ipa_add_group_$userid.ldif <<EOF
>> dn: cn=$userid,cn=groups,cn=accounts,$basedn
>> objectClass: ipaObject
>> objectClass: mepManagedEntry
>> objectClass: posixGroup
>> objectClass: top
>> cn: $userid
>> gidNumber: $NEWGID
>> description: User private group for $userid
>> mepManagedBy: uid=$userid,cn=users,cn=accounts,$basedn
>> EOF
>>
>> /usr/bin/ldapmodify -h $server -x -w $password -D "$user" -a -f /tmp/ipa_add_group_$userid.ldif
>>
>>
>>
>> cat > /tmp/ipa_add_$userid.ldif <<EOF
>> dn: uid=$userid,cn=users,cn=accounts,$basedn
>> changetype: modify
>> add: objectClass
>> objectClass: inetuser
>> -
>> add: objectClass
>> objectClass: ipaNTUserAttrs
>> -
>> add: objectClass
>> objectClass: ipaObject
>> -
>> add: objectClass
>> objectClass: ipaSshGroupOfPubKeys
>> -
>> add: objectClass
>> objectClass: ipaSshUser
>> -
>> add: objectClass
>> objectClass: krbPrincipalAux
>> -
>> add: objectClass
>> objectClass: krbTicketPolicyAux
>> -
>> add: objectClass
>> objectClass: mepOriginEntry
>> -
>> add: objectClass
>> objectClass: posixAccount
>> -
>> add: homeDirectory
>> homeDirectory: /home/$userid
>> -
>> add: loginshell
>> loginshell: /bin/bash
>> -
>> add: ipaNTSecurityIdentifier
>> ipaNTSecurityIdentifier: $nextNTSecurityIdentifier
>> -
>> add: uidNumber
>> uidNumber: $NEWUID
>> -
>> add: gidNumber
>> gidNumber: $NEWGID
>> -
>> add: krbCanonicalName
>> krbCanonicalName: $userid at IPA.DOMAIN.LTD
>> -
>> add: krbPrincipalName
>> krbPrincipalName: $userid at IPA.DOMAIN.LTD
>> -
>> add: preferredLanguage
>> preferredLanguage: YourLangHere
>> -
>> add: gecos
>> gecos: $userid
>> -
>> add: mepManagedEntry
>> mepManagedEntry: cn=$userid,cn=groups,cn=accounts,$basedn
>> EOF
>>
>> /usr/bin/ldapmodify -h $server -x -w $password -c -D "$user" -f /tmp/ipa_add_$userid.ldif
>>
>> # Change password once again!
>> cat > /tmp/ipa_password_$userid.ldif <<EOF
>> dn: uid=$userid,cn=users,cn=accounts,$basedn
>> changetype: modify
>> replace: userPassword
>> userPassword: $pass
>> EOF
>>
>> /usr/bin/ldapmodify -h $server -x -w $password -c -D "$user" -f /tmp/ipa_password_$userid.ldif
>>
>> rm -f /tmp/ipa_add_$userid.ldif
>> rm -f /tmp/ipa_add_group_$userid.ldif
>> rm -f /tmp/ipa_ipausers_$userid.ldif
>> rm -f /tmp/ipa_password_$userid.ldif
>>
>> ##########
>> If you know the better way, please let me know.
>> Best Regards!
>> WS
>>
>> _______________________________________________
>> midPoint mailing list
>> midPoint at lists.evolveum.com
>> https://lists.evolveum.com/mailman/listinfo/midpoint
>
> _______________________________________________
> midPoint mailing list
> midPoint at lists.evolveum.com
> https://lists.evolveum.com/mailman/listinfo/midpoint
--
--- eZ
More information about the midPoint
mailing list