Support domain controller for Samba file server as domain member on IPA client


Samba is a free software that implements various aspects of SMB protocol and Active Directory infrastructure. Apart from the networking file system that SMB is well known for, Samba provides services to resolve user and group identities for resources accessible via SMB. SMB protocol identity model is based on a Windows NT concept of security identifiers (SIDs) and access control lists (ACLs) which is not directly compatible with a concept of identities employed in POSIX environment model. Thus, Samba suite serves as a translation layer between the two environments.

Active Directory is an extension of Windows NT identity model where identity information is stored in a database exposed to the world via a combination of LDAP and SMB protocols, with authentication provided with both password (NTLMSSP) and Kerberos methods. Systems in Active Directory are organized into logical groups, domains, where some nodes, domain controllers, are used to store domain-specific information and others, domain members, utilize the information via SMB, LDAP, and Kerberos protocols.

SMB protocol has a mechanism for encapsulating and channeling through itself other types of requests, expressed as an access to “files” over a specialized share IPC$. There are multiple interfaces provided by a typical domain controller and domain member servers, most well-known ones are LSA (local security authority, documented in MS-LSAD and MS-LSAT) and NETLOGON remote protocol (documented in MS-NRPC). LSA remote procedure calls are used, among other needs, for retrieving identity information about SIDs and their relationship to other objects. NETLOGON, as its name suggests, is utilized for authentication in a domain environment, across domains, and across forests of domains.

In a traditional domain member set up, the member machine has no possession of a particular user credentials. Instead, it relies on its own connection to its own domain controller to identify a user and to proxy a user’s authentication to the domain controller of the domain a user belongs to. In case a user is performing a remote authentication using Kerberos, a remote system has to present a Kerberos ticket to the domain member’s SMB service, like with any other Kerberos services.

To operate as a domain member in a FreeIPA domain, thus, Samba needs a FreeIPA master to be configured as a domain controller and a FreeIPA client needs to be configured in a specific way to allow Samba to talk to a domain controller. This document overviews a set of implementation tasks to achieve the domain controller operation.

Domain controller side configuration overview

FreeIPA master can be configured to perform as a ‘trust controller’ with the help of ipa-adtrust-intall tool. The tool creates required subtrees and objects in LDAP, configures Samba to use an ipasam PASSDB module which knows how to deal with FreeIPA LDAP schema for Samba-specific attributes and supports storing and retrieving information about trusted domains from LDAP. The tool also makes sure certain 389-ds plugins provided by FreeIPA are enabled and initialized.

As a result of the configuration, Samba considers itself a domain controller for the traditional (Windows NT) domain type. Such traditional domain controller is not capable to serve as a fully-fledged Active Directory domain controller due to few important limitations:

  • Samba traditional domain controller role is not implementing AD DC itself

  • LDAP schema used by FreeIPA is different from Active Directory LDAP schema

  • LDAP directory information tree (DIT) is different from what Active Directory clients expect from an AD DC

  • No Global Catalog service is provided

Additionally, ipasam PASSDB module is not capable to create machine accounts for requests coming from Samba. This means net rpc join will not work when issued from FreeIPA domain members. Also, traditional (Windows NT) domain controller role in Samba is not able to create machine accounts on request from net ads join, a procedure to join machine to an Active Directory.

The limitations above are fine for FreeIPA environment because FreeIPA clients perform its own enrollment process via IPA API and a special LDAP control extension.

When a domain member establishes a secure channel connection to a domain controller, following is considered on the domain controller side:

  • DCE RPC connection is negotiated and authenticated. As part of authentication, either NTLMSSP or Kerberos token is processed and converted into a local NT token.

  • Local NT token represents a remote user (machine account) on the domain controller. The information includes POSIX attributes as well as NT attributes since Samba will spawn a process to handle the connection under local POSIX user identity. Each machine account, therefore, requires associated POSIX attributes.

  • DCE RPC connection from a domain member is authenticated by use of mutually known secret, machine account credentials. Additionally, when Kerberos is in use, DCE RPC packets might be signed with the use of a service ticket to the domain controller’s machine account (host/... principal in Kerberos) because on Windows systems all other service principals (SPNs) are presented as aliases to the machine account.

Changes required on domain controller

Domain controller configuration is mostly covered already by the ipa-adtrust-install installation utility. The only missing part is to make sure Samba has access to the host keytab. The host keytab’s content is copied during upgrade process and also is added during initial ipa-adtrust-install run.

The rest of the changes fall into specific parts of FreeIPA configuration.

