Jump to: navigation, search

IPAv3 AD trust

Trusts in FreeIPA

FreeIPA supports trusts with AD since version 3.0. Various features were added in following releases and this page attempts to describe most up to date behavior. Always check FreeIPA documentation by running 'ipa trust' and 'ipa <command> --help' commands. You can use Active Directory trust setup page for instructions on how to test it.

The remainder of this page goes through logic of working with trusts from technical and UX points of view.

Trusts in pictures

The very basic concept described in pictures (not technically precise!) can be found in presentation File:Users-in-IPA-AD-Trusts.odp.

The 3 slides are about SSO authentication, password based authentication and how the Linux side provides the POSIX information to the IPA Client after authentication even though there is no real user object in the IPA LDAP server itself.

Cross-forest realm trusts between FreeIPA and Active Directory: a development view

Trust primer

Both Active Directory domain and FreeIPA deployments can be seen as Kerberos realms. Active Directory domain can be configured to trust MIT Kerberos realm as described in the "Step-by-Step Guide to Kerberos 5 Interoperability" document at http://technet.microsoft.com/en-us/library/bb742433.aspx#ECAA.

Users and groups in Active Directory are assigned with uniform identifiers at the moment of the creation, called Security IDentifiers (SIDs).These identifiers bear relationship with the domain they are part of. Access control checks in Active Directory are built around use of SIDs and in any file access or SMB session access there is a check of an accessor's SID against the access control list (ACL) associated with the object or API interface that is going to be accessed.

Such uniform handling of access controls means any other protocol authentication like Kerberos or LDAP would always end up in finding a SID which represents an accessor. When Active Directory domain trusts another Active Directory domain, name to SID (and SID to name) resolution is delegated to the domain controller of the domain owning the object. When Active Directory domain trusts MIT Kerberos realm there is no domain controller to talk to. Instead, a manual configuration to map foreign Kerberos identities to a local account identities in the corresponding domain should be performed. For example, a MIT Kerberos identity foo@MIT.DOMAIN would have to be mapped first to an AD\User local account in order to impersonate AD\User using a ticket from a MIT kerberos realm MIT.DOMAIN.

The same configuration requirement applies to a AD\User identity willing to access resources in a MIT Kerberos realm MIT.DOMAIN with the help of its User@AD.DOMAIN Kerberos identity.

From SMB session perspective, Active Directory domain trust to another Active Directory domain is seen as ability to authenticate with a special purpose account against the domain's domain controller and Kerberos KDC. As a mixture between its past NT domain and Kerberos heritage, Active Directory domain has a short domain name, often called NetBIOS domain name, and its Kerberos realm name. The Kerberos realm name is always the same as its DNS domain name in case of Active Directory domain. In addition, Active Directory domains are case insensitive, so realm ad.domain is the same as AD.DOMAIN. However, NetBIOS domain name has its own limitations as described in http://support.microsoft.com/kb/909264, including maximum name size of 15 characters. By default, leftmost component of the DNS name is used as a NetBIOS domain name, so Active Directory domain named ad.domain by default would have AD as its NetBIOS domain name.

If two Active Directory domains, ad1.domain and ad2.domain, are in trust, then ad1.domain would be able to authenticate against ad2.domain's domain controller using account AD1$ from ad2.domain. If this trust is bi-directional, then ad2.domain will be able to authenticate against ad1.domain's domain controller using account AD2$ from ad1.domain. This is true for both SMB session authentication and Kerberos authentication. In the latter case ad1.domain's domain controller would use AD1$@AD2.DOMAIN Kerberos identity to represent itself and ad2.domain's domain controller will be able to map this identity to a local account AD1$.

These special accounts are created using MS-RPC protocol calls. MS-RPC calls can be issued over different transports and there are some limitations which calls could be performed over which transports. There are certain complication as, for example, name resolution calls could be performed over ncacn_ip_tcp (TCP/IP) transport and not via ncacn_np (SMB), while querying policy information is possible only over ncacn_np (SMB) transport.

