Integrating Solaris 10 with Active Directory

And heres the recipe, edited 2009-07-03.

This is a howto for using Kerberos/LDAP to authenticate a Solaris 10 machine against Active Directory.

This is mostly cribbed from here:

It presumes the existence of a domain DOMAIN, a Unix box (some-machine.local) which can run zones.

The outline is basically:
1. Create a key on a DC
2. Install software on the machine
3. Configuring the machine

In all the examples the machines called smbtest.

Creating a key on a DC

First create a user in the AD, and put them in the proper place, something like: Users/Services/unix

Firstname/Full name is the server name: sfu-smbtest
User logon name is: sfu-smbtest
User logon name (pre-Windows 2000) is: sfu-smbtest

Untick “must change password at next logon”

Tick “password never expires”
“User cannot change password”

Generate a good random password using something like this:
$ pwgen -s 25 1

From a cmd prompt:

ktpass -out smbtest.keytab -mapuser "DOMAINsfu-smbtest" -pass rndpass  -ptype KRB5_NT_PRINCIPAL /princ "host/sfu-smbtest@DOMAIN.LOCAL"

Targeting domain controller: dc.domain.local
Successfully mapped host/sfu-smbtest to sfu-smbtest.
Key created.
Output keytab to smbtest.keytab:
Keytab version: 0x502
keysize 52 host/sfu-smbtest@DOMAIN.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x3
 (DES-CBC-MD5) keylength 8 (0x07b31a584ae3d670)
Account smbtest has been set for DES-only encryption.

Now move the key over to your Unix box using something like:

pscp.exe smbtest.keytab bluefoo@some-machine:/export/home/bluefoo

Installing software on the machine

Log into your zone-running machine, some-machine.local.

1. Setup zone (making it sparse or full as appropriate)

# mkdir -p /zones/smbtest
# chmod 700 /zones/smbtest

# zonecfg -z smbtest
set zonepath=/zones/smbtest
set autoboot=true
add net
set address=
set physical=ge0

( Dump the config )

# zonecfg -z smbtest export

( Now to make it non-sparse remove all the inherit-pkg-dir entries, they should be these but may be others )

# zonecfg -z smbtest
zonecfg:smbtest> remove inherit-pkg-dir dir=/lib
zonecfg:smbtest> remove inherit-pkg-dir dir=/platform
zonecfg:smbtest> remove inherit-pkg-dir dir=/sbin
zonecfg:smbtest> remove inherit-pkg-dir dir=/usr
zonecfg:smbtest> verify
zonecfg:smbtest> exit

2. Install zone

# zoneadm -z smbtest install
# zoneadm -z smbtest boot

3. Configure the zone

# zlogin -C smbtest

4. Setup DNS

# cp /etc/nsswitch.conf /etc/nsswitch.conf.back
# cp /etc/nsswitch.dns /etc/nsswitch.conf

Fix your resolv.conf

5. Download the blastwave package manager
See for reference

( Download )

$ ssh some-machine
$ wget
$ sudo /usr/sbin/zlogin smbtest

( Copy package over )

# cd /tmp
# scp bluefoo@some-machine:~/pkgutil_sparc.pkg .

6. Install CSW/Blastwave software

# pkgadd -d ./pkgutil_sparc.pkg
# export http_proxy="http://wwwcache.domain.local:8080/"
# /opt/csw/bin/pkgutil --catalog 
# /opt/csw/bin/pkgutil --install gnupg textutils 
# /opt/csw/bin/pkgutil --install wget
# /opt/csw/bin/wget
# /opt/csw/bin/gpg --import gpg_key.txt

# /opt/csw/bin/pkgutil --install CSWautomake CSWbzip2 CSWgcc3 CSWgcc3adart CSWgcc3core CSWgcc3corert CSWgcc3g++ CSWgcc3g++rt CSWgcc3g77rt CSWgcc3javart CSWgcc3objcrt CSWgcc3rt CSWgmake CSWlibtool CSWlibtoolrt CSWncurses CSWossl CSWossldevel CSWosslrt CSWosslutils CSWperl  CSWreadline CSWsasl CSWsaslgssapi CSWsunmath CSWtcpwrap CSWtextutils CSWvim CSWvimrt CSWzlib CSWgtar CSWbinutils CSWfindutils CSWgsed CSWggrep

( Use something like this to catch most of it )

# cd /opt/csw/bin
#  gfind . -type f -iname 'g*' | gsed -e 's#./##' | gsed -e 's/^g//' | xargs -I{} ln -s "g{}" "{}"

( Do the special cases (i.e. already symlinks) by hand )

# ln -s gstrip strip
# ln -s gar ar
# ln -s gld ld
# ln -s gas as
# ln -s gnm nm
# ln -s gobjcopy objcopy
# ln -s gobjdump objdump
# ln -s granlib ranlib