Changes to FreeIPA framework

A new command is added to the ipa service family, ipa service-add-smb. This command creates LDAP object that represents cifs/... service principal for the domain member. This LDAP object must have a number of attributes assigned that cannot be assigned past creation because otherwise object classes set on the object will not pass through constraint checks.

The SMB service object needs to have:

  • POSIX attributes

  • NT attributes, including ipaNTSecurityIdentifier

ipaNTSecurityIdentifier is filled in by the SID generation plugin at the object creation time for SMB service.

ipaNTSecurityIdentifier attribute is a part of ipaNTUserAttrs object class for users and SMB services. IPA groups also can contain the attribute via ipaNTGroupAttrs object class.

With the help of the sidgen plugin, ipaNTSecurityIdentifier attribute is only added when:

  • the object has POSIX attributes uidNumber and gidNumber

  • the values of those attributes are within 32-bit unsigned integer

  • the object has any of the following object classes: ipaIDObject, posixAccount, or posixGroup

  • the object has no ipaNTSecurityIdentifier attribute already.

sidgen plugin will add ipaNTUserAttrs object class for non-group objects and ipaNTGroupAttr for the group object type. A plugin is triggered at an object creation or via an LDAP task. One can trigger task run by running ipa-adtrust-install --add-sids on the trust controller.

LDAP object class ipaNTUserAttrs defines few other attributes. These attributes, called below ‘SMB attributes’, are required by the domain controller to define content of an NT token for an authenticated identity (user or a machine account).

SMB attributes are:

  • ipaNTLogonScript : Path to a script executed on a Windows system at logon

  • ipaNTProfilePath : Path to a user profile, in UNC format \\server\share\

  • ipaNTHomeDirectory : Path to a user’s home directory, in UNC format \\server\share

  • ipaNTHomeDirectoryDrive : a letter [A-Z] for the drive to mount the home directory to on a Windows system

All SMB attributes require the presence of ipaNTUserAttrs object class in the user object LDAP entry. This object class cannot be added without ipaNTSecurityIdentifier. Adding SID requires to consume IDs from a range suitable for SIDs and this logic is recorded in the sidgen plugin. Thus, until SID is generated, no attributes can be set on the user entry.

As result of it, SMB attributes are not available at ipa user-add or ipa stageuser-add level. Instead, it is possible to modify a user object with ipa user-mod or ipa stageuser-mod commands:

$ ipa user-mod --help
Usage: ipa [global-options] user-mod LOGIN [options]

Modify a user.
  --smb-logon-script=STR    SMB logon script path
  --smb-profile-path=STR    SMB profile path
  --smb-home-dir=STR        SMB Home Directory
  --smb-home-drive=['A:', 'B:', 'C:', 'D:', 'E:', 'F:', 'G:', 'H:', 'I:', 'J:', 'K:',
                    'L:', 'M:', 'N:', 'O:', 'P:', 'Q:', 'R:', 'S:', 'T:', 'U:', 'V:',
                    'W:', 'X:', 'Y:', 'Z:']
                   SMB Home Directory Drive

$ ipa stageuser-mod --help
Usage: ipa [global-options] stageuser-mod LOGIN [options]

Modify a stage user.
  --smb-logon-script=STR    SMB logon script path
  --smb-profile-path=STR    SMB profile path
  --smb-home-dir=STR        SMB Home Directory
  --smb-home-drive=['A:', 'B:', 'C:', 'D:', 'E:', 'F:', 'G:', 'H:', 'I:', 'J:', 'K:',
                    'L:', 'M:', 'N:', 'O:', 'P:', 'Q:', 'R:', 'S:', 'T:', 'U:', 'V:',
                    'W:', 'X:', 'Y:', 'Z:']
                   SMB Home Directory Drive

Due to limitations on how SMB attributes can be added, Web UI shows the section “User attributes for SMB services” without any values for those users who have no SID assigned.

Changes to LDAP storage

By default, POSIX attribute can only be searched by LDAP clients in cn=users,cn=accounts,$basedn and cn=groups,cn=accounts,$basedn subtrees. Since SMB service belongs to cn=services,cn=accounts,$basedn subtree, new ACI has to be added.