Trust accounts also share common password, meaning AD1$ account in ad2.domain has the same password as AD2$ account in ad1.domain. They cannot be created in the same way as normal user or machine accounts, there are dedicated MS-RPC calls for the purpose. In addition, before Active Directory domain's domain controller starts trusting another Active Directory domain, a verification procedure has to be performed, to check that AD1$ account is indeed existing in ad2.domain and is usable for MS-RPC operations.

Establishing trust

When operation to establish trust is requested, ad1.domain domain controller will have no credentials to create trust account object in ad2.domain. To do so, one needs privileges associated with Domain Admins group of ad2.domain. Thus, without such privileges only a local (ad1.domain's) part of the trust accounts pair could be created.

When enough privileges are available, establishing bi-directional trust boils down to the following sequence of SMB calls:

0. Prerequisites:
   1. Credentials for accessing AD1 domain, within Domain Admins group
   2. Credentials for accessing AD2 domain, within Domain Admins group

1. Connect to the AD1 domain primary domain controller and get its information
   1. Make IPC$ connection
   2. Open LSA pipe without authentication
   3. Issue LSA OpenPolicy2 call with following flags:
            (LSA_POLICY_VIEW_LOCAL_INFORMATION |
             LSA_POLICY_TRUST_ADMIN |
             LSA_POLICY_CREATE_SECRET)
   4. Issue LSA QueryInfoPolicy2 call to get DNS info level
            LSA_POLICY_INFO_DNS
      Gives us domain name and DNS domain name, along with domain SID

2. Do the same for AD2 domain primary domain controller

3. Create trust
   1. Generate trust password (128 chars) if not provided explicitly
   2. Create trust domain password authentication blob:
      auth type TRUST_AUTH_TYPE_CLEAR
      password converted to UTF16
   3. Encrypt blob RC4 using connection user session key to AD1 PDC
   4. Establish trust at AD1 domain side
   5. Encrypt blob RC4 using connection user session key to AD2 PDC
   6. Establish trust at AD2 domain side

Establish trust subsequence is following:

1. Issue LSA CreateTrustedDomainEx2 call with following parameters:
     direction    LSA_TRUST_DIRECTION_INBOUND | LSA_TRUST_DIRECTION_OUTBOUND
     type         LSA_TRUST_TYPE_UPLEVEL
     attributes   LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE

2. Issue LSA SetInformationTrustedDomain call to define set of supported encryption
   classes:
     enc_types = KERB_ENCTYPE_RC4_HMAC_MD5 | 
                 KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 |
                 KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96

FreeIPA trust

As can be seen from the sequences above, the core operation of establishing trust is CreateTrustedDomainEx2 call performed on LSA (Local Security Authority) pipe available through SMB protocol. The same call is used to establish trusts between 'normal' SMB domains, the only difference is that in case of Active Directory domains there is assumption that the very same trust account can be used to obtain Kerberos ticket issued by the domain's KDC.

There are two outcomes from this fact. First, Samba server could be used to respond to incoming CreateTrustedDomainEx2 LSA call. Second, the result of this operation should be visible to Kerberos KDC of FreeIPA as an account that could be used to obtain a Kerberos ticket. In addition, KDC will need to be able to deal with tickets produced by a trusted domain's KDC.

A Kerberos ticket issued by Active Directory domain's KDC contains special information called MS-PAC, Privilege Attribute Certificate Data Structure, http://msdn.microsoft.com/en-us/library/cc237917.aspx, stored as part of Kerberos AuthorizationData structure (RFC4120, section 5.2.6). MS-PAC contains authorization information, which consists of a group membership, additional credentials information, profile and policy information, and supporting security metadata. Authorization information in the MS-PAC structure refers to SIDs of objects in an Active Directory domain.

Since MS-PAC is signed by the trusted domain's KDC at the moment when ticket was issued, the trusting party can use it after signature verification to decide how to map the Kerberos identity to a trusting domain account.

From POSIX system perspective we need to have an account that has UID (and GID) associated so that processes executed under the account would have defined UID and GID, and supplemental GIDs, if any.

Mapping of trusted Kerberos identities

This is where Active Directory and POSIX world differ. When access control operation is performed in Active Directory, list of SIDs is checked against existing access control list associated with the object that is accessed. ACL can contain many SIDs and since SIDs have uniform structure, spanning across multiple domains, they can be used directly in the checks without consulting remote domain controllers. This allows for authorization information caching and levies some load from the domain controllers.

In POSIX environment UID and GID information is local to the host where application is executed. On most POSIX-compatible operating systems today, with the help of name service switch interface in libc, it is possible to plug different mechanisms for resolving names to UIDs and GIDs against global sources. FreeIPA sister project, SSSD, on GNU/Linux supplies its own mechanism that works best with FreeIPA's LDAP server. If user or group exists in LDAP, SSSD can fetch and cache its information locally, including associated UIDs and GIDs.

When SSSD PAM provider responds for authorization requests involving Kerberos tickets from trusted domain, if the ticket contains MS-PAC structure, SSSD can extract group membership and credentials information from the ticket, in form of SIDs. This information is then used to retrieve corresponding UID and GID via SSSD IPA provider.

In case of trusted domain's users, information about them does not exist in FreeIPA's LDAP server and cannot be directly consulted via SSSD NSS provider. However, FreeIPA's LDAP server contains also information about configured trusted domains.

SSSD IPA provider includes special sub-provider that knows how to handle trusted domains for FreeIPA. It consults FreeIPA LDAP server via special interface to convert SIDs to UIDs and GIDs, and SIDs to names.

For SID to UID conversion FreeIPA plugin to LDAP server that responds to this request uses defined UID range for the trusted domain in question to map SIDs to UIDs with a predefined algorithm. The plugin calculates UID and makes primary GID of the account equal to the calculated UID value.

For SID to name conversion there are two different paths.

For FreeIPA before 3.3, FreeIPA plugin to LDAP server uses winbind interface pipe on FreeIPA server to talk to winbindd process, part of Samba suite. Winbindd then uses configured trust information stored in FreeIPA LDAP server to discover proper Active Directory domain's domain controller and ask it either via MS-RPC call on LSA pipe or via LDAP request to the trusted domain's Global Catalog to resolve SID to name.

In Freeipa 3.3 and above FreeIPA plugin to LDAP server uses SSSD instead of winbind interface pipe on FreeIPA server to talk to the proper Active Directory domain's domain controller and Global Catalog service to resolve SID to name.

For name to SID translation same interface is used. In this case it is crucial to know trusted domain to ask for the translation, thus the name should be fully qualified, either as AD\User or User@AD.DOMAIN form. SSSD uses domain part of the name to discover that sub-provider needs to be consulted.

As result, users from trusted domain never stored in FreeIPA LDAP server. Instead, information from Kerberos ticket (if available) is used to discover information about them via FreeIPA server. If MS-PAC structure or Kerberos ticket as a whole is not available, then fully-qualified name of the identity is used to decide whether trusted domain user is attempting to log in and name resolution is performed on FreeIPA server.

Thus, FreeIPA cross-forest realm trust setup involves use of Samba suite, set up on FreeIPA server only. All FreeIPA clients are using Samba suite indirectly but free from the requirement to have Samba configured and running on them. There is a requirement to run SSSD on them, though, in case these clients should be accessible to the trusted domain users.

Another consequence of this approach is the fact that each trusted domain user has its own private primary group. It is inconvenient for access-control purposes since group definitions from trusted domain cannot be used directly to group users' UIDs. In order to solve this issue FreeIPA introduces concept of groups referencing SIDs from trusted domains as their members. These groups are non-POSIX, they cannot have GID associated with them. However, non-POSIX groups can be included into POSIX groups in FreeIPA LDAP since its schema supports nested group membership. In such case POSIX group's GID will be associated with SID of the external user or group.

Trust logic

Please note that description below needs updating since command line interface and Web UI are implemented and released in 3.0.

Samba3 includes 'net rpc trust' command designed to set up trusts against AD.

Below is a short description of the logic of trust joining.

  1. Connect to the OUR domain controller and get its information
    1. Make IPC$ connection
    2. Open LSA pipe without auth
    3. Issue LSA OpenPolicy2 call with following flags:
      (LSA_POLICY_VIEW_LOCAL_INFORMATION |
      LSA_POLICY_TRUST_ADMIN |
      LSA_POLICY_CREATE_SECRET)
    4. Issue LSA QueryInfoPolicy2 call to get DNS info level
      LSA_POLICY_INFO_DNS
      Gives us domain name and DNS domain name, along with domain SID
  2. Do the same for AD domain controller

3a. Create trust

  1. Generate trust password (8 chars) if not provided.
  2. Create trust domain password authentication blob:
    auth type TRUST_AUTH_TYPE_CLEAR
    password converted to UTF16
  3. Encrypt blob RC4 using connection user session key to OUR PDC
  4. Establish trust at OUR domain side
  5. Encrypt blob RC4 using connection user session key to AD PDC
  6. Establish trust at AD domain side

3b. Delete trust

  1. Issue LSA DeleteTrustedDomain with domain SID argument

Establish trust:

  1. Issue LSA CreateTrustedDomainEx2 with following parameters:

direction = LSA_TRUST_DIRECTION_INBOUND | LSA_TRUST_DIRECTION_OUTBOUND
type = LSA_TRUST_TYPE_UPLEVEL
attributes = LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
access mask = LSA_TRUSTED_SET_POSIX | LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_QUERY_DOMAIN_NAME

Trust arguments

In order to establish the trust, one needs access to the both domain controllers. Therefore, there should be credentials for on both sides. With FreeIPA using Kerberos to authenticate management operations automatically, we can re-use admin Kerberos ticket to obtain ticket for CIFS service.

For Active Directory management part there are two variants:

  1. We have credentials (username and password) of the Active Directory user authorized to manage trusts (Admins group or Entperise admins group). In this case we can use the credentials to establish the trust ourselves.
  2. We have no credentials and therefore we can't manage trusts on Active Directory side. In case Active Directory admin has used Windows management UI to define AD part of the trust, a shared secret for the trust is required to finish the trust operation on our side.

If Active Directory admin does not want to delegate credentials to create trusts and instead creates the AD trust part himself, he needs to know information about our domain (domain SID, GUID, etc.). We also need to know the same information about Active Directory domain plus shared secret to setup the trust on our side.

Thus, depending on who creates what first, the user flow would be either:

IPA UI shows our domain info -> AD admin use the info to setup the trust -> return shared trust secret to IPA admin -> IPA admin setups the trust by pointing IPA UI to AD server + giving shared trust server.

or

IPA UI shows our domain info -> IPA admin creates trust part by pointing to AD server for discovery -> IPA UI displays a page of instructions to AD admin (our domain info + shared trust secret + instructions for setting the trust) -> IPA admin prints the page (to PDF, for example) and passes it to AD admin -> AD admin sets up the trust part.

Possible CLI and UI flows detailed

ipa trust-add-ad ad.local
   1. My credentials (kerberos ticket)
   2. AD domain
   3. Miss AD admin creds
   4. Miss shared secret
result:
   1. Generate shared secret
   2. Discover anonymously AD domain/realm
   3. Set up local trust part
   4. Display instructions and info for windows admin to setup the remote trust part

ipa trust-add-ad ad.local --realm-admin=AD\Administrator
   1. My credentials (kerberos ticket)
   2. AD domain
   3. AD admin creds (will be asked for the password)
   4. Miss shared secret
result:
   1. Generate shared secret
   2. Discover AD domain/realm with AD admin creds
   3. Setup local trust part
   4. Setup remote trust part
   5. Verify remote trust working
   6. Display info, result of verification, and instructions how to use the trust

ipa trust-add-ad ad.local --shared-secret=ABCD
   1. My credentials (kerberos ticket)
   2. AD domain
   3. Shared secret
   4. Miss AD admin creds
result:
   1. Discover anonymously AD domain/realm
   2. Setup local trust part
   3. Verify remote trust working
   4. Display info and result of verification

Samba

Samba4 by default links against Heimdal kerberos libraries that are bundled with it. Heimdal and MIT kerberos implementations are different in certain areas, especially in areas of S4U2Proxy support and keys loading from keytabs.

In order to get properly working MIT krb5-based Samba4 build one have to use --without-ad-dc --with-system-mitkrb5 options when configuring WAF top level build.

The support for these options is available in Samba4 beta2.