Integrating Solaris 10
and Active Directory

Assumtions:

You have a working version of: And a usable editor of some description. Lines prefixed with a "#" indicate a command on the command line. Lines prefixed with a ">" indicate a line added to the file mentioned at the top of the block.

Preparations:

Create a source directory of your choice. We shall use /usr/local/src. # mkdir /usr/local/src Also, ensure your path covers all the binaries needed: #PATH="/usr/local/sbin:/usr/local/bin:/usr/sfw/sbin:/usr/sfw/bin:/usr/ucb:/usr/ccs/bin:/usr/sbin:/usr/bin" Specifically in OpenLDAP, you need to configure extra Compiler/Linker flags # CPPFLAGS="-I/usr/local/BerkeleyDB.4.2/include -I/usr/sfw/include" # LDFLAGS="-L/usr/local/BerkeleyDB.4.2/lib -L/usr/sfw/lib"

-~-

Install OpenSSL

Get package and install it # wget http://www.openssl.org/source/openssl-0.9.7g.tar.gz # tar -zxvf openssl-0.9.7g.tar.gz # ./config shared # make depend # make # make install Link the new libraries into /usr/lib # cd /usr/local/ssl/lib # for FILE in `ls *so*`; do ln -s $FILE /usr/lib; done; # cd /usr/local/src

-~-

Install OpenLDAP

Get package and deflate it # wget http://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.2.26.tgz # tar -zxvf openldap-2.2.26.tgz # cd openldap-2.2.26 Configure, Make and Install # ./configure --without-bdb --disable-bdb --enable-null # make depend # make # make install # cd ..

-~-

Install Kerberos

Get Source # wget http://web.mit.edu/kerberos/dist/krb5/1.4/krb5-1.4.1-signed.tar # tar -xvf krb5-1.4.1-signed.tar # tar -zxvf krb5-1.4.1.tar.gz Configure, Make and Install IMPORTANT This does not work well with GCC 3.3.2. Please install the GCC 3.4.3 package from sunfreeware first. TCL should be installed in /usr/sfw/[bin|lib] # cd krb5-1.4.1/src # ./configure --prefix=/usr --sysconfdir=/etc/krb5 --localstatedir=/var/krb5 --with-tcl=/usr/sfw # make # make install # cd .. Edit configuration Files # vi /etc/krb5/krb5.conf > [libdefaults] > default_realm = YOUR.DOMAIN.COM > ticket_lifetime = 24000 > dns_lookup_realm = false > dns_lookup_kdc = false > >[realms] > ISRC.QUT.EDU.AU = { > kdc = pri-domain-ctrlr.your.domain.com:88 > kdc = sec-domain-ctrlr.your.domain.com:88 > admin_server = pri-domain-ctrlr.your.domain.com:749 > } > >[domain_realm] > your.domain.com = YOUR.DOMAIN.COM > .your.domain.com = YOUR.DOMAIN.COM > > >[logging] > default = FILE:/var/krb5/kdc.log > kdc = FILE:/var/krb5/kdc.log > kdc_rotate = { > period = 1d > versions = 10 > } > >[appdefaults] > kinit = { > renewable = true > forwardable= true > } > pam = { > debug = false > ticket_lifetime = 36000 > renew_lifetime = 36000 > forwardable = true > krb4_convert = false > } > The kinit utility can be used to test your kerberos configuration. # kinit user@YOUR.DOMAIN.COM Password for user@YOUR.DOMAIN.COM: ***** #klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: user@YOUR.DOMAIN.COM Valid starting Expires Service principal 05/11/05 14:39:17 05/11/05 21:40:38 krbtgt/YOUR.DOMAIN.COM@YOUR.DOMAIN.COM renew until 05/18/05 14:39:17 # cd /usr/local/src

-~-

Install pam_krb5

The Solaris pam_krb5 seems to have issues that seem to overcomplicate the Kerberos authentication system (namely: needing stuff in keytab files which other distribs like Linux do not seem to need). I have taken the simple pam_krb5 1.0 module developed by () and modified it slightly to include extra security enhancements and EUID checking, and repackaged it so it compiles under Solaris 10 with GCC.




Download, and build

# tar -zxvf pam_krb5-1.2.tar.gz
# make
# mv /usr/lib/security/pam_krb5.so.1 /usr/lib/security/pam_krb5.so.SOLARIS
# make install

Configuring PAM is detailed later....

-~-

Install Samba

Get Samba # wget http://us1.samba.org/samba/ftp/samba-latest.tar.gz # tar -zxvf samba-latest.tar.gz # cd samba-3.0.14a/source/ ./configure --with-ads --with-ldap --with-windbind \ --with-pam --with-shared-modules=idmap_rid \ --prefix="/usr" --sysconfdir="/etc" \ --localstatedir="/var" *IMPORTANT* - configure does not completely set up the library path. After you run configure, you must edit Makefile, and change the line: LIBS= -lsendfile -lsec -lgen -lresolv -lsocket -lnsl or similar, to include -llber: # vi Makefile > LIBS= -lsendfile -lsec -lgen -lresolv -lsocket -lnsl -llber # make # make install VERY IMPORTANT!! Again, some things aren't quite right. The pam_winbind modules need to be manually copied: # cp nsswitch/pam_winbind.so /usr/lib/security # cp nsswitch/libnss_winbind.so /lib/nss_winbind.so.1 # ln -s /lib/nss_winbind.so.1 /usr/lib/nss_winbind.so.1 A configuration file also needs to be created. The following was used in /usr/lib/smb.conf, with key entries in bold. # vi /usr/lib/smb.conf > [global] > workgroup = DOMAIN > server string = Samba Server (%L) > printcap name = /etc/printcap > printing = cups > load printers = yes > cups options = raw > log file = /var/log/samba/%m.log > max log size = 50 > security = ads > encrypt passwords = yes > socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192 > local master = no > domain logons = no > dns proxy = no > idmap backend = idmap_rid:DOMAIN=1000-1000000 > idmap uid = 1000-1000000 > idmap gid = 1000-1000000 > winbind enum users = yes > winbind enum groups = yes > winbind nested groups = yes > template homedir = /home/%U > template shell = /usr/bin/bash > winbind use default domain = yes > realm = YOUR.DOMAIN.COM > password server = domain-controller.your.domain.com > obey pam restrictions = yes > allow trusted domains = no > > [homes] > comment = Home Directories > browseable = no > writable =yes # mkdir /etc/samba # ln -s /usr/lib/smb.conf /etc/samba/smb.conf

Install pam_mkhomedir

-~-

Linux distributions come with a neat module called pam_mkhomedir. This module will create the users home directory if it does not exist and they authenticated. The module is distributes with the Linux-PAM project source. I have written a script which will fetch Linux-PAM-0.79 (Latest at time of writing), patch it, compile it, and leave pam_mkhomedir.so in your working directory.




set proxy if necessary

# export http_proxy="http://proxy.host.yourdomain.com:3128/"

Download and run script
IMPORTANT Make sure that gcc is using the Solaris
linker ld - ie, it takes a -B option, and ln can take a
-f flag.

# ./make_mkhomedir.sh

===================================================
pam_mkhomedir.so Creator
By Matt Bradford (m.bradford@isi.qut.edu.au)
Configured for PAM-0.79
====================================================
--- Attempting to create pam_mkhomedir.so. ---------
--- If all goes well, it will exist here, ----------
--- in /usr/local/src. -----------------------------
--- Wish me luck... --------------------------------
====================================================
Getting Linux-PAM-0.79.tar.gz...
Extracting...
Configuring...
Prepping...
-> Patching pammodutil files...
Generating Patch...
Patching Makefile...
  Looks like a normal diff.
done
Generating Patch...
Patching modutil_getspnam.c...
  Looks like a normal diff.
done
Building modutils...
modutil_getlogin.c: In function `_pammodutil_getlogin':
modutil_getlogin.c:26: warning: dereferencing type-punned pointer will break strict-aliasing rules
modutil_getlogin.c:31: warning: dereferencing type-punned pointer will break strict-aliasing rules
-> Copying required modutil files...
-> Patching pam_mkhomedir.c...
  Looks like a normal diff.
done
-> Compiling pam_mkhomedir...
-> Linking pam_mkhomedir...
 DONE.
Copying module out of path of destruction...
Removing old source, etc...
Done:
-rwxr-xr-x   1 root     root       82124 May 13 12:32 pam_mkhomedir.so
===================================================

Copy the new module to the PAM module directory.

# cp pam_mkhomedir.so /usr/lib/security/pam_mkhomedir.so.1
# ln -s ./pam_mkhomedir.so.1 /usr/lib/security/pam_mkhomedir.so

-~-

Configure PAM

PAM (Pluggable Authentication Module) Will allow us to hook into the login process, recycling the user's entered credentials. The three modules we installed have the following characteristics:
pam_winbind

  • pam_winbind allows us to authenticate the user through kerberos and fetch user information throuh LDAP
  • pam_winbind DOES NOT give us a cached session ticket
  • pam_winbind (with the use of idmap:rid) allows a unique mapping of domain usernames to UNIX UID's through the use of the RID attribute on active directory domains.
    pam_krb5
  • pam_krb5 ONLY deals with authentication (no user details or authorization)
  • pam_krb5 DOES provide us with a cached session ticket
    pam_mkhomedir
  • This module will create the user's home directory if it doesn't exist.

    We must also consider the following:
  • Accounts are stored on Active Directory
  • ... WITH THE EXCEPTION OF ROOT

    So, with the above in mind, the following PAM config was created:
    # PAM configuration
    #
    # Authentication management
    #
    login   auth optional   /usr/lib/security/$ISA/pam_krb5.so.1 debug
    login   auth sufficient /usr/lib/security/$ISA/pam_winbind.so try_first_pass
    login   auth required   /usr/lib/security/$ISA/pam_unix_cred.so.1 debug
    login   auth required   /usr/lib/security/$ISA/pam_unix_auth.so.1 try_first_pass
    login   auth required   /usr/lib/security/$ISA/pam_dial_auth.so.1 try_first_pass
    #
    dtlogin auth optional   /usr/lib/security/$ISA/pam_krb5.so.1  debug
    dtlogin auth sufficient /usr/lib/security/$ISA/pam_winbind.so try_first_pass
    dtlogin auth required   /usr/lib/security/$ISA/pam_unix_cred.so.1 debug
    dtlogin auth required   /usr/lib/security/$ISA/pam_unix_auth.so.1 try_first_pass
    #
    dtsession auth required /usr/lib/security/$ISA/pam_unix_password.so.1
    #
    rlogin  auth required   /usr/lib/security/$ISA/pam_deny.so
    rsh     auth required   /usr/lib/security/$ISA/pam_deny.so
    #
    other   auth optional   /usr/lib/security/$ISA/pam_krb5.so.1 debug
    other   auth sufficient /usr/lib/security/$ISA/pam_winbind.so try_first_pass
    other   auth required   /usr/lib/security/$ISA/pam_unix_cred.so.1 debug
    other   auth required   /usr/lib/security/$ISA/pam_unix_auth.so.1 try_first_pass
    #
    # Account management
    #
    login   account sufficient      /usr/lib/security/$ISA/pam_winbind.so
    login   account requisite       /usr/lib/security/$ISA/pam_roles.so.1
    login   account required        /usr/lib/security/$ISA/pam_unix_account.so.1
    #
    dtlogin account sufficient      /usr/lib/security/$ISA/pam_winbind.so
    dtlogin account requisite       /usr/lib/security/$ISA/pam_roles.so.1
    dtlogin account required        /usr/lib/security/$ISA/pam_unix_account.so.1
    #
    other   account sufficient      /usr/lib/security/$ISA/pam_winbind.so.1
    other   account requisite       /usr/lib/security/$ISA/pam_roles.so.1
    other   account required        /usr/lib/security/$ISA/pam_unix_account.so.1
    #
    # Session management
    #
    other   session optional        /usr/lib/security/$ISA/pam_mkhomedir.so.1 skel=/etc/skel/ umask=0077
    other   session required        /usr/lib/security/$ISA/pam_unix_session.so.1
    #
    # Password management
    #
    other   password sufficient     /usr/lib/security/$ISA/pam_winbind.so
    other   password required       /usr/lib/security/$ISA/pam_unix_password.so.1
    #
    
    

    This configuration firstly allows us to grab a kerberos ticket from the domain controller. It's optional because it doesn't really really matter if it fails - if it does, the next one will most likely fail as well. We just want this entry to get our ticket.

    The next entry in the auth statements allows us to recycle the provided credentials to winbind. This one is listed as sufficient, so that when a user authenticates against the domain successfully, the PAM modules below winbind do not need to be processed.

    However, if root were to log in, the first two would fail, but would drop down to unix authentication, which is where root's account details are stored.


    Account management only has winbind listed, because winbind is what provides us with account information.

    The user's home directory is made when the session starts - therefore the module is included at the session level.


    -~-

    Conclusion

    Now, When the user logs in, their home directory should be created, and "klist" should reveal a ticket. To test that it is all working correctly, kerberized samba requests can be used to test it: smbclient -k --list //windows-host/share and a list of the shares on the windows (or SAMBA ADS) host should appear without the prompt for a password: # smbclient -k --list //windows-host OS=[Windows 5.0] Server=[Windows 2000 LAN Manager] Sharename Type Comment --------- ---- ------- IPC$ IPC Remote IPC print$ Disk Printer Drivers NETLOGON Disk Logon server share F$ Disk Default share ADMIN$ Disk Remote Admin SYSVOL Disk Logon server share VPLOGON Disk Virus Protect C$ Disk Default share VPHOME Disk Virus Protect VPALERT$ Disk Virus Protect admin_share Disk OS=[Windows 5.0] Server=[Windows 2000 LAN Manager] Server Comment --------- ------- Workgroup Master --------- -------