Ticket #276 (new defect)

Opened 12 years ago

Last modified 10 years ago

Shouldn’t accept Kerberos passwords for local users without username@ATHENA.MIT.EDU in .k5login

Reported by: andersk Owned by:
Priority: normal Milestone: The Distant Future
Component: -- Keywords:
Cc: Fixed in version:
Upstream bug:

Description

   debathena / pam / andersk  17:07  (Anders Kaseorg)
       I’d be tempted to set minimum_uid=500.  Though what I’d actually like
       to require is (group nss_nonlocal_users || principal in .k5login).
   debathena / pam / broder  17:10  (Evan Broder)
       Principal in .k5login doesn't matter, because PAM doesn't deal with that
   debathena / pam / andersk  17:11  (Anders Kaseorg)
       > PAM doesn't deal with that
   
       But I want it to.  If username@ATHENA.MIT.EDU is not in username’s
       ~/.k5login, then I don’t want that Kerberos password to be useful for
       logging into that local account.

Change History

comment:1 Changed 12 years ago by jdreed

  • Milestone set to The Distant Future

If I'm reading this correctly, users who install -login or higher will have to take an extra step to log in using their Kerberos passwords? That seems guaranteed to cause a lot of confusion for minimal benefit.

Also, isn't this a change from the stock upstream behavior? If it's important from a security perspective, I'd rather lobby to get it changed upstream. Certainly the current behavior (accepting both Kerberos and local passwords) is the default behavior in RHEL and (I believe) OS X.

Regardless, I really really do not want to implement this during the upcoming academic year (modulo it appearing in stock Karmic). There's going to be enough headache getting people to migrate their private workstations from Athena 9 to Debathena that I'd like to not introduce confusing new behavior such as this on top of everything else.

comment:2 Changed 12 years ago by andersk

The upstream libpam-krb5 “solution” to this problem is the minimum_uid option, and the Debian package by default sets minimum_uid=1000 as recommended by the upstream documentation. But we can’t do that on Athena without locking out users with low UIDs. We currently set minimum_uid=1, which means that anyone may be able to compromise a local system account on a debathena-login machine (other than root) if they can obtain an ATHENA.MIT.EDU Kerberos principal of the same name.

This represents a hole in the security property that I attempted to establish with nss_nonlocal: nonlocal users of a debathena-login machine should never be able to obtain local credentials, unless explicitly authorized locally.

I’m not sure whether upstream currently recognizes this as an important property, so including them in this discussion would probably be productive.

comment:3 Changed 12 years ago by andersk

If I'm reading this correctly, users who install -login or higher will have to take an extra step to log in using their Kerberos passwords?

BTW, no, I don’t want to change the normal case of logging into a nonlocal account on a debathena-login system. Only if you create a local account should a .k5login be required.

comment:4 Changed 11 years ago by adehnert

Based on discussion on -c debathena -i zhm tonight (principally with kcr and andersk), it looks like the auth_to_local krb5.conf option may be useful. In particular, completely disabling the default missing k5login behavior seems to be doable with "auth_to_local = { }" in the ATHENA.MIT.EDU section of [realms]. More useful configuration is also likely doable. It's not clear what documentation is available, unfortunately.

However,  http://mailman.mit.edu/pipermail/krbdev/2002-July/000486.html does suggest that it's possible to do database lookups. Installing such a database to disable the default k5login behavior would probably be reasonable (possibly generated at package build, or possibly something more elaborate like a cron job or a FUSE filesystem). I could also believe that it'd be possible to patch Kerberos to do something nicer (only map for people in nss_nonlocal_users?).

comment:5 Changed 11 years ago by kcr

The source code is the best documentation that I've found:
kerberos_source_tree/src/lib/krb5/os/an_to_ln.c

comment:6 Changed 11 years ago by jdreed

As previously noted, we need to think hard about how and when we make any change here. We will be deviating away from stock upstream behavior, which we've generally tried to avoid doing. We will also be introducing a fairly large behavior change: No matter how trivial it is to create a .k5login, some users will almost certainly find themselves unable to login after we make this change.