( Bodge the library path )

# crle -l /usr/local/lib:/opt/csw/lib:/lib:/usr/lib

7. Setup other bits of the OS:

Fix your path by editing .bashrc for root. See:

if [[ ! -z "$PS1" ]]; then
        export PS1="u@h:w \$ "

export PATH=/opt/csw/gcc3/bin:/opt/csw/bin:$PATH
export http_proxy="http://wwwcache.domain.local:8080/"
export ftp_proxy="http://wwwcache.domain.local:8080/"

( Sort out /usr/local )

# cd /usr
# mkdir local
# cd local
# mkdir bin src lib man include share var sbin

Create kinit_nssldap_ccache in /usr/local/sbin then chmod 755 it.

# Have this as /usr/local/sbin/kinit_nssldap_cache and run it from cron hourly

kinit -c $CACHEFILE -k -t $KEYTAB host/sfu-$HOSTNAME@DOMAIN.LOCAL && 
 chown root ${CACHEFILE} && chmod 644 ${CACHEFILE}

8. Install OpenLDAP

( Bodge libraries )

# cd /usr/lib
# ln -s
# ln -s

( Main install )

# cd /usr/local/src
# wget
# tar xzf  openldap-2.4.16.tgz 
# cd openldap-2.4.16
# export CFLAGS="-I/usr/include -I/usr/local/include -I/opt/csw/include -I/usr/include/kerberosv5" 
# export LDFLAGS="-R/lib -L/lib -R/usr/lib -L/usr/lib -R/usr/local/lib -L/usr/local/lib -R/opt/csw/lib -L/opt/csw/lib"
# export LDADD="-L/lib -L/usr/lib -L/usr/local/lib -L/opt/csw/lib -R/usr/local/lib -R/opt/csw/lib"
# ./configure --prefix=/usr/local --enable-slapd=no --with-tls --without-threads --disable-shared --with-gssapi --with-cyrus-sasl
# make depend && make all
# make install

If you want to see the SASL stuff is built into openldap properly then use this, however it only works after the ldap.conf has been setup and kinit_nss_ldap script run.

# ldapsearch -x -LLL -s "base" -b "" supportedSASLMechanisms

You should see:

supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: EXTERNAL
supportedSASLMechanisms: DIGEST-MD5

Why the symlinks?

  • GSSAPI_LIBS in the Makefile gets autodetected to gssapi_krb5 because configure is looking for and Sun use
  • Symlinks make it find them first time
  • Yes I tried: export LIBS=” -lgss ” It didn’t work.

( Now fix /etc/nsswitch.conf with something like this )

# the following two lines obviate the "+" entry in /etc/passwd and /etc/group.
passwd:         files ldap [TRYAGAIN=3]
group:          files ldap [TRYAGAIN=3]

# consult DNS first, we will need it to resolve the LDAP host. (If we
# can't resolve it, we're in infinite recursion, because libldap calls
# gethostbyname(). Careful!)
hosts:          files dns

# LDAP is nominally authoritative for the following maps.
services:   files
networks:   files
protocols:  files
rpc:        files
ethers:     files

# no support for netmasks, bootparams, publickey yet.
netmasks:   files
bootparams: files
publickey:  files
automount:  files

# I'm pretty sure nsswitch.conf is consulted directly by sendmail,
# here, so we can't do much here. Instead, use bbense's LDAP
# rules ofr sendmail.
aliases:    files
sendmailvars:   files

# Note: there is no support for netgroups on Solaris (yet)
netgroup:   ldap [NOTFOUND=return] files

9 Compiling nss_ldap:

# cd /usr/local/src
# wget
# tar xzf nss_ldap.tgz
# cd nss_ldap-264

# export CFLAGS="-I/usr/local/include -I/opt/csw/include -I/usr/include/kerberosv5"
# export LDFLAGS="-L/usr/local/lib -L/opt/csw/lib"
# ./configure --with-prefix=/usr/local --enable-rfc2307bis --with-ldap-dir=/usr/local  --with-ldap-lib=openldap --with-ldap-conf-file=/etc/libnss-ldap.conf 

# export LDADD="-L/usr/local/lib -L/opt/csw/lib -R/usr/local/lib -R/opt/csw/lib"
# make

# make install all prefix=/usr/local
 +++ WARNING: This make install line will stamp on your /etc/libnss-ldap.conf +++

( Then create a symlink to make it available to nsswitch )

# cd /lib
# mv
# mv
# ln -s /usr/local/lib/ /lib/
# ln -s

# cd /usr/lib
# mv
# ln -s /usr/local/lib/ /usr/lib/

