Section 10.4. Winbind

10.4. Winbind

So far, we have assumed that each domain account would be mapped to a preexisting Unix user or group. You may wish to deploy a Samba server with no preexisting Unix account infrastructure. In this cases, Winbind, the name given to the winbindd
daemon and set of libraries that act as an intermediary between Unix services and Windows domain controllers, offers a means to manage domain users and groups without the overhead of local accounts.

In its most common configuration, Winbind maintains a database of domain accounts matched to Unix uids and gids. These Unix identifiers are allocated to domain users and groups from a range specified in smb.conf. Winbind then makes these SID-to-uid/gid mappings available to Unix applications via the Name Service Switch (NSS) interface so that lookups for a user such as EDEN\leezard returns an entry resembling a line from /etc/passwd:

EDEN\leezard:*:10000:10002:Lee Zard:/home/EDEN/leezard:/bin/false

Winbind is currently supported on the following platforms: AIX, FreeBSD 5.x, HP-UX 11.x, IRIX, Linux, and Solaris. If you are using vendor-provided Samba packages for any of these platforms, chances are good that winbindd and its associated pieces are already installed. If you compile Samba yourself on a supported platform, the following files will be created:

winbindd

The long-running daemon that communicates with domain controllers on behalf of other Unix processes, including smbd.

libnss_winbind.so

This library provides the support functions for the passwd and group NSS databases listed in /etc/nsswitch.conf. The library extension, .so, may vary depending on the convention used by your server's operating system.

pam_winbind.so

A PAM module utilizing winbindd to provide NTLM authentication and password change support. This library is built only if you have enabled the --with-pam option when compiling Samba. Its extension, .so, may vary depending on the convention used by your server's operating system.

ntlm_auth

A command-line interface providing features similar to the pam_winbind.so library. The tool is commonly used to provide challenge/response authentication to Unix services such as dial-in and web proxy servers.

wbinfo

A command line utility for interacting with winbindd. Although it can be used in shell scripts, its main purpose is as an administrative testing tool to ensure that winbindd is functioning properly.

You can force Winbind to be compiled by specifying the --with-winbind option when running the configure script. This option can be useful when porting Winbind to a new platform.

By default, Samba's make install process places winbindd in /usr/local/samba/sbin and the ntlm_auth and wbinfo tools to /usr/local/samba/bin. However, due to paranoia about copying files to operating system directories and the subtle differences between systems, neither the PAM nor NSS libraries are installed by default. These must be manually copied.

The target directory for the pam_winbind library varies, depending on your platform. The most common location is /lib/security/. However, 64-bit Linux servers use /lib64/security. Make sure to check your operating system's documentation for specifics. The following set of commands, executed as root on a 32-bit Linux host, installs the PAM module to the correct location and sets the appropriate ownership and permissions. It is assumed that you have already navigated to the top level of the Samba source tree.

Next, install the NSS library. Once again, the target directory varies, depending on your server's operating system. In most cases, it is the /lib directory. The library name is a bit less standard. On modern Linux systems, the library is called libnss_winbind.so.2, and on Solaris hosts it should be nss_winbind.so.1. Usually, you can just follow the convention of other NSS libraries on your system. As an example, these commands install the library on a 32-bit Linux host. Executing ldconfig at the end creates the symbolic link from libnss_winbind.so.2 to libnss_winbind.so:

Early versions of Samba 3.0 did not correctly set the internal version for the libnss_winbind.so library, and therefore require that you create the symbolic link manually.

After installing the NSS library, add the winbind service to the passwd and group databases in /etc/nsswitch.conf. This step enables the operating system to query winbindd when searching for users and groups. Winbind will happily coexist in nsswitch.conf with other services such as NIS or LDAP. This example instructs the operating system to query local files, an LDAP directory service, and finally winbindd when searching for users and groups:

passwd: files ldap winbind
group: files ldap winbind

