New Version Woes

I’ve been fighting the last few months with upgrading the underlying libraries for my SSO scheme to the most recent releases. I am not certain whether the change is in Cyrus SASL or OpenLDAP, but using either SASL 2.1.25 or any OpenLDAP > 2.4.23 breaks GSSAPI authentication against Windows 2003 and 2008 for LDAPs horribly. Not using maxssf=0 results in the well-documented malformed packets, while using it returns a SASL error (could not read required input). Not sure yet how to track that one down.

Posted in Uncategorized | Leave a comment

Solaris and external users’ home directories

The Solaris automounter is a nifty toy. I filched a script from znogger (http://znogger.blogspot.com) with some modifications found in his comments section, and configured the automounter to automatically create and mount my home directories. In relevant part, add

/export/home/adusers /etc/auto_homedir

to /etc/auto_master,

* localhost:/export/home/&

to /etc/auto_home, and set up znogger’s /etc/auto_homedir script as per his instructions. Anything I don’t need to do in the PAM stack is a good thing.

Posted in Active Directory, Integration | Leave a comment

Solaris 10 + Windows 2003 R2 (Take 2)

Turns out this was a bit more of a project than I thought. Something in Solaris’ PAM stack dies horribly when using PADL’s nss_ldap for name lookup; as it turns out, though, configuring the Solaris 10 LDAP client works around the problem, even if I still cannot get useful returns out of it and thus am still working with PADL’s nss_ldap and OpenLDAP.

Configuration for Solaris 10 LDAP:

ldapclient manual -a credentialLevel=self -a authenticationMethod=sasl/GSSAPI -a defaultSearchBase=dc=lab, dc=network -a domainName=lab.network -a defaultServerList=w2003r2.lab.network -a objectclassMap=passwd:posixAccount=user      -a objectclassMap=shadow:shadowAccount=user      -a objectclassMap=group:posixGroup=group      -a attributeMap=passwd:uid=sAMAccountName      -a attributeMap=passwd:homeDirectory=unixHomeDirectory      -a attributeMap=shadow:uid=sAMAccountName      -a attributeMap=shadow:shadowLastChange=pwdLastSet      -a attributeMap=group:uniqueMember=member -a defaultSearchScope=sub

Not nice to have to do that, but it works.

Posted in Active Directory, Integration | Leave a comment

Solaris 10 (x86) + Windows 2003

This largely works like Solaris 9; theoretically, it’s probably possible to accomplish this with Solaris 10’s onboard tools, but I could not figure out how. If anyone can fill me in, leave a comment. There is one change – building nss_ldap requires copying the file vers_string to a directory in the executable searchpath or modifying the PATH variable.

To get the new OpenSSH to start as a service, modify the file /lib/svc/method/sshd, point the SSH_KEYGEN and SSHDIR variables to the appropriate places in /opt/local and modify the start line to start the new sshd executable.

Posted in Active Directory, Integration | Leave a comment

Solaris 9 (SPARC) + Windows 2003 R2

 

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.

  1. GNU make
  2. openssl
  3. MIT krb5
  4. cyrys-sasl 2.1.22
  5. openldap
  6. PADL nss_ldap
  7. Russ Albery’s fork of pam_krb5
  8. samba
  9. 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.

Posted in Active Directory, Integration | Leave a comment

Adventures in System Administration

Having recently started a full-time position as systems admin, I decided it might be time to shake a few more things up. So, I am launching this blog to discuss interesting and challenging projects I am working on (all names changed, of course, to protect the guilty). My first post series will deal with integration of UNIX servers into Active Directory. The goals are user and group administration through Active Directory, and single sign-on capability for both UNIX and Windows systems. This is to be accomplished without the need to store any passwords in plaintext files. A host keytab file is acceptable, as it is a necessary evil of Kerberos 5. I will discuss integrating Solaris 9 / Windows 2003 R2, Solaris 10 / Windows 2003 R2, Linux / Windows 2003 R2, Solaris 10 / Windows 2008 R2, Solaris 11 / Windows 2008 R2 and Linux / Windows 2008 R2.

Posted in Plans | Leave a comment