'System: Read POSIX details of the SMB services': {
    'replaces_global_anonymous_aci': True,
    'ipapermbindruletype': 'all',
    'ipapermright': {'read', 'search', 'compare'},
    'ipapermdefaultattr': {
        'objectclass', 'cn', 'uid', 'gecos', 'gidnumber',
        'homedirectory', 'loginshell', 'uidnumber',

SMB attributes for users are now accessible for self-modification and also readable by the members of cn=adtrust agents,cn=sysaccounts,cn=etc,$basedn group which contains, among others, service principals of the domain controllers.

Changes to LDAP plugins

As mentioned above, both domain controller and domain member need to know common secret – the machine account credential of the domain member. For the purpose of MS-NRPC section, it is enough to know RC4-HMAC hash. Given that there is general willingness to not allow access to RC4-HMAC key over Kerberos in contemporary systems, FreeIPA code was changed to explicitly allow generation of RC4-HMAC hash for SMB service only. For users in FreeIPA generation of RC4-HMAC will be disabled.

Combined with system-wide crypto policy changes in Fedora 30, it means that both in FIPS and non-FIPS environment RC4-HMAC will not be usable as a Kerberos encryption type unless an application explicitly specifies it and RC4-HMAC key exists in the principal’s database entry in FreeIPA.

A consequence of it is that RC4-HMAC hash will not be usable for FreeRADIUS integration because the hashes will be missing from user entries.

Changes to Kerberos KDC driver

Support for recognizing SMB service principals as machine accounts is added to Kerberos KDB driver. For SMB service principal an MS-PAC record is generated.

Changes to Samba PASSDB driver

Support for resolving SIDs to user and group names is added. This is needed to allow Samba domain controller to resolve requests from Samba domain member servers for SID to ID conversion.

Support for recognizing machine accounts as ACB_WSTRUS entry type in PASSDB is added. This is needed to allow Samba domain members to login to Samba domain controller for LSA RPC and Netlogon operations.

Support is added to recognize machine account names (NetBIOS names plus ‘$’ sign) as machines. Multivalued uid attribute in the LDAP object entry is now supported as SMB service objects will have both cifs/... and NetBIOS$ names assigned to uid attribute. Samba looks up POSIX entries by using either Kerberos principal name or machine account name depending on a code flow in different parts of the SMB login processing, thus both needs to be supported.

Notes about unfinished Samba work

Since changes on Samba side apply for both domain controller and domain member, unfinished work is reflected in a single place only.

Below is the current list, most of the entries on it are still open.

  • Samba needs to implement ‘net ads offlinejoin’ call to allow setting up a machine account and SID without actually joining the machine via DCE RPC (for IPA or VAS or other join types).

    See for one part that should explain failures with ‘did we join?’ message in the logs.

  • windbindd daemon attempts to look up list of trusted domains from own domain controller. Samba domain controller, as used in FreeIPA does not implement netr_DsrEnumerateDomainTrust call. The situation here is the same as in which is another call we need to implement to allow Windows side operations.

    [2019/06/28 04:27:35.699042,  1, pid=31998, effective(0, 0), real(0, 0), class=rpc_cli] ../source3/rpc_client/cli_pipe.c:569(cli_pipe_validate_current_pdu)
      ../source3/rpc_client/cli_pipe.c:569: RPC fault code DCERPC_NCA_S_OP_RNG_ERROR received from host master.ipa.test!
    [2019/06/28 04:27:35.699065, 10, pid=31998, effective(0, 0), real(0, 0), class=rpc_cli] ../source3/rpc_client/cli_pipe.c:979(rpc_api_pipe_got_pdu)
      rpc_api_pipe: got frag len of 32 at offset 0: NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
    [2019/06/28 04:27:35.699159,  3, pid=31998, effective(0, 0), real(0, 0), class=winbind] ../source3/winbindd/winbindd_ads.c:1391(trusted_domains)
      ads: trusted_domains
    [2019/06/28 04:27:35.699191,  1, pid=31998, effective(0, 0), real(0, 0), class=rpc_parse] ../librpc/ndr/ndr.c:471(ndr_print_function_debug)
          netr_DsrEnumerateDomainTrusts: struct netr_DsrEnumerateDomainTrusts
              in: struct netr_DsrEnumerateDomainTrusts
                  server_name              : *
                      server_name              : 'master.ipa.test'
                  trust_flags              : 0x00000023 (35)
                        1: NETR_TRUST_FLAG_IN_FOREST
                        1: NETR_TRUST_FLAG_OUTBOUND
                        0: NETR_TRUST_FLAG_TREEROOT
                        0: NETR_TRUST_FLAG_PRIMARY
                        0: NETR_TRUST_FLAG_NATIVE
                        1: NETR_TRUST_FLAG_INBOUND
                        0: NETR_TRUST_FLAG_MIT_KRB5
                        0: NETR_TRUST_FLAG_AES