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:
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:
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.
$ cp source/bin/pam_winbind.so /lib/security/ $ chown root /lib/security/pam_winbind.so $ chgrp root /lib/security/pam_winbind.so $ chmod 755 /lib/security/pam_winbind.so
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:
$ cp source/nsswitch/libnss_winbind.so /lib/libnss_winbind.so $ chown root /lib/libnss_winbind.so $ chgrp root /lib/libnss_winbind.so $ chmod 755 /lib/libnss_winbind.so $ ldconfig
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:
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:
$ winbindd -d 10 -i <...intermediate output deleted...> Could not fetch our SID - did we join? unable to initialize domain list
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:
$ wbinfo -a "EDEN\leezard%test" plaintext password authentication succeeded challenge/response password authentication succeeded
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.
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.
$ getent passwd "EDEN\leezard" EDEN\leezard:*:10000:10002:Lee Zard:/home/EDEN/leezard:/bin/false
If your operating system doesn't include a getent or equivalent command, the same test can be performed using Perl's getpwnam( ) function:
$ perl -e '@pw = getpwnam("EDEN\\leezard"); print "@pw\n";' EDEN\leezard * 10000 10002 Lee Zard /home/EDEN/leezard /bin/false
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:
$ getent group "EDEN\Domain Admins" EDEN\domain admins:x:10003:EDEN\gcarter,EDEN\administrator
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]:
$ smbclient //zero/public -U leezard -W EDEN Password: test Domain=[EDEN] OS=[Unix] Server=[Samba 3.0.22] smb: \>
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:
$ smbstatus Samba version 3.0.22 PID Username Group Machine ------------------------------------------------------------- 13854 EDEN\leezard EDEN\domain users zero (127.0.0.1) Service pid machine Connected at ------------------------------------------------------- public 13854 zero Tue Jul 4 21:12:29 2006 No locked files
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.
Table 10-5 concludes our initial setup of Winbind by summarizing the smb.conf parameters presented in this section.
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:
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:
[global] ldap admin dn = cn=smbadmin,ou=people,dc=example,dc=com ldap suffix = dc=example,dc=com
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:
dn: ou=idmap,dc=example,dc=com objectClass: organizationalUnit objectClass: sambaUnixIdPool ou: idmap uidNumber: 207250 gidNumber: 204932
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:
dn: sambaSID=S-1-5-21-406022937-1377575209-526660263-8188, ou=idmap,dc=example,dc=com objectClass: sambaIdmapEntry objectClass: sambaSidEntry uidNumber: 205342 sambaSID: S-1-5-21-406022937-1377575209-526660263-8188
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.
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:
[global] idmap uid = 200000 - 300000 idmap gid = 200000 - 300000 idmap backend = rid
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 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:
Figure 10-3. SFU attributes for a user in AD
$ getent passwd "OCEAN\phish" OCEAN\phish:*:10007:10027:Peter Trout:/home/phish:/bin/bash
Table 10-6 provides a brief summary of the parameter introduced in this section.