4. The IDX-smbldap-tools

Smbldap-tools is a set of perl scripts designed to manage user and group accounts stored in an LDAP directory. These scripts will make our lives much easier by providing a set of simple commands for carrying out the most common user administration tasks, thus saving us from dealing with the internals of LDAP and making managing Samba users almost as easy as managing normal system users.

Please note that, though Samba account information will be stored in LDAP, smbd(8) will still obtain the user's UNIX account information via the standard C library calls, such as getpwnam() (see documentation), which don't natively support LDAP. This means we'll also need to configure the ypldap(8) daemon, which will act as an interface between LDAP and OpenBSD's authentication routines.

4.1 Configuration

The smbldap-tools require the installation of quite a few perl modules:

The /etc/smbldap-tools/smbldap_bind.conf file contains the parameters to connect to the LDAP server; they should match the rootdn and rootpw parameters in /etc/openldap/slapd.conf. Make sure this file has restrictive permissions (600) to protect the passwords from unauthorized access.

/etc/smbldap-tools/smbldap_bind.conf
slaveDN="cn=Manager,dc=kernel-panic,dc=it"
slavePw="password"
masterDN="cn=Manager,dc=kernel-panic,dc=it"
masterPw="password"

Before editing the next configuration file, we need to retrieve the SID for the domain:

# net getlocalsid
SID for domain SAMBA is: S-1-5-21-2855447605-3248580512-2157288933

The /etc/smbldap-tools/smbldap.conf file allows you to set global parameters that will be readable by everybody.

/etc/smbldap-tools/smbldap.conf
# SID and domain name
SID="S-1-5-21-2855447605-3248580512-2157288933"
sambaDomain="KERNEL-PANIC"

# LDAP servers and ports (if you're using LDAP over TLS/SSL, set the URI schemes
# to 'ldaps' and the ports to '636')
slaveLDAP="ldap://ldap.kernel-panic.it"
slavePort="389"
masterLDAP="ldap://ldap.kernel-panic.it"
masterPort="389"

# TLS configuration (set ldapTLS to '1' to enable TLS)
ldapTLS="0"
verify="none"
cafile="/etc/openldap/ssl/ca.crt"
clientcert="/etc/openldap/ssl/client.crt"
clientkey="/etc/openldap/ssl/private/client.key"

# LDAP configuration
suffix="dc=kernel-panic,dc=it"
usersdn="ou=Users,${suffix}"
computersdn="ou=Computers,${suffix}"
groupsdn="ou=Groups,${suffix}"
idmapdn="ou=Idmap,${suffix}"
sambaUnixIdPooldn="sambaDomainName=KERNEL-PANIC,${suffix}"
scope="sub"
hash_encrypt="SSHA"
crypt_salt_format="%s"

# Unix accounts configuration
userLoginShell="/bin/ksh"
userHome="/home/%U"
userHomeDirectoryMode="700"
userGecos="System User"
defaultUserGid="513"
defaultComputerGid="515"
skeletonDir="/etc/skel"
defaultMaxPasswordAge="45"

# Samba configuration
userSmbHome=""
userProfile=""
userHomeDrive="H:"
userScript="logon.bat"
mailDomain="kernel-panic.it"

# smbldap-tools configuration
with_smbpasswd="0"
smbpasswd="/usr/local/bin/smbpasswd"
with_slappasswd="0"
slappasswd="/usr/local/sbin/slappasswd"

4.2 Populating the LDAP database

Now we can create the structure of the LDAP tree by inserting the base entries in the database; the smbldap-populate script will take care of everything for us:

# /usr/local/sbin/smbldap-populate
Populating LDAP directory for domain KERNEL-PANIC (S-1-5-21-2855447605-3248580512-2157288933)
(using builtin directory structure)