So if and when we make this change, it needs to be phased in slowly over the course of at least a semester. It should not be a sudden change, and should not (unless there's a really really good reason) coincide with a distro upgrade.

comment:7 Changed 11 years ago by ghudson

This is all handled by krb5_kuserok(), which has the following logic:

  • If $HOME/.k5login exists, check if the string form of the principal (with realm) is listed.
  • Otherwise, call krb5_aname_to_localname() on the principal and see if the result matches the local username.

krb5_aname_to_localname() has the following logic:

  • If krb5.conf has any associations {realms, defaultrealm, auth_to_local_names, princname}, use the last one as the local username. princname is the string form of the principal without realm.
  • If krb5.conf has any associations {realms, defaultrealm, auth_to_local}, treat them as rules as follows:
    • RULE:rule: See below.
    • DB:filename: Disabled in default build.
    • DEFAULT: Apply default rule.
  • If neither kind of association is found, apply the default rule.

The default rule is: reject the principal if its realm doesn't match the default realm, or it doesn't have one or two components, or it has two components and the second component doesn't match the default realm. If the principal is not rejected, return its first component.

Rules have three parts, all optional:

  • A formulation part in brackets: [ncomps:format]. If this part does not exist, the string form of the principal without realm is used. If this part does exist, ncomps must match the number of components of the principal, and format is used as the formulation. Inside format, $0 is substituted with the principal's realm, $1 with the first component of the principal, $2 with the second, etc.
  • A match part in parentheses: (regexp). If this part exists, the formulated string must match the regexp.
  • One or more sed expressions: s/regexp/result/ or s/regexp/result/g. The formulated string is substituted according to the sed expression, or left alone if regexp doesn't match it.

It's important to note when the logic operates on the string form of principals without their realms (auth_to_local_names and the default formulation for rules). In a cross-realm environment like ours, it is not safe to use those operations in order to grant positive access to a local account. Obviously, those parts of the logic are a botch; this stuff all dates back to like 1995.

It is possible to completely disable aname-to-lname translation with something like (in the ATHENA.MIT.EDU realm definition):

auth_to_local = RULE:[0:]

But as Jon notes, that would be disruptive. auth_to_local = { } will also work, sort of, but only in that it generates a profile syntax error inside krb5_aname_to_localname which then gives up.

On Zephyr, Anders suggested using auth_to_local_names to negatively map local users to "nobody". If "nobody" is not allowed to log in, that should be safe, in that mapping daemon@FOREIGN_REALM to a disabled account is harmless. You could map more precisely with something like:

auth_to_local = RULE:[1:$1@$0](daemon@ATHENA.MIT.EDU)s/.*/nobody/
auth_to_local = RULE:[1:$1@$0](root@ATHENA.MIT.EDU)s/.*/nobody/
auth_to_local = DEFAULT

comment:8 Changed 11 years ago by jdreed

So, is the idea that a PAM module (whether stock upstream, or a Debathena-specific one) would call krb5_kuserok()? Because if so, it would be great if it could (during the deprecation period) inform the user why it failed and what steps the sysadmin should take to restore access. (Yes, I'm aware that giving the user any information about a failure is considered bad security practice, but this would be during the deprecation period only, not indefinitely.) Of course, GDM seems to have given up on the idea of displaying PAM messages to the user, so this may not be that useful...

comment:9 Changed 10 years ago by andersk

I wrote  a FUSE filesystem that implements comment:7 as a proof-of-concept. To try it,

mkdir /var/lib/debathena-krb5fs
touch /var/lib/debathena-krb5fs/realms.conf
/mit/andersk/Public/debathena/krb5fs /var/lib/debathena-krb5fs

and put this line in /etc/krb5.conf above the [realms] section:

include /var/lib/debathena-krb5fs/realms.conf
Note: See TracTickets for help on using tickets.