Using Testsaslauthd on Active Directory

Martin Schweizer schweizer.martin at
Fri Jan 22 01:53:07 EST 2010

Hello Jesus
I've written a smal tutorial about this. It was very hard... See below.
Kind regards,
2010/1/22 Jesus Noland <konpah23 at>

> Hello,
> Hopefully I can get my question answered here. My problem is that I want to
> use testsaslauthd to guery an Active Directory server on campus with my own
> credentials. Is this possible from my laptop running ubuntu desktop? Using
> this syntax:
> user at ubuntu-desktop:~$ testsaslauthd -u user at -p somepassword -r
> (Be careful the lines are probably wrapped).

FreeBSD 7.2: Authentication against Windows 2003 Domain controller
over Kerberos5

The following setup I use to authenticate users on a mail server
(Cyrus Imapd) againts Active Directory (but you can use any
other services too). In this case FreeBSD works as a Kerberos5 client.
Afterwoods I'm able to authenticate with Kerberos5,
PAM and Cyrus SASL (over saslauthd -a PAM or -a Kerberos5).


The first step is to create a user in Active Directory (see Windows
domain controller) for the Unix host. krb5.keytab you need normaly
only for services requests (for example from saslauthd -a kerberos5)

acsvfbsd06# ktutil -v list

Vno Type Principal Date
 4 arcfour-hmac-md5 host/ at ACUTRONIC.CH 2009-09-08

ktutil: krb5_kt_start_seq_get krb4:/etc/srvtab: open(/etc/srvtab): No
such file or directory

Hint: The entries in /etc/srvtab will not be used in this case and can
be ignored. This only for KerberosIV.

To create a /etc/krb5.keytab file you have first to export it from a
domain controller and bind it to the above user name:

C:\Programme\Support Tools>ktpass princ
host/acsvfbsd06.domain.tld at DOMAIN.TLD -crypto RC4-HMAC-NT -ptype
KRB5_NT_SRV_INST -mapuser acsvfbsd06 -pass password out 21.keytab
Targeting domain controller: acsv3k04.domain.tld
Using legacy password setting method
Successfully mapped host/acsvfbsd06.domain.tld to acsvfbsd06.
WARNING: pType and account type do not match. This might cause problems.
Key created.
Output keytab to 21.keytab:
Keytab version: 0x502
keysize 76 host/acsvfbsd06.domain.tld at DOMAIN.TLD ptype 2 (KRB5_NT_SRV_INST)
vno 4 etype 0x17 (RC4-HMAC) keylength 16

Important: pytype should be KRB5_NT_SRV_INST! In any other case it
will not work. This is because Kerberos5 looks in this
file and search this type of key. If the type is wrong you get under
different cirscumstance different error messages in


- saslauthd -a pam
Sep 2 08:42:22 acsvfbsd06 saslauthd[772]: pam_krb5:
verify_krb_v5_tgt(): krb5_kt_read_service_key(): Key table entry not

- saslauthd -a kerberos5
Sep 2 08:42:22 acsvfbsd06 saslauthd[42062]: do_auth : auth
failure: [user=user][service=imap] [realm=] [mech=kerberos5]

After you create the keytab file you have to securly transfer the file
to the FreeBSD host. If there exists one you can import the new key in
/etc/krb5.keytab as following:

ktutil copy /usr/home/martin/21.keytab /etc/krb5.keytab

The file /etc/krb5.keytab has (after the creation) the following rights:

-rw------- 1 root wheel 86B 8 Sep 08:20 krb5.keytab

- The settings from /etc/krb5.conf will be used.
- kinit creates user owned Kerberos tickes. It's located under
/tmp/krb5cc_<uid>, (for example kinit root => /tmp/krb5cc_0)

You can use kinit to test the basic Kerberos mechanism on FreeBSD
(without parameters). Then /etc/krb5.keytab will not be used.