The last step before starting
winbindd is to specify a range of uid and gid values in smb.conf that can be allocated for domain users and groups. These allocations are then stored in the winbindd_idmap.tdb file, where they can be found after the system reboots. Each range, one for users and one for groups, must be continuous and must not overlap any existing accounts. On older Unix implementations that supported only 16-bit uid/gid values, this could be a problem. On newer platforms, the possibility of 4 billion uid values provided by 32-bit identifiers lessens the contention a bit. Here's an example that allots uids from 200,000 to 300,000 for winbindd's use:

[global]
idmap uid = 200000 - 300000

There is no absolute requirement that the idmap gid parameter use the same range as the uids, but this is a common convention:

idmap gid = 200000 - 300000

It may seem that 100,000 users or groups would be plenty. It frequently is. There is, however, a potential mathematical problem. Each domain can potentially possess a total sum of users and groups just under 232. Although this limit is rarely reached in a single domain, mapping accounts from multiple trusted domains might reach the limit of the idmap ranges in smb.conf. We have never actually seen this occur in practice, because uids are allocated only when a domain user accessed the Samba server. It is rare for every user in a domain to access the same file server.

Once smb.conf has been modified, it is time to start winbindd. The daemon supports most of the command-line options common to smbd and nmbd. It does not, however, support being started from inetd. Normally winbindd is launched as part of the system boot process. To initially test your setup, start the server from the command line:

$ /usr/local/samba/sbin/winbindd

The internals of winbindd have been rewritten several times; most recently, in the 3.0.20 Samba release. In all of the 3.0 releases, you will see at least two winbindd processes. In Samba 3.0.20 and later, you may see more, depending on the number of trusts supported by your domain.

winbindd does not respond to network requests as smbd and nmbd do. It listens on two Unix domain sockets in /tmp/.winbindd and the directory specified in the lock directory configuration option (normally /usr/local/samba/var/locks/winbindd_privileged). The former is accessible by any user for queries such as enumerating users or groups and resolving names to and from SIDs. In contrast, the winbindd_privileged pipe is available only for root. Certain operations, such as NTLM challenge/response authentication and allocating a uid or gid, must be restricted from nonadministrative users for security reasons.

You can test that winbindd is responding correctly by using wbinfo to send it a ping request:

$ wbinfo -p
Ping to winbindd succeeded on fd 4

If you receive the message "could not ping winbindd!", make sure that winbindd is in fact running. If the server immediately exited, it may be helpful to start it interactively with a high debug level. The following examples show winbindd failing to start because it does not believe that it has been correctly joined to the domain:

Once you know that winbindd is responding to requests, verify that it can properly communicate with a domain controller. Running wbinfo -t validates Samba's machine trust account much in the same way as when we ran net ... testjoin. The difference in this case is that you are asking winbindd to validate the credentials rather than doing it yourself using the net command.

$ wbinfo -t
checking the trust secret via RPC calls succeeded

If you observe any failures at this point, recheck the trust account using net . . . testjoin and follow the troubleshooting steps presented earlier in the chapter.

Next, verify winbindd's ability to authenticate users. Using the -a option to wbinfo, ask winbindd to send a NetSamLogon( ) authentication request to the appropriate DC using a set of credentials passed in on the command line. The backslash is the default separator between the domain and login name and must be either quoted or escaped when specified in a shell environment. This delimiter can be changed to an alternate character by specifying the winbind separator option in smb.conf. The % character is used to separate the password from the username:

If the previous tests have succeeded, this one should succeed as well. The plaintext authentication is similar to what is provided by pam_winbind. However, the challenge/response authentication requires access to winbindd's privileged pipe operations and therefore can succeed only if wbinfo -a is run as well. If both of these fail, ensure that you have entered the correct credentials.

There are quite a few more options
to wbinfo. In fact, every query supported by winbindd has an analogous wbinfo command-line switch. Table 10-4 summarizes the remaining arguments supported by the tool. Note that some options possessing a long description string have no single-character equivalent.

Table 10-4. wbinfo options

Short option

Long option

Argument

Description

-a

--authenticate

username%password

Attempt to authenticate a user using NTLM.

-D