adding new entry: dc=kernel-panic,dc=it
adding new entry: ou=Users,dc=kernel-panic,dc=it
adding new entry: ou=Groups,dc=kernel-panic,dc=it
adding new entry: ou=Computers,dc=kernel-panic,dc=it
adding new entry: ou=Idmap,dc=kernel-panic,dc=it
adding new entry: uid=root,ou=Users,dc=kernel-panic,dc=it
adding new entry: uid=nobody,ou=Users,dc=kernel-panic,dc=it
adding new entry: cn=Domain Admins,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Domain Users,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Domain Guests,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Domain Computers,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Administrators,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Account Operators,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Print Operators,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Backup Operators,ou=Groups,dc=kernel-panic,dc=it
adding new entry: cn=Replicators,ou=Groups,dc=kernel-panic,dc=it
adding new entry: sambaDomainName=KERNEL-PANIC,dc=kernel-panic,dc=it

Please provide a password for the domain root:
Changing UNIX and samba passwords for root
New password: <admin_passwd>
Retype new password: <admin_passwd>
#

The last step of the above command doesn't actually change the UNIX password for the root account: it only sets the password for the domain administrator (in LDAP). You can test that the database now contains the base entries by running the ldapsearch(1) command; you can get an LDIF dump of the users defined in the LDAP database by running:

# ldapsearch -x -LL -b 'ou=Users,dc=kernel-panic,dc=it' -s sub
version: 1

dn: ou=Users,dc=kernel-panic,dc=it
objectClass: top
objectClass: organizationalUnit
ou: Users

[ ... ]

In addition to the default groups created by smbldap-populate, you may also want to define some additional groups, e.g.:

# smbldap-groupadd -g 1500 Accounting
[ ... ]

Now we need to create the appropriate user for every computer that will need to connect to Samba (the "$" sign at the end of each name is mandatory):

# smbldap-useradd -w -u 3000 computer1$
# smbldap-useradd -w -u 3001 computer2$
[ ... ]

Finally, we can create the actual Samba users; each user will have a home directory that will be automatically connected as drive "H:" at logon:

# smbldap-useradd -a -u 2000 -g 512 -G 513 -N Daniele -S Mazzocchio \
> -c "Daniele Mazzocchio" danix
# smbpasswd -a danix
New SMB password: password
Retype new SMB password: password
#

Now we can (re)start the Samba processes:

# pkill .mbd
# /usr/local/libexec/smbd -D
# /usr/local/libexec/nmbd -D

Don't forget to assign the correct permissions and ownerships to the Samba shares.

4.3 Configuring ypldap(8)

YP(8) is a directory service originally developed by Sun Microsystems which, long before LDAP, allowed network management of password, group and hosts file entries. Starting with release 4.5, OpenBSD provides an additional YP daemon, ypldap(8), which uses LDAP as a backend in place of the traditional db(3) database.

Since YP is the only directory service that can be accessed directly using standard C-library functions like getpwent(3), getgrent(3), gethostbyname(3) and so on [FAQ10], it will act as an interface between the system's authentication routines (used by smbd(8)) and the LDAP directory.

As a first step in configuring the YP subsystem, we will set the YP domain of the host, which is an arbitrary string identifying the hosts that share (part of) their system configuration data through YP (and has nothing to do with Samba or DNS domains); the YP domain for a host is set with domainname(1) and can be made permanent across reboots by putting it into the file /etc/defaultdomain(5):

# domainname kernel-panic.it
# echo "kernel-panic.it" > /etc/defaultdomain

Before initializing the YP server, you may want to edit /var/yp/Makefile.yp in order to create only the necessary YP maps, by modifying the "all" target:

/var/yp/Makefile.yp
all: passwd group netid

Now we are ready to initialize the YP server as a master by issuing the ypinit(8) command:

# ypinit -m
Server Type: MASTER Domain: kernel-panic.it

Creating an YP server will require that you answer a few questions.
Questions will all be asked at the beginning of the procedure.

Do you want this procedure to quit on non-fatal errors? [y/n: n] <Enter>

Ok, please remember to go back and redo manually whatever fails.
If you don't, something might not work.

At this point, we have to construct a list of this domain's YP servers.
smb.kernel-panic.it is already known as master server.
Please continue to add any slave servers, one per line. When you are
done with the list, type a <control D>.
        master server   :  smb.kernel-panic.it
        next host to add:  ^D
The current list of NIS servers looks like this:

smb.kernel-panic.it

Is this correct?  [y/n: y] <Enter>
Building /var/yp/kernel-panic.it/ypservers...
smb.kernel-panic.it has been setup as an YP master server.
Edit /var/yp/kernel-panic.it/Makefile to suit your needs.
After that, run 'make' in /var/yp.
#

The default configuration file for ypldap(8) is /etc/ypldap.conf(5), which is made up of three sections: macros, global configuration settings and the declaration of one or more directories. Below is a sample configuration file:

/etc/ypldap.conf
# Macros
# Optional macros go here...

# Global settings
domain       "kernel-panic.it"
interval     3600
# Specify the maps that ypldap should provide
provide map  "passwd.byname"
provide map  "passwd.byuid"
provide map  "group.byname"
provide map  "group.bygid"

# Directory declaration
directory "ldap.kernel-panic.it" {
    binddn    "cn=Manager,dc=kernel-panic,dc=it"
    bindcred  "password"
    basedn    "ou=Users,dc=kernel-panic,dc=it"

    # passwd maps configuration
    passwd filter "(objectClass=posixAccount)"

    attribute name maps to "uid"
    fixed attribute passwd "*"
    attribute uid maps to "uidNumber"
    attribute gid maps to "gidNumber"
    attribute gecos maps to "gecos"
    attribute home maps to "homeDirectory"
    # LDAP users are not interactive system users
    fixed attribute shell "/sbin/nologin"
    fixed attribute change "0"
    fixed attribute expire "0"
    fixed attribute class "default"

    # group maps configuration
    group filter "(objectClass=posixGroup)"

    attribute groupname maps to "cn"
    fixed attribute grouppasswd "*"
    attribute groupgid maps to "gidNumber"
    list groupmembers maps to "memberUid"
}

Since it contains sensitive information, the ypldap.conf(5) file should have restrictive permissions (600); the "-n" flag of ypldap(8) allows you to check the configuration file for validity:

# chmod 600 /etc/ypldap.conf
# ypldap -n
configuration OK

To actually tell the system to include user and group accounts from the YP domain, we need to add the default YP markers to the passwd(5) and group(5) files:

# echo "+:*::::::::" >> /etc/master.passwd
# pwd_mkdb -p /etc/master.passwd
# echo "+:*::" >> /etc/group

Well, now we're ready to start all the required daemons! YP uses RPC(3) to communicate with clients, so it requires that the portmap(8) daemon be enabled. Also the ypbind(8) daemon is required for the server to use its own maps.

# portmap
# ypldap
# ypbind
Enabling yp client subsystem.
To disable: kill ypbind and remove /var/yp/binding
#

You can test that the system is correctly retrieving user information from the YP directory by using the getent(1) command:

# getent passwd
[ ... ]
danix:*:2000:512:Daniele Mazzocchio:/home/danix:/sbin/nologin
#

To automatically start the daemons on boot, add the following lines to the /etc/rc.conf.local(8) file:

/etc/rc.conf.local
portmap=YES
ypldap_flags=""

comment out the following lines in /etc/rc(8) (which would start ypserv(8) instead of ypldap(8)):

/etc/rc
#        if [ -d /var/yp/`domainname` ]; then
#                # YP server capabilities needed...
#                echo -n ' ypserv';              ypserv ${ypserv_flags}
#                #echo -n ' ypxfrd';             ypxfrd
#        fi

#        if [ -d /var/yp/binding ]; then
#                # YP client capabilities needed...
#                echo -n ' ypbind';              ypbind
#        fi

and add the following commands to /etc/rc.local(8), right after the startup of slapd(8C):

/etc/rc.local
if [ -d /var/yp/$(domainname) ]; then
    echo -n ' ypldap'
    ypldap ${ypldap_flags}
    # Wait 5 seconds to fully initialize ypldap before starting ypbind
    sleep 5
fi

if [ -d /var/yp/binding ]; then
    echo -n ' ypbind'
    ypbind
fi

Well, now we have a fully functional Primary Domain Controller: then we can start joining computers to our fresh new domain and perform all the necessary tests! The next chapters will discuss a couple of additional features you may find very useful: antivirus support and printer shares.