acsvfbsd06# klist -v
Credentials cache: FILE:/tmp/krb5cc_0
  Principal: martin at DOMAIN.TLD
  Cache version: 4

Server: krbtgt/DOMAIN.TLD at DOMAIN.TLD
Ticket etype: arcfour-hmac-md5, kvno 2
Auth time: Sep 8 07:40:45 2009
End time: Sep 8 17:40:25 2009
Renew till: Sep 15 07:40:45 2009
Ticket flags: renewable, initial, pre-authenticated
Addresses: IPv4:192.168.x.y

Server: ldap/acsv3k04.domain.tld at DOMAIN.TLD
Ticket etype: arcfour-hmac-md5, kvno 22
Auth time: Sep 8 07:40:45 2009
Start time: Sep 8 07:40:50 2009
End time: Sep 8 17:40:25 2009
Ticket flags: pre-authenticated, ok-as-delegate
Addresses: IPv4:192.168.x.y

kinit -k <username> can be used to test the keytab file. If you get no
message then the authentication is ok and the tickets will deleted
imediatly. If you get init: krb5_get_init_creds: Additional
pre-authentication required, then only the pre-authentication is
failed (see under Windows domain controller).


Important: kinit should be executed before!

With ldapsearch you can test the ldap functionality against the domain

acsvfbsd06# ldapsearch -v -LLL -b
"OU=Mitgliedsserver,OU=ACH,DC=domain,DC=tld" -h acsv3k04.domain.tld
ldap_initialize( ldap://acsv3k04.domain.tld )
SASL/GSSAPI authentication started
SASL username: martin at DOMAIN.TLD
SASL data security layer installed.
filter: (objectclass=*)
requesting: description
dn: OU=Mitgliedsserver,OU=ACH,DC=domain,DC=tld

Important: If you use default_etypes_des in your etc/krb5.conf,
ldapsearch will fail.

After the first ldapsearch query you get an additional Kerberos ticket
(see under kinit).

  default_realm = DOMAIN.TLD

  kdc = acsv3k04.domain.tld:88

  domain.tld = DOMAIN.TLD
  .domain.tld = DOMAIN.TLD
  .acsv3k04.domain.tld = DOMAIN.TLD
  acsv3k04.domain.tld = DOMAIN.TLD
  .acsvfbsd06.domain.tld = DOMAIN.TLD
  acsvfbsd06.domain.tld = DOMAIN.TLD
  acsvfbsd06 = DOMAIN.TLD


domain domain.tld
nameserver 192.168.x.y


With the settings below you get no DNS overhead. acsv3k04.domain.tld

Cyrus SASL

First you need to compile Cyrus SASL with all authentication mechanisms:

acsvfbsd06# saslauthd -h
usage: saslauthd [options]

option information:
 -a <authmech> Selects the authentication mechanism to use.
 -c Enable credential caching.
 -d Debugging (don't detach from tty, implies -V)
 -r Combine the realm with the login before passing to
authentication mechanism
  Ex. login: "foo" realm: "bar" will get passed as
login: "foo at bar"
  The realm name is passed untouched.
 -O <option> Optional argument to pass to the authentication
 -l Disable accept() locking. Increases performance, but
  may not be compatible with some operating systems.
 -m <path> Alternate path for the saslauthd working directory,
  must be absolute.
 -n <procs> Number of worker processes to create.
 -s <kilobytes> Size of the credential cache (in kilobytes)
 -t <seconds> Timeout for items in the credential cache (in seconds)
 -v Display version information and available mechs
 -V Enable verbose logging
 -h Display this message.

saslauthd 2.1.23
authentication mechanisms: sasldb getpwent kerberos5 pam rimap ldap

saslauthd you start in /etc/rc.conf with -a pam or -a kerberos5


In my setup I use PAM for central authentication. If you use Cyrus
SASL/Imapd you need the service name "imap". So the
correspondend file in /etc/pam.d should have the name imap.

auth required try_first_pass no_user_check
account required
password required
session required
Hint: do not check the fields Vno and encryption
(arcfour-hmac-md5) from the keytab file (see the source code in
/usr/src/lib/libpam/modules/pam_krb5). looks for a principal
host/acsvfbsd06.domain.tld at DOMAIN.TLD with the type KRB5_NT_SRV_INST
(see krb5.keytab/ktpass)

In the actual version of /usr/src/lib/libpam/modules/pam_krb5 there is
a long outstanding bug (see PR The problem is
the authentication is only successfully if the authenticated user is
also in the local FreeBSD passwd file. To change this you have to
apply the patch below an set the option no_user_check in
/etc/pam.d/imap (see PAM).

--- pam_krb5.c.orig Tue Feb 10 10:13:20 2004
+++ pam_krb5.c Sun Jan 9 23:58:36 2005
@@ -89,6 +89,7 @@
 #define PAM_OPT_FORWARDABLE "forwardable"
 #define PAM_OPT_NO_CCACHE "no_ccache"
 #define PAM_OPT_REUSE_CCACHE "reuse_ccache"
+#define PAM_OPT_NO_USER_CHECK "no_user_check"
 * authentication management
@@ -213,11 +214,13 @@
  PAM_LOG("PAM_USER Redone");
- pwd = getpwnam(user);
- if (pwd == NULL) {
- retval = PAM_USER_UNKNOWN;
- goto cleanup2;
- }
+ if (!openpam_get_option(pamh, PAM_OPT_NO_USER_CHECK)) {
+ pwd = getpwnam(user);
+ if (pwd == NULL) {
+ retval = PAM_USER_UNKNOWN;
+ goto cleanup2;
+ }
+ }
  PAM_LOG("Done getpwnam()");

Windows domain controller

As a directory you can use the following article:
(Step-by-Step Guide to Kerberos 5 (krb5 1.0) Interoperability )
- Windows Security and Directory Services for UNIX v1.0 (onlsy
available on

As a first step you should create a user which has the same name as
your FreeBSD host. This user name you need in combination with ktpass
(see krb5.keytab). Additional your FreeBSD host should be resolvable
by DNS with PTR and A record.

Do not use the Support tools from Windows 2000, because ktpass has not
the same options (for example encryption).

If you see error messages in the Eventlog (Security) on your domain
controller like:

(sorry only in german available)

Ereignistyp: Fehlerüberw.
Ereignisquelle: Security
Ereigniskategorie: Kontoanmeldung
Ereigniskennung: 675
Datum: 08.09.2009
Zeit: 08:22:00
Computer: ACSV3K04
Fehlgeschlagene Vorbestätigung:
  Benutzername: martin
  Benutzerkennung: ACH\martin
  Dienstname: krbtgt/DOMAIN.TLD
  Vorauthentifizierungstyp: 0x0
  Fehlercode: 0x19

... then the user name is successfully authenticated. The error shows
only the pre-authentication is failed see:

0x19 (KDC_ERR_PREAUTH_REQUIRED) "Additional pre-authentication"
The client did not send pre-authorization, or did not send the
appropriate type of pre-authorization, to receive a ticket.
The client will retry with the appropriate kind of pre-authorization
(the KDC returns the pre-authentication type in the
error). Many Kerberos implementations will start off without
preauthenticated data and only add it in a subsequent request
when it sees this error. In this case, this error can safely be ignored.

You need the following ports: 88 (for Kerberos), 53 (for DNS) and 389
(for ldap).

Therewith you have no DNS resolve problems it is a good idea to use a
domain DNS server in /etc/resolv.conf.

You need also this DNS record:


- Kerberos:
- PAM:
- Principal/ktpass:

Martin Schweizer
schweizer.martin at
Tel.: +41 32 512 48 54 (VoIP)
Fax: +1 619 3300587
-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Cyrus-sasl mailing list