--domain-info

domain

List information regarding the domain.

--getdcname

domain

Find a domain controller for a specific domain.

-g

--domain-groups

Enumerate domain groups.

-G

--gid-to-sid

gid

Convert a gid to a SID.

-?

--help

Display the help listing.

-m

--TRusted-domains

Display the list of trusted domains.

-n

--name-to-sid

name

Convert a name into a SID.

-p

--ping

Ping the winbindd daemon.

-r

--user-groups

username

List the gids for groups to which the user belongs.

--separator

Print the winbind separator character.

--sequence

Display the current sequence number for all trusted domains, including our own.

-s

--sid-to-name

SID

Convert a SID to a user or group name.

-S

--sid-to-uid

SID

Convert a SID to a uid.

-t

--check-secret

Verify the machine account credentials.

--user-domgroups

SID

Print the SIDs for the domain groups to which the user belongs.

--user-sids

SID

Print the SIDs for the all groups to which the user belongs.

-u

--domain-users

Enumerate domain users.

-U

--uid-to-sid

uid

Convert a uid to a SID.

-Y

--sid-to-gid

SID

Convert a SID to a gid.

Next, verify that the NSS library is properly installed by issuing a call to retrieve a user from libnss_winbind. The resulting output also confirms winbindd's ability to allocate uids and gids for users and groups. Many operating systems provide the getent tool for querying NSS databases. You can issue a query for a specific user by executing the following command. Remember to either quote the username or escape the backslash so that getent doesn't misinterpret the following l as a control character. If the libnss_winbind library is not installed in the correct location or has improper permissions, the test fails to locate the user.

The home directory path and login shell values are filled in by the smb.conf parameters template homedir and template shell. The home directory location defaults to the path /home/%D/%U. %D and %U are smb.conf variables, documented in Chapter 4, for the user's domain and login name. The shell defaults to /bin/false, although you will see later how to change this to a valid shell in order to allow domain users access to non-Samba services using pam_winbind.

It is a good idea to rerun the getent test, but this time, search for a domain group:

You are now ready to start both smbd and nmbd and connect as a domain user. The easiest way to view winbindd in action is to connect to a share using smbclient and examine the output from smbstatus. For the example here, assume that the server named ZERO is providing a file share named [public]:

Running smbstatus on the server while still connected with smbclient shows that the the user EDEN\leezard has attached to the share public. The important bit of data is the username, which has been provided Winbind's NSS library:

When winbindd performs actions such as authenticating a user or querying the membership of a group, it remembers certain information in an attempt to minimize network communication. In AD domains, it is almost guaranteed that cached user and group information will be flushed from the winbindd_cache.tdb file regularly at an interval specified in seconds by the winbind cache time option. This parameter defines the number of seconds before winbindd queries a DC to determine whether its local cache is still current. At most sites, the default of 5 minutes is sufficient, although you may wish to experiment with longer periods, depending on the replication period between your DCs. Rest assured that uids and gids allocated to users and groups are not part of this cache and persist across restarts and server reboots.

One very expensive operation in both in time and bandwidth, regardless of any amount of caching, is enumerating users and groups. This problem, coupled with the fact that current Windows service packs and hot fixes make it increasingly difficult to retrieve this information with only the machine account credentials, have led Samba developers to recommend that both the winbind enum users and winbind enum groups parameters be disabled. These two parameters are used to enable or disable Winbind NSS support for the getpwent( ) and getgrent( ) set of functions, which have historically been used to iterate over available user accounts. Developers agree that these functions are highly inefficient and that an application should use the getpwnam( ) or getgrnam( ) function when looking for a specific user or group. Nevertheless, there are a still a few older applications that may fail if you disable user and group enumeration. Our advice is to get a newer version of the application. If you ever need to enumerate accounts, wbinfo's -u and -g options will continue to work, as these are independent of the NSS library.

The character used to separate the domain name from the user or group name when displaying domain accounts.

\

Global

[a]

[a] These two parameters are disabled by default starting with release 3.0.23.

