Tour of FreeIPA
389-DS plugins

Alexander Bokovoy

Sr. Principal Software Engineer, Red Hat

FreeIPA and 389-DS directory Server

FreeIPA utilizes 389-ds Directory Server as its core component:

  • LDAP database with a flat directory tree:
    • All similar objects are in the same container
      • cn=users,cn=accounts,$SUFFIX
      • cn=groups,cn=accounts,$SUFFIX
      • cn=computers,cn=accounts,$SUFFIX
      • cn=services,cn=accounts,$SUFFIX
      • ...
  • Access to the objects is defined in terms of 389-DS ACIs
    • ACI: a rule that says how an LDAP bind can access certain sub-trees or individual records. Can be specified down to an individual attribute
    • All objects with a password-like (users, computers, services) can be configured to access data with a permission-privilege-role in freeIPA, it translates to a set of ACIs internally

FreeIPA and 389-DS directory Server

  • Objects with a password
    • LDAP schema defines attributes and object classes
      • userPassword attribute is used to represent a password

      • multivalued attribute, may represent multiple password forms (different hashes, clear text)

    • In standard LDAP schemas many object classes can have passwords:

      • organization, person, organizationalUnit, domain, simpleSecurityObject, posixAccount, shadowAccount, posixGroup, ipHost
    • LDAP bind process is done by comparing a clear-text bind password with hashed values of the userPassword attribute in the bind DN entry
      • There are multiple 'password storage scheme' plugins  for hash generation in 389-ds
      • However, 389-ds does not know about multi-factor authentication, so 2FA does not work directly

FreeIPA and 389-DS directory Server

  • LDAP password change process
    • Traditionally LDAP client either modifies userPassword attribute values directly or provides a clear text
      • LDAP modify accepts 'whatever' is given and performs modification of just that specific value
      • LDAP password change operation accepts a clear text
    • What to do if clear text password is provided to modify userPassword but there is no clear text version in the userPassword attribute?
      • 389-ds needs to hash the clear text password to find out which hash would match
  • Password policy is applied to clear text password on a change
    • Policies are flexible but they assume access to clear text passwords at the change time
  • 389-ds password change process cannot create multiple hashes out of the same clear text password
    • Only default password hash type is used

FreeIPA and 389-DS directory Server

  • Kerberos principals
    • LDAP server utilizes SASL to abstract authentication
      • SASL GSSAPI or SASL SPNEGO mechanisms allow using Kerberos
    • LDAP server does not check password for Kerberos authentication
      • 3-way negotiation is performed in Kerberos
        • A client authenticates itself against KDC
        • Client uses a service ticket obtained from KDC to talk to 389-ds
        • 389-ds decodes the provided ticket using its own key
      • At no point LDAP server has any idea how client authenticated to KDC
        • if SASL GSSAPI or SASL SPNEGO authentication is successful, LDAP server maps authenticated identity to LDAP object
        • LDAP object's DN becomes the 'bind DN' for the rest of access control checks

FreeIPA and 389-DS directory Server

  • Kerberos principal password change
    • LDAP object for kerberos principal has a separate attribute for its Kerberos key
    • 389-ds does not know how to generate it from a clear text password
    • 389-ds does not know how to apply Kerberos password policy
  • Password change from KDC side
    • KDC uses LDAP driver that knows freeIPA LDAP schema
    • It directly stores computed Kerberos keys in LDAP
    • It applies Kerberos password policy

LDAP operation handling: plugins

389-ds plugins handle multiple operation types

they executed before or after a specific LDAP operation

 

  • 389-ds has more than 80 points that can be overridden in the processing of LDAP operation
  • freeIPA plugins override some of them where it makes sense
  • Most common operations:
    • ADD (pre- and post-)
    • MODIFY (pre- and post-)
    • BIND (pre- and post-)
    • DELETE (pre- and post-)
    • MODRDN (pre- and post-)

Password handling: ipa-pwd-extop

 

  • ipa-pwd-extop:
    • freeIPA plugin to handle password-related operations
      • pre-BIND:
        • Password migration
        • 2FA validation and synchronization
      • pre-MODIFY and pre-ADD:
        • password policy check
        • (re)generate password keys for Kerberos
        • (re)generate password hashes for Samba
      • post-MODIFY and post-ADD:
        • password history update
        • password expiration for Kerberos keys
          • krbPasswordExpiration is set for hosts
          • krbLastPwdChange is set for all other entries
        • 2FA configuration update

Password handling: ipa-pwd-extop

 

  • ipa-pwd-extop:
    • Keytab generation: special LDAP extended operation
      • v1: set Kerberos key for a principal based on what client did send
      • v2: two separate operations
        • generate Kerberos key for a principal at the server side, return key to the client
        • allow retrieval of the existing Kerberos key

Account handling: ipa-lockout

 

  • ipa-lockout: blend LDAP authentication and Kerberos policies together
    • pre-BIND:
      • applies lockout policy:
        • denies BIND for a specified time interval if krbLoginFailedCount is above krbPwdMaxFailure value from the policy associated with the bind DN
    • post-BIND:
      • update Kerberos password policy attributes after successful or unsuccessful LDAP BIND operation
        • on unsuccessful BIND
          • updates krbLoginFailedCount
          • updates krbLastFailedAuth
        • on successful BIND
          • resets krbLoginFailedCount
          • updates krbLastSuccessfulAuth if IPA config allows it

