← Back to team overview

touch-packages team mailing list archive

[Bug 1484262] [NEW] Heimdal krb5_kuserok fails if user's home directory protected

 

Public bug reported:

I've encountered this problem with Ubuntu 12.04.5 LTS Release: 12.04 and
libkrb5-heimdal 1.6~git20120311.dfsg.1-2ubuntu0.1.  It wouldn't surprise
me were the problem wider in scope.

Assume a valid Heimdal Kerberos setup, with:

Packages heimdal-clients and libpam-heimdal installed (which also brings in sundry libraries as dependencies);
/etc/krb5.conf properly set up, in particular the default realm under [libdefaults], DNS-domain-to-realm mappings under [domain_realm], and the KDC under [realms];
pam_krb5 configured in /etc/pam.d/common-auth (as should happen automatically when libpam-heimdal is installed);
a proper host principal for the client host, with its key installed in /etc/krb5.keytab;

and a local user with:

a proper entry in /etc/passwd and /etc/shadow;
a proper corresponding principal user@REALM in the KDC;
a home directory accessed over NFS, with root_squash in effect.

If the user's home directory has permissions 755, Kerberos login works
just fine; in particular klist displays a TGT.

If the user's home directory has permissions 700, Kerberos login fails.
A message containing `pam_krb5(login:auth): failed authorization check'
is written to syslog/auth.  No session ticket cache is set up.

Workaround: give pam_krb5 the ignore_k5login parameter, either in
[appdefaults] in /etc/krb5.conf or whereever it appears in the several
files in /etc/pam.d.

I've dug around in the source, and I believe the trouble to be not in the PAM module but in the Heimdal implementation of library function krb5_kuserok.  In particular, in function kuserok_user_k5login_plug_f in file lib/krb5/kuserok.c in source package heimdal-1.6~git20120311 (fetched by apt-get source libkrb5-26-heimdal).
That function:

a.  Calls check_one_file to try to read $HOME/.k5login. If the function
returns zero, the file was opened and read (and a value returned through
a pointer tells whether the current principal was found); if nonzero,
the value is an errno code.  kuserok_user_k5login_plug_f believes that
if errno was ENOENT, the file didn't exist and all is well; otherwise it
acts as if it found an empty file, which means the principal wasn't
listed there, which means krb5_kuserok will return failure.

b.  Calls check_directory to scan directory $HOME/.k5login.d.  Again, it
returns zero if the directory was found and opened; a nonzero errno
value if not.  kuserok_user_k5login_plug_f declares that all is well if
the error value is ENOENT or ENOTDIR; otherwise it again causes
krb5_kuserok to fail.

The trouble is that when logging in, this code is executed as the super-
user; hence, if the user's home directory forbids access to anyone but
the owner and NFS root_squash blocks the super-user's extra permissions,
check_one_file and check_directory will return EACCES, and krb5_kuserok
will return failure as if .k5login existed but didn't list the current
principal, and authentication will be denied.

One could quibble over what to do if the file might exist but cannot be
opened.  (We don't know it exists because it is the directory's
permissions that block access.)  I've checked the MIT Kerberos source;
in their rather-different krb5_kuserok implementation, any open failure
for .k5login or .k5login.d allows access.  That means maybe it's OK for
Heimdal to do the same.  On the other hand, one could argue (probably
whoever wrote the code would) that it's safer to deny access if you
can't tell whether the file is even there.

I would argue that one of two things should happen:
1.  The checks for ret == ENOENT should be changed either to ret != 0 (to match the MIT behaviour) or (ret == ENOENT || ret == EACCES) (so the permission-denied case allows access, but less-ordinary errors like EIO don't).
2.  It should be documented, perhaps in the Heimdal version of pam_krb5(5), that there will be unexpected failures if the super-user is denied read permission to users' home directories, and if your system is set up that way you should use ignore_k5login.

We'll probably just use ignore_k5login since for other reasons that
seems the right answer for our site, but it may be a bigger problem for
others.

** Affects: heimdal (Ubuntu)
     Importance: Undecided
         Status: New


** Tags: heimdal kerberos krb5

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to heimdal in Ubuntu.
https://bugs.launchpad.net/bugs/1484262

Title:
  Heimdal krb5_kuserok fails if user's home directory protected

Status in heimdal package in Ubuntu:
  New

Bug description:
  I've encountered this problem with Ubuntu 12.04.5 LTS Release: 12.04
  and libkrb5-heimdal 1.6~git20120311.dfsg.1-2ubuntu0.1.  It wouldn't
  surprise me were the problem wider in scope.

  Assume a valid Heimdal Kerberos setup, with:

  Packages heimdal-clients and libpam-heimdal installed (which also brings in sundry libraries as dependencies);
  /etc/krb5.conf properly set up, in particular the default realm under [libdefaults], DNS-domain-to-realm mappings under [domain_realm], and the KDC under [realms];
  pam_krb5 configured in /etc/pam.d/common-auth (as should happen automatically when libpam-heimdal is installed);
  a proper host principal for the client host, with its key installed in /etc/krb5.keytab;

  and a local user with:

  a proper entry in /etc/passwd and /etc/shadow;
  a proper corresponding principal user@REALM in the KDC;
  a home directory accessed over NFS, with root_squash in effect.

  If the user's home directory has permissions 755, Kerberos login works
  just fine; in particular klist displays a TGT.

  If the user's home directory has permissions 700, Kerberos login
  fails.  A message containing `pam_krb5(login:auth): failed
  authorization check' is written to syslog/auth.  No session ticket
  cache is set up.

  Workaround: give pam_krb5 the ignore_k5login parameter, either in
  [appdefaults] in /etc/krb5.conf or whereever it appears in the several
  files in /etc/pam.d.

  I've dug around in the source, and I believe the trouble to be not in the PAM module but in the Heimdal implementation of library function krb5_kuserok.  In particular, in function kuserok_user_k5login_plug_f in file lib/krb5/kuserok.c in source package heimdal-1.6~git20120311 (fetched by apt-get source libkrb5-26-heimdal).
  That function:

  a.  Calls check_one_file to try to read $HOME/.k5login. If the
  function returns zero, the file was opened and read (and a value
  returned through a pointer tells whether the current principal was
  found); if nonzero, the value is an errno code.
  kuserok_user_k5login_plug_f believes that if errno was ENOENT, the
  file didn't exist and all is well; otherwise it acts as if it found an
  empty file, which means the principal wasn't listed there, which means
  krb5_kuserok will return failure.

  b.  Calls check_directory to scan directory $HOME/.k5login.d.  Again,
  it returns zero if the directory was found and opened; a nonzero errno
  value if not.  kuserok_user_k5login_plug_f declares that all is well
  if the error value is ENOENT or ENOTDIR; otherwise it again causes
  krb5_kuserok to fail.

  The trouble is that when logging in, this code is executed as the
  super-user; hence, if the user's home directory forbids access to
  anyone but the owner and NFS root_squash blocks the super-user's extra
  permissions, check_one_file and check_directory will return EACCES,
  and krb5_kuserok will return failure as if .k5login existed but didn't
  list the current principal, and authentication will be denied.

  One could quibble over what to do if the file might exist but cannot
  be opened.  (We don't know it exists because it is the directory's
  permissions that block access.)  I've checked the MIT Kerberos source;
  in their rather-different krb5_kuserok implementation, any open
  failure for .k5login or .k5login.d allows access.  That means maybe
  it's OK for Heimdal to do the same.  On the other hand, one could
  argue (probably whoever wrote the code would) that it's safer to deny
  access if you can't tell whether the file is even there.

  I would argue that one of two things should happen:
  1.  The checks for ret == ENOENT should be changed either to ret != 0 (to match the MIT behaviour) or (ret == ENOENT || ret == EACCES) (so the permission-denied case allows access, but less-ordinary errors like EIO don't).
  2.  It should be documented, perhaps in the Heimdal version of pam_krb5(5), that there will be unexpected failures if the super-user is denied read permission to users' home directories, and if your system is set up that way you should use ignore_k5login.

  We'll probably just use ignore_k5login since for other reasons that
  seems the right answer for our site, but it may be a bigger problem
  for others.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/heimdal/+bug/1484262/+subscriptions