Getting pam-krb5 working with cifs and autofs

On: Mon 17 April 2017

The recent update to ubuntu 17.04 broke everything about my setup, so i had to spend a lot of time understanding what changed so i could fix it.

pam-krb5 uses by default a slightly different path to the default for its credential cache.

/tmp/krb5cc_UID_RANDOM where UID is the user's UID and RANDOM is six randomly-chosen letters

cifs-utils has a helper function called cifs.upcall. It has had many changes over the last year. Notably 6.6 changed the way that correct credential caches was found.

Prior to 6.5, it would search for all cache files in /tmp/krb5cc* and see if the owner matched the requestor.

We can see this behaviour here:

Apr  9 17:33:09 rif cifs.upcall: key description: cifs.spnego;0;0;39010000;ver=0x2;host=server;ip4=192.168.50.2;sec=krb5;uid=0x0;creduid=0x44c;user=root;pid=0x8bb
Apr  9 17:33:09 rif cifs.upcall: ver=2
Apr  9 17:33:09 rif cifs.upcall: host=server
Apr  9 17:33:09 rif cifs.upcall: ip=192.168.50.2
Apr  9 17:33:09 rif cifs.upcall: sec=1
Apr  9 17:33:09 rif cifs.upcall: uid=0
Apr  9 17:33:09 rif cifs.upcall: creduid=1100
Apr  9 17:33:09 rif cifs.upcall: user=root
Apr  9 17:33:09 rif cifs.upcall: pid=2235
Apr  9 17:33:09 rif cifs.upcall: find_krb5_cc: considering /tmp/krb5cc_1100_drGvxJ
Apr  9 17:33:09 rif cifs.upcall: find_krb5_cc: FILE:/tmp/krb5cc_1100_drGvxJ is not a valid credcache.
Apr  9 17:33:09 rif cifs.upcall: find_krb5_cc: considering /tmp/krb5cc_0
Apr  9 17:33:09 rif cifs.upcall: find_krb5_cc: FILE:/tmp/krb5cc_0 is valid ccache
Apr  9 17:33:09 rif cifs.upcall: handle_krb5_mech: getting service ticket for grunt.variar.net
Apr  9 17:33:09 rif cifs.upcall: handle_krb5_mech: obtained service ticket
Apr  9 17:33:09 rif cifs.upcall: Exit status 0

After 6.6 it requires that the credential cache location be hard coded in the krb5.conf file.

6.7 additionally had an extra feature whereby it could find the KRB5CCNAME environment variable from the other session.

Once its working it should look something like:

Apr 17 22:27:38 rif cifs.upcall: key description: cifs.spnego;0;0;39010000;ver=0x2;host=server;ip4=192.168.50.2;sec=krb5;ui
d=0x44c;creduid=0x44c;user=root;pid=0x3584
Apr 17 22:27:38 rif cifs.upcall: ver=2
Apr 17 22:27:38 rif cifs.upcall: host=server
Apr 17 22:27:38 rif cifs.upcall: ip=192.168.50.2
Apr 17 22:27:38 rif cifs.upcall: sec=1
Apr 17 22:27:38 rif cifs.upcall: uid=1100
Apr 17 22:27:38 rif cifs.upcall: creduid=1100
Apr 17 22:27:38 rif cifs.upcall: user=root
Apr 17 22:27:38 rif cifs.upcall: pid=13700
Apr 17 22:27:38 rif cifs.upcall: get_cachename_from_process_env: pathname=/proc/13700/environ
Apr 17 22:27:38 rif cifs.upcall: get_existing_cc: default ccache is FILE:/tmp/krb5cc_1100
Apr 17 22:27:38 rif cifs.upcall: handle_krb5_mech: getting service ticket for grunt.variar.net
Apr 17 22:27:38 rif cifs.upcall: handle_krb5_mech: obtained service ticket
Apr 17 22:27:38 rif cifs.upcall: Exit status 0

The trick to getting it working was in the krb5.conf. I have to configure both kerberos and pam-krb5 to use the same file. My end config looks like the following:

[libdefaults]
default_realm = MYREALM.NET
forwardable = true
proxiable = true
default_ccache_name = FILE:/tmp/krb5cc_%{euid}

[realms]
MYREALM.NET = {
kdc = kdc.myrealm.net
admin_server = kdc.myrealm.net
}

[appdefaults]
pam = {
ccache = FILE:/tmp/krb5cc_%u
}

Critical to the above working is the creduid. This variable tells mount and cifs.upcall on whose behalf should the operation be made.

So, when i login via pam, or manually do kinit, my credential cache is always in the same place:

klist
Ticket cache: FILE:/tmp/krb5cc_1100
Default principal: mbarlow@SERVER

Valid starting     Expires            Service principal
17/04/17 22:46:32  18/04/17 22:46:32  krbtgt/MYREALM.NET@MYREALM.NET

My autofs mount looks like the following:

/etc/auto.master.d/auto.server:
/mnt/automount /etc/auto.servermaps

With the actual maps looking like:

/etc/auto.servermaps: photos -fstype=cifs,sec=krb5,cruid=$USER,uid=$USER ://server/share

Drop me a line using one of the contact methods