10.4.1. idmap Backends

In some scenarios, you may wish to have more control over how winbindd allocates uids and gids for domain accounts, or want to share mappings between Winbind installations on multiple servers. The idmap backend parameter allows you to specify an alternative SID-to-uid/gid database, which may also provide alternative uid and gid allocation semantics. We have already mentioned one backend: tdb. The default tdb idmap implementation stores uid and gid allocations in the local database file winbindd_idmap.tdb.

Samba 3.0.22 currently ships with four supported idmap backend modules:

tdb

The default backend used for local uid and gid allocation. Its main advantage is that it requires very little setup or maintenance. Its main disadvantage is that a user is allocated a different uid on each Winbind server installation, thus making it incompatible with NFS.

ldap

Support for storing SID-to-uid/gid mappings in an LDAP directory service was added to address the problems with NFS and the tdb backend. If your network already has an available LDAP directory, this backend provides a simple means of ensuring consistent mapping tables among multiple Winbind installations.

rid

The RID backend shared library provides a central mapping solution for single domain installations. It is built only when the --with-shared-modules=idmap_rid option is passed to the configure script. The RID backend guarantees consistent one-to-one mappings between domain SIDs and Unix accounts by generating the Unix ID value based on the Windows Relative Identifier. Because a user's or group's RID does not change for the lifetime of the account, you are ensured that the uid or gid will be the same in every Winbind install. However, because Windows domain allocates RIDs in a monotonic fashion beginning with 1,000, it does not support trusted domains, as accounts in multiple domains may be mapped to the same local Unix uid/gid.

ad

The AD backend utilizes POSIX information stored in Active Directory rather than allocating any uid or gid local values, and currently supports only a domain with the Services for Unix (SFU) schema extensions. To create this plug-in, you must specify the --with-shared-modules=idmap_ad option when building Samba. Note that although this option gains you the most flexibility for managing specific uid and gid values, it also requires that you manually manage additional attributes for accounts in AD.

With the exception of TDb, let's look at the specific configuration details of each backend. The default TDb configuration was covered in the previous section as part of our initial Winbind installation.

10.4.1.1. idmap backed = ldap

Winbind's LDAP backend shares much of its configuration settings with the ldapsam passdb backend discussed in Chapter 5. If Samba has been compiled to include LDAP support, the ldap idmap feature is included in winbindd. Based on the parameters presented in conjunction with the ldapsam module, our initial smb.conf contains the following parameters:

We also assume that smbpasswd -w has been run to store the admin DN's password in secrets.tdb and that the LDAP directory service has already loaded Samba's distributed schema file.

The next step is to specify where the SID-to-uid/gid mappings will be stored in the directory using the ldap idmap suffix parameter. All that is required is that this DN exists and may be modified by the account specified in the ldap admin dn option. winbindd will handle the rest. The server in our example uses an organizational unit directly below the directory root for storing idmap entries:

ldap idmap suffix = ou=idmap

idmap modules use a syntax similar to their passdb counterparts for defining configuration settings. Parameters are appended to the module name using a colon followed by the option's value. The only parameter that this module supports is the LDAP server's URI. The following setting in smb.conf's [global] section informs winbindd to contact the LDAP server named ldap.example.com:

idmap backend = ldap:ldap://ldap.example.com

As with the user and group information in Chapter 5, the best solution is to allow winbindd to manage its LDAP entries without any interference. It will keep track of the next available uid and gid values and ensure that each is allocated atomically and store in the directory. Other instances of winbindd then query the LDAP directory prior to allocating a new uid or gid. The use of the SID as the RDN value prevents two servers from creating multiple records for a given user or group.

The LDIF entry shows the the next available uid (207250) and gid (204932) values maintained by winbindd in the ldap idmap suffix:

When winbindd needs to allocate a new Unix user, it increments the uidNumber attribute by one and store the SID and allocated uid in the directory. The following LDIF represents a mapping between the SID S-1-5-21-406022937-1377575209-526660263-8188 and the uid 205342:

If you observe any failures in the winbindd logfiles when attempting to access the LDAP directory, check whether you have specified the correct ldap suffix and ldap idmap suffix values and that the directory service's access controls allow modification to those locations by the ldap admin dn account.

10.4.1.2. idmap backed = rid

The idmap_rid plug-in, like the ldap idmap module, provides consistent uid and gid allocation across servers. It is much easier to configure, mainly because it is able to make use of existing domain account information rather than requiring an extra directory service other than the Windows domain itself. However, it is less flexible in terms of support for trusted domains and administrative control over uid and gid assignments. Still, its ease of use and compatibility with both Windows NT 4.0 and Active Directory domains make it very attractive for many administrators.

To build the idmap_rid (or rid) shared library, you must specify --with-shared-modules=idmap_rid when running the Samba's configure script.[*] Even if you are relying on Samba packages provided by a vendor, you may find it necessary to compile the library yourself, as it is not always included. Once built, the idmap_rid library should be installed in /usr/local/samba/lib/idmap as part of the make install process.

[*] Operating system support for shared libraries is also a requirement.

Next, configure the idmap parameters in smb.conf. In this example, we'll set the idmap uid and idmap gid options exactly as we did before, except that this module does require that both parameters specify the same range. The idmap backend option need only refer to the rid plug-in by name:

Because the rid plug-in officially supports only a single domain, you must also disable support for trusted domains in smb.conf:

allow trusted domains = no

To calculate the uid or gid assigned to a domain user or group, add the RID to the lower end of the idmap range and verify that the resulting value is less than the upper boundary of the range. So a user with the SID S-1-5-21-3493585492-4029240144-3226775320-1168 would be assigned the uid of 201168 (1168 + 200000).

Although the rid idmap module does not officially support trusted domains, it can be built with unofficial support by defining the IDMAP_RID_SUPPORT_TRUSTED_DOMAINS macro when running make.

$ make -DIDMAP_RID_SUPPORT_TRUSTED_DOMAINS bin/rid.so

The resulting library allows you to split up the idmap range between domains by defining the subrange as an option to the idmap backed = rid directive. The following setting splits the range (200000-300000) between the domains EDEN and PERSIA. Always use the short name of the domains here, even when joined to an AD domain. The ranges cannot overlap, or exceed the original idmap uid and gid ranges.

idmap backend = rid:EDEN=200000-26000,PERSIA=260001-300000

The main disadvantage in this configuration, and mostly likely why it is not officially supported by Samba developers, is that if the first domain ever outgrows the allotted ids, there is no way to expand the available range without changing all of the uids and gids allocated to the second domain.

10.4.1.3. idmap backed = ad

The final idmap module examined here is the idmap_ad library, which uses the Microsoft's SFU schema extensions for managing Unix users and group attributes in AD. Like the rid plug-in, it also requires that you include it in the list of shared modules (--with-shared-modules=idmap_ad) when compiling Samba. The resulting library (named ad.so or idmap_ad.so, depending on your Samba version and platform) is installed in /usr/local/samba/lib/idmap/ by default.

The ad library included in Samba 3.0.23 also works with the RFC2307 schema support in Windows 2003 R2.

The setup is remarkably easy. All that is required is to enable the module using the idmap backend parameter:

idmap backend = ad

Because the uid and gid information is maintained in Active Directory, there is no need to specify an available range in smb.conf. This approach does, however, require some coordination between Unix and AD administrators because winbindd does not check whether a uid from AD overlaps with any local Unix users.

Normally the home directory path and login shell values for users in Winbind's NSS output would be filled in from the template homedir and template shell options.
However, the SFU schema also supports storing these attributes in AD. The winbind nss info option allows us to specify whether we want to retrieve the real attributes from AD (sfu) or to fill them in with template values (template). To make use of the SFU attributes, add the following line to the global section of smb.conf:

winbind nss info = sfu

Figure 10-3 shows the SFU attributes for a user in a Windows 2003 domain named ocean.plainjoe.org. And here is corresponding passwd record returned from libnss_winbind: