This one is not for the faint of heart – on Solaris 9, some surgery is required to get things working as laid out in my initial post. To begin with, you will need some development environment; I was fortunate enough that our senior DBA left me with a working toolchain (gcc, Sun assembler and linker, C library and headers) on the host I worked on, so I am not sure what is required to get to that stage. Once you are there, though, you will need a few additional packages. Unless a specific version is noted, the latest available at the time of this writing were used when I set this up.
- GNU make
- openssl
- MIT krb5
- cyrys-sasl 2.1.22
- openldap
- PADL nss_ldap
- Russ Albery’s fork of pam_krb5
- samba
- openssh
You will also need to configure your domain controller with the “Identity Management for UNIX” component and enable at least one user and group for UNIX use.
Environment variables set were
CPPFLAGS=”-I/opt/local/include”
LDFLAGS=”-L/opt/local/lib -R/opt/local/lib”
To avoid picking up system GSSAPI headers, I executed
mv /usr/include/gssapi /usr/include/gssapi.old
I configured make to install in /usr/local – so a straight CMMI install did exactly what was needed. For openssl, I configured with the options
–prefix=/opt/local solaris-sparcv9-gcc shared zlib zlib-dynamic
After build, all tests passed. Kerberos was another CMMI install, with prefix /opt/local. Cyrus SASL needed some massaging, though. After configuring with
–prefix=/opt/local –with-gss_impl=mit –with-openssl=/opt/local –with-plugindir=/opt/local/lib/sasl2 –with-configdir=/opt/local/lib/sasl2
and running gmake, I discovered that the resulting GSSAPI plugin did not have the proper RPATH set to pick up the Kerberos libraries at runtime. As it turns out, libtool stripped out the -R flag for me when linking plugins. I resolved this by relinking with the command
/usr/ccs/bin/ld -G -h libgssapiv2.so.2 -o .libs/libgssapiv2.so.2.0.22 gssapi.lo gssapiv2_init.lo plugin_common.lo -L/opt/local/lib -R/opt/local/lib -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lkrb5support -lresolv -lresolv -lsocket -lnsl -lresolv -lresolv -lsocket -lc
executed in the plugins subdirectory of the SASL source tree. Openldap was configured with the server disabled – I only needed client tools and libraries.
–prefix=/opt/local –disable-slapd
It picked up cyrus-sasl and openssl from the environment variables alone, built and installed fine. At this point, I was ready to do an initial functionality test. I configured /opt/local/etc/krb5.conf for my environment
[libdefaults]
default_realm = LAB.NETWORK
[realms]
LAB.NETWORK = {
}
[domain_realm]
lab.network = LAB.NETWORK
Then I acquired a ticket for my test user
/opt/local/bin/kinit testuser
And finally executed an LDAP search over my AD tree to ensure that so far, my stack was working.
/opt/local/bin/ldapsearch -H ldap://win2003r2.lab.network -Y gssapi -Omaxssf=0 -b c=lab,dc=network
This might fail in a number of ways. If your kinit failed, you will need to troubleshoot your kerberos configuration. If the LDAP search fails, make sure you have the right version of Cyrus SASL and you are setting -Omaxssf=0 ; failing to do so /will/ make the LDAP search fail. Once the stack is working to this point, it’s time to proceed.
The next step is to integrate the LDAP directory with NSS. I chose PADL’s nss_ldap package for this. I am aware of the recent forks and improvements to that code, but for this project, I preferred simplicity. Even so, some source code changes were required.
First, in ldap-init-krb5-cache.c,insert
#define HOST_NAME_MAX 255
at the top of the preprocessor directives, and insert
#include <limits.h>
before the #ifndef HEIMDAL. Finally, remove the line
typedef struct _profile_t *profile_t;
I made another change in another file to make sure my SASL headers were picked up, but that might be placebo. In ldap-nss.c, between #include <sasl.h> and #endif, insert
#elif defined(HAVE_SASL_SASL_H)
#include <sasl/sasl.h>
At this point, nss_ldap can be configured with
–prefix=/opt/local –with-ldap-lib=openldap –with-ldap-dir=/opt/local –with-gssapi-dir=/opt/local –enable-rfc2307bis –enable-configurable-krb5-keytab –enable-krb –enable-sasl
built, and installed. The resulting nss_ldap.so.1 will need to be copied to /usr/lib, overwriting the system one – be sure to make backups. Then, create /etc/ldap.conf
uri ldap://win2003r2.lab.network
scope sub
timelimit 30
bind_policy soft
use_sasl on
SASL_MECH GSSAPI
sasl_secprops maxssf=0
krb5_ccname FILE:/tmp/krb5cc_0
nss_schema rfc2307bis
nss_base_passwd dc=lab,dc=network
nss_base_shadow dc=lab,dc=network
nss_base_group dc=lab,dc=network
nss_map_objectclass posixAccount User
nss_map_objectclass shadowAccount User
nss_map_objectclass posixGroup group
nss_map_attribute uid sAMAccountName
nss_map_attribute uidNumber uidNumber
nss_map_atrribute gidNumber gidNumber
nss_map_attribute uniqueMember member
nss_map_attribute givenname givenName
nss_map_attribute homeDirectory unixHomeDirectory
nss_map_attribute loginShell loginShell
nss_map_attribute shadowLastChange pwdLastSet
pam_login_atrribute sAMAccountName
pam_filter objectclass=User
pam_password ad
pam_member_attribute uniquemember
pam_groupdn dc=lab,dc=network
Change the passwd and group lines in /etc/nsswitch.conf to read
passwd: files ldap [NOTFOUND=continue]
group: files ldap [NOTFOUND=continue]
At this point, run
getent passwd
and make sure your UNIX-enabled Active Directory users and groups show up. If they do not, add the line “debug 1″ to the top of ldap.conf to get some debugging output from nss_ldap and try to troubleshoot what is going wrong here.
Once NSS is working, it’s time to get the system authenticating to Active Directory as itself, rather than using a user ticket. Configure Samba with
–prefix=/opt/local –with-krb5=/opt/local –with-ads –without-winbind –with-libiconv=/usr/local LIBS=-lintl
build and install. Then set up an smb.conf in /opt/local/lib
[global]
workgroup = LAB
realm = LAB.NETWORK
security = ADS
kerberos method = system keytab
and execute
/opt/local/bin/net -k ads join
/opt/local/bin/net -k ads keytab create
/opt/local/bin/kdestroy
/opt/local/bin/kinit -k SOLARIS9$
Where SOLARIS9 is the name of your Sun box. Then verify LDAP lookups are still working by running
getent passwd
You might see a DNS update error when executing the net join – this is harmless. It is caused by restrictive permissions on who can and cannot update DNS dynamically, and I have not yet found a reliable workaround. One possibility is to pre-create the A record and computer account for your UNIX system, and give the UNIX box full control of its A record.
Once the getent works with the computer account’s ticket, it’s time for the last step: integrate Kerberos into the PAM stack and get remote logins working. Unfortunately, the system pam_krb5 module is too old to work reliably (I kept having packet fragmentation problems, and it does not support Kerberos via TCP). So, install Russ Albery’s fork of pam_krb5, configured with
–prefix=/opt/local –with-krb5=/opt/local
and replace the pam module in /lib/security with the newly built one. Then change the pam configuration to consider the Unix authentication modules “sufficient,” enable the krb5 authentication module, and configure it to be “required” for the “other” service. Finally, configure OpenSSH with
–prefix=/opt/local –with-kerberos5=/opt/local –with-pam
configure a user and group “sshd” with home directory /var/empty and login shell /bin/false, and run
make tests
on the newly built SSH server. This will replace the system SSH server, so making sure it works right is essential before installing it. Once installed, change the startup script in /etc/init.d/ssh to launch /opt/local/sbin/sshd rather than the the system SSH server, configure /opt/local/etc/sshd_config to allow PAM authentication, GSSAPI authentication and (at least for now) root login, copy the host keys over, and restart SSH. Make sure you can log in from a new Putty window before logging out.
If this works, all you need is to create a cronjob to refresh the Kerberos ticket every 24 hours.