Re: Possible bug in NFSv4 with krb5p security?

From: Rick Macklem <rmacklem_at_uoguelph.ca>
Date: Fri, 15 Feb 2013 19:57:08 -0500 (EST)
Benjamin Kaduk wrote:
> On Sat, 16 Feb 2013, Elias MÃ¥rtenson wrote:
> 
> >
> > Thank you. I did exactly that and I found out some more.
> >
> > The problem occurss in file gss.c, in the
> > function gssd_pname_to_uid_1_svc(). This function is responsible for
> > taking
> > a principal and returning the Unix user ID that this principal
> > corresponds
> > to. I did confirm that this function is called with elias_at_REALM,
> > which is
> > the correct principal. It then calls the libgssapi function
> > gss_pname_to_uid() which does the actual lookup.
> >
> > The problem is that after the lookup (which succeeds by the way), it
> > returns user ID 0 (i.e. root, what!?). Of course, this uid later
> > gets
> > mapped to nobody, resulting in the behaviour that I see.
> >
> > I tried to add more debugging information in libgssapi.so.10, but if
> > I just
> > try to add some printf() statements, the entire thing hangs. I'm not
> > sure
> > how to proceed from there.
> >
> > Oh, and the libgssapi function gss_pname_to_uid() actually delegates
> > the
> > actual lookup to a function that depends on what security mechanism
> > is in
> > place. My printf()'s (that caused the hang) attempted to print what
> > mechanism was actually used.
> 
> Unless things are very messed up, it should be using the krb5
> mechanism,
> which I believe will boil down to krb5_aname_to_localname, per
> heimdal/lib/gssapi/krb5/pname_to_uid.c. I'm not sure how this would
> end
> up with success but uid 0, though.
> Do you have the default realm set in krb5.conf? Having it set to a
> different value than the realm of elias_at_REALM could result in strange
> behavior.
> 
> > And yet one more thing: Heimdal ships with its own version of
> > libgssapi. I
> > can link gssd to it, but it won't run properly (it hangs pretty
> > early).
> 
> I have forgotten: you are using Heimdal from ports, not from the base
> system? I remember it being easy to get into subtly-broken
> configurations
> when both a ports and a base version are present.
> 
> -Ben Kaduk
Well, here's the aname_to_localname function sources. After this, it just
calls getpwnam_r() to get the password database entry for the name.
I've put "***" in front of what I suspect is causing your problem.
I have no idea when there is a name_string.len == 2 with "root" as the
second string. Maybe Benjamin knows?

krb5_error_code KRB5_LIB_FUNCTION
krb5_aname_to_localname (krb5_context context,
			 krb5_const_principal aname,
			 size_t lnsize,
			 char *lname)
{
    krb5_error_code ret;
    krb5_realm *lrealms, *r;
    int valid;
    size_t len;
    const char *res;

    ret = krb5_get_default_realms (context, &lrealms);
    if (ret)
	return ret;

    valid = 0;
    for (r = lrealms; *r != NULL; ++r) {
	if (strcmp (*r, aname->realm) == 0) {
	    valid = 1;
	    break;
	}
    }
    krb5_free_host_realm (context, lrealms);
    if (valid == 0)
	return KRB5_NO_LOCALNAME;

    if (aname->name.name_string.len == 1)
	res = aname->name.name_string.val[0];
*** else if (aname->name.name_string.len == 2
	     && strcmp (aname->name.name_string.val[1], "root") == 0) {
	krb5_principal rootprinc;
	krb5_boolean userok;

	res = "root";

	ret = krb5_copy_principal(context, aname, &rootprinc);
	if (ret)
	    return ret;
	
	userok = krb5_kuserok(context, rootprinc, res);
	krb5_free_principal(context, rootprinc);
	if (!userok)
	    return KRB5_NO_LOCALNAME;

    } else
	return KRB5_NO_LOCALNAME;

    len = strlen (res);
    if (len >= lnsize)
	return ERANGE;
    strlcpy (lname, res, lnsize);

    return 0;
}

I've never seen Kerberos map to "root" like the above would for
name.name_string.len == 2, but I'm guessing that's how you get
uid == 0.

rick
Received on Fri Feb 15 2013 - 23:57:37 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:34 UTC