Host enrollment: ipa-enrollment

 

  • ipa-enrollment: enroll a host into IPA domain
    • implements special LDAP extended operation:
      • on TLS-protected LDAP connection
        • adds Kerberos attributes to the host entry which is being enrolled
        • returns Kerberos principal name for this host
    • Allows only to require write access to userPassword to enroll a host
  • Called by ipa-join
    • after ipa-enrollment LDAP extended operation succeeded, ipa-getkeytab is used to retrieve new Kerberos key

DNS zone handling: ipa-dns

 

  • ipa-dns: handle DNS zone serial number during replication
    • if replicated DNS zone has no idnsSOAserial attribute, add '1'
  • Yes, that's all it does. :)

Handle name changes IN LDAP: ipa-modrdn

 

  • ipa-modrdn: update attributes after RDN rename
    • each object in LDAP has RDN value that is unique within the container
    • for many objects there are related attributes which should follow RDN value
      • user has uid and krbPrincipal
      • host has fqdn and krbPrincipal
  • post-MODRDN:
    • update attributes defined in a plugin configuration to use new RDN value

Multifactor authentication

 

  • ipa-otp-counter: handle consistency of 2FA token atomically
    • HOTP token has a counter (number of times it was used)
    • TOTP token has a watermark
    • The plugin enforces the change to them to be consistent
      • replaces MODIFY operation to a pair of DELETE/ADD operations
      • sanity checks for DELETE operations against token counter/watermark
    • Special replication handling:
      • replication may be dropped due to a lower CSN value by 389-ds but it may contain a higher watermark/counter and this value needs to be recorded even if replication was dropped
      • clear of a replication operation that doesn't cause actual change of the counters locally to reduce replication traffic during authentication
  • ipa-otp-lasttoken: make sure last 2FA token cannot be deleted if password authentication is not enabled for the user

unique identifiers: ipa-uuid

 

  • ipa-uuid: generate unique identifier
  • Many objects in freeIPA have no explicitly defined RDNs
    • HBAC rules, SUDO rules, etc
  • All LDAP objects need to have unique identifiers too
    • 389-ds has own unique identifier but it is used for replication and generally is not guaranteed to stay the same in case of replication conflicts
  • We generate unique identifiers using UUID syntax based on the current time
  • A configuration may be defined to say which attribute should be automatically generated for which object type

ID range checks: ipa-range-check

 

  • ipa-range-check: keep ID ranges consistent
  • ID ranges
    • ID ranges used by SSSD to map SIDs of Active Directory users and groups to UID and GID values
    • ID ranges used by SID generation plugin to assign SIDs to IPA users and groups based on their UID and GID values
  • This plugin prevents adding ID range which would overlap with already existing ones
    • handles ID range additions coming from outside freeIPA framework

SID generation plugin: ipa-sidgen

 

  • ipa-sidgen: generate SID for a user or a group
  • SID: security identifier in Active Directory or SMB world
    • uniform identifier, similar to UUID but with logical parts for domain and an object within the domain
  • The plugin generates SID value for objects within IPA domain based on existing ID ranges and UID/GID values of the objects

Connectionless LDAP: ipa-cldap

 

  • ipa-cldap: implements domain controller discovery in Active Directory way
  • Windows machines discover closest domain controller using connectionless LDAP requests: LDAP over UDP
    • special form of LDAP query is used
    • special binary structure is returned
  • The plugin returns information about IPA host and domain in a format expected by AD DCs
  • 389-ds does not listen on UDP port, so this is a special plugin that implements a separate transport

Identity retrieval: ipa-extdom-extop

 

  • ipa-extdom-extop: extended LDAP operation to request identity information about users and groups from trusted Active Directory forests
  • Core of trust to Active Directory feature
    • SSSD on IPA clients uses this LDAP extended operation to query information about AD users/groups or convert SIDs to UID/GIDs
    • Requests passed to the SSSD running on the IPA master
    • Responses returned back to SSSD on IPA clients
  • See https://jhrozek.wordpress.com/2015/08/19/performance-tuning-sssd-for-large-ipa-ad-trust-deployments/ for details of how SSSD talks to IPA master

Windows synchronization: ipa-winsync

 

  • ipa-winsync: synchronize users between IPA and Active Directory
  • A stripped-down version of winsync plugin from 389-ds
    • Intercepts replication requests from AD DC side sent by a winsync plugin there
    • Modifies user details to follow IPA schema (objectclasses and attributes)
      • enforces low-case uid
      • derives uid from samAccountName
      • adds krbPrincipalName based on uid
      • adds homeDirectory based on uid
      • adds default loginShell
    • Filters out changes done on IPA side before sending them back to AD DC
  • The plugin is on a life-support. It works but is not recommended for deployment as trust to Active Directory gives much better way of integrating between the two domains.

Replication version check: ipa-version

 

  • ipa-version: prevent replication between IPA and non-IPA LDAP servers
  • The plugin ensures that replication is only done between IPA servers
  • We are not interested in:
    • LDAP schema conflicts
    • Incompatible LDAP tree structure

Thanks!