( And symlink the libnss ldap config into the main ldap config )

# mv /etc/libnss-ldap.conf /etc/libnss-ldap.conf.orig
# ln -s /usr/local/etc/openldap/ldap.conf /etc/libnss-ldap.conf 

Configuring the machine

1. First configure ldap.conf which is stored here:


The example is here:

host dc.domain.local dc2.domain.local
base dc=DOMAIN,dc=LOCAL
timelimit 120
bind_policy soft

use_sasl on
sasl_secprops maxssf=0
krb5_ccname FILE:/tmp/.ldapcache

nss_paged_results yes

nss_base_passwd ou=Users,dc=DOMAIN,dc=LOCAL
nss_base_group ou=Groups,dc=DOMAIN,dc=LOCAL

nss_map_attribute   uid           msSFU30Name
nss_map_attribute   uidNumber     msSFU30UidNumber
nss_map_attribute   gidNumber     msSFU30GidNumber
nss_map_attribute   loginShell    msSFU30LoginShell
nss_map_attribute   homeDirectory msSFU30HomeDirectory
nss_map_attribute   uniqueMember  member
nss_map_attribute   gecos         displayName

nss_map_objectclass posixAccount  User
nss_map_objectclass shadowAccount User
nss_map_objectclass posixGroup    Group


nss_schema rfc2307bis
nss_initgroups backlink
nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,radvd,tomcat,radiusd,news,mailman,nscd

# PAM settings
pam_login_attribute msSFU30Name
pam_filter objectclass=User

pam_min_uid 500
pam_max_uid 0

2. Import the keytab generated on the DCs

# cd /etc/krb5

( Retrieve it from where you stored it in step 1 right at the start )

# scp bluefoo@some-machine:~/smbtest.keytab .

( This will import it )

# ktutil
rkt /etc/krb5/smbtest.keytab
write_kt /etc/krb5/krb5.keytab

 ( Verify it was imported correctly )

# ktutil
rkt /etc/krb5/krb5.keytab

( You should get something like this )

slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    3                host/smbtest@DOMAIN.LOCAL

( The KVNO may well change )

3. Configure kerberos

# mv /etc/krb5/krb5.conf /etc/krb5/krb5.conf.orig

Then use this krb5.conf

    default = FILE:/var/log/krb5libs.log
    admin_server = FILE:/var/log/kadmind.log

    default_realm = DOMAIN.LOCAL
    dns_lookup_realm = true
    dns_lookup_kdc = true
    ticket_lifetime = 24h
    forwardable = yes
    verify_ap_req_nofail = false

    .domain.local = DOMAIN.LOCAL
    domain.local = DOMAIN.LOCAL

    pam = {
      debug = false
      ticket_lifetime = 36000
      renew_lifetime = 36000
      forwardable = true
      krb4_convert = false

4. Put the local shell in place if your using this as a machine nonspecific shell

# ln -s /usr/bin/bash /usr/bin/local-sh

5. Fix PAM

You can control access to the machine by changing the “other” and
“login” segments. However to just control SSHd access using Kerberos then use the following snippet by appending it to /etc/pam.conf

# Change the Login section to look like this:
login   auth requisite
login   auth required 
login   auth sufficient
login   auth required 
login   auth required 
login   auth required 
# Change the other section to look like this:
other   auth requisite
other   auth required 
other   auth required 
other   auth sufficient
other   auth required 

6. Restart services

# svcadm disable svc:/milestone/name-services:default svc:/network/ssh:default svc:/network/ldap/client:default svc:/system/name-service-cache:default

# svcadm enable svc:/milestone/name-services:default svc:/network/ssh:default svc:/network/ldap/client:default

Note that we don’t reenable name-service-cache because it doesn’t allow you to use the symlinked versions of

7. Test your system

# /usr/local/sbin/kinit_nssldap_ccache
# ldapsearch -v -b "dc=domain,dc=local" -Y "GSSAPI" "cn=bluefoo"
# id bluefoo
# groups bluefoo
# getent passwd bluefoo

$ ssh bluefoo@smbtest.domain.local

3 thoughts on “Integrating Solaris 10 with Active Directory

  1. darius_of_lancs

    ok, that looks hideous. It ‘feels’ hideous too. It feels like you have to create a braindead solaris box, slave it mutantly to AD then, try to uplift it back to normal.


    it also looks incredibly neato

      1. mostlyfoo

        Yeah, basically you swap out Sun’s nss_ldap for Padl’s nss_ldap, and install OpenLDAP on the side. Sun’s Kerberos appears to work (although samba doesn’t play nicely with it) so you can keep that.

        The real issue is that nscd blows up with the symlinked nss_ldap, further testing will reveal if just copying the files in place is a better plan.


Leave a Reply