Skip Menu |
 

From: "Nebergall, Christopher" <cneberg@sandia.gov>
To: "'krb5-bugs@mit.edu'" <krb5-bugs@mit.edu>
Subject: auth_to_localnames drops realm before match
Date: Mon, 24 Nov 2003 10:48:12 -0700
Download (untitled) / with headers
text/plain 1.9KiB
The auth_to_local_names attribute only consults the default realm for
matching, no matter what realm that the user is authenticating from. This
may be alright by itself because that makes it consistent with auth_to_local
call. The problem is that the realm of the user is dropped before the
match. User1@anyrealm will always be treated the same as User1@defaultrealm
for the match.

Example from kerb 1.3.1

If I see roger@siteA.com <mailto:roger@siteA.com> or roger@siteB.com
<mailto:roger@siteB.com> they both get mapped into roger1
using the krb5.conf settings below.

default_realm = siteA.com
siteA.com = {
kdc = something
auth_to_local_names = {
roger = roger1
}

siteB.com = {
kdc = something
}

lib/krb5/os/an_to_ln.c

if (!(kret = krb5_get_default_realm(context, &realm))) {
/* Flatten the name */
if (!(kret = krb5_unparse_name(context, aname, &pname))) {
Show quoted text
>>> Realm is dropped if ((mname =
aname_full_to_mapping_name(pname))) {
/*
* Search first for explicit mappings of the form:
*
* [realms]->realm->"auth_to_local_names"->mapping_name
*/
hierarchy[0] = "realms";
Show quoted text
>>> Only the default realm is used. >>>>>>>> hierarchy[1] =
realm;
hierarchy[2] = "auth_to_local_names";
hierarchy[3] = mname;
hierarchy[4] = (char *) NULL;
if (!(kret = profile_get_values(context->profile,
hierarchy,
&mapping_values))) {
/* We found one or more explicit mappings. */
for (nvalid=0; mapping_values[nvalid]; nvalid++);

/* Just use the last one. */
/* Trim the value. */



-Christopher Nebergall
The attached patch (against the current 1.4 release) does what i think
the original requestor was after and which i'm also keen on doing:
it turns auth_to_local_names and auth_to_local into real per-realm
configs, specifying auth-to-local conversion based on the aname's
realm. In the absence of an auth_to_local config for a given realm
(besides the default realm), though, the prior behavior of using the
default realm's auth_to_local config is fallen back upon. No such
provision is made for auth_to_local_names, however, as that doesn't
seem to make much sense to me (and it complicates the patch and raises
configuration precedence issues, though somebody with more insight
may be able to work those out, in addition to filtering out the bugs
that the patch no doubt introduces)

--buck
Download an_to_ln.c.diff
text/x-patch 4.1KiB
--- an_to_ln.c.orig 2004-07-02 17:32:17.000000000 -0400
+++ an_to_ln.c 2005-03-18 17:26:12.000000000 -0500
@@ -614,8 +614,7 @@
#endif /* AN_TO_LN_RULES */

/*
- * Implementation: This version checks the realm to see if it is the local
- * realm; if so, and there is exactly one non-realm component to the name,
+ * Implementation: If there is exactly one non-realm component to the name,
* that name is returned as the lname.
*/
static krb5_error_code
@@ -630,11 +629,6 @@
if ((retval = krb5_get_default_realm(context, &def_realm))) {
return(retval);
}
- if (((size_t) realm_length != strlen(def_realm)) ||
- (memcmp(def_realm, krb5_princ_realm(context, aname)->data, realm_length))) {
- free(def_realm);
- return KRB5_LNAME_NOTRANS;
- }

if (krb5_princ_size(context, aname) != 1) {
if (krb5_princ_size(context, aname) == 2 ) {
@@ -687,6 +681,8 @@
char *cp, *s;
char *typep, *argp;
unsigned int lnsize;
+ const krb5_data *conven_prealm;
+ krb5_boolean defaulting_to_default_realm;

if (lnsize_in < 0)
return KRB5_CONFIG_NOTENUFSPACE;
@@ -694,9 +690,15 @@
lnsize = lnsize_in; /* Unsigned */

/*
- * First get the default realm.
+ * First get the *incoming* principal's realm
*/
- if (!(kret = krb5_get_default_realm(context, &realm))) {
+ conven_prealm = krb5_princ_realm(context, aname);
+ realm = malloc(conven_prealm->length + 1);
+ kret = ENOMEM;
+
+ if (realm) {
+ strncpy(realm, conven_prealm->data, conven_prealm->length);
+ realm[conven_prealm->length] = '\0';
/* Flatten the name */
if (!(kret = krb5_unparse_name(context, aname, &pname))) {
if ((mname = aname_full_to_mapping_name(pname))) {
@@ -743,6 +745,9 @@
*
* [realms]->realm->"auth_to_local"
*
+ * Check first for the realm of the incoming princ.
+ * In the absence of any config for it, try the default realm.
+ *
* This can have one or more of the following kinds of
* values:
* DB:<filename> - Look up principal in aname database.
@@ -750,13 +755,28 @@
* DEFAULT - Use default rule.
* The first rule to find a match is used.
*/
+ defaulting_to_default_realm = FALSE;
hierarchy[0] = "realms";
hierarchy[1] = realm;
hierarchy[2] = "auth_to_local";
hierarchy[3] = (char *) NULL;
- if (!(kret = profile_get_values(context->profile,
- hierarchy,
- &mapping_values))) {
+ kret = profile_get_values(context->profile,
+ hierarchy,
+ &mapping_values);
+ if (kret) {
+ kret = krb5_get_default_realm(context, &s);
+ if (!kret) {
+ if (!strcmp(s, realm)) {
+ defaulting_to_default_realm = TRUE;
+ hierarchy[1] = s;
+ kret = profile_get_values(context->profile,
+ hierarchy,
+ &mapping_values);
+ }
+ krb5_xfree(s);
+ }
+ }
+ if (!kret) {
/*
* Loop through all the mapping values.
*/
@@ -792,6 +812,11 @@
else
#endif /* AN_TO_LN_RULES */
if (!strcmp(typep, "DEFAULT") && !argp) {
+ /* only honor a DEFAULT mapping if we didn't
+ * land here b/c we have no auth_to_local
+ * info for the principal's crealm
+ */
+ if (!defaulting_to_default_realm) {
kret = default_an_to_ln(context,
aname,
lnsize,
@@ -799,6 +824,7 @@
if (kret != KRB5_LNAME_NOTRANS)
break;
}
+ }
else {
kret = KRB5_CONFIG_BADFORMAT;
break;
@@ -810,12 +836,19 @@
}
else {
/*
- * No profile relation found, try default mapping.
+ * No profile relation found, try default mapping,
+ * if principal is from local realm.
*/
- kret = default_an_to_ln(context,
- aname,
- lnsize,
- lname);
+ if (!(kret = krb5_get_default_realm(context, &s))) {
+ if (strlen(realm) == strlen(s) &&
+ !strcmp(realm, s)) {
+ kret = default_an_to_ln(context,
+ aname,
+ lnsize,
+ lname);
+ }
+ krb5_xfree(s);
+ }
}
}
free(mname);
@@ -824,8 +857,7 @@
kret = ENOMEM;
krb5_xfree(pname);
}
- krb5_xfree(realm);
+ free(realm);
}
return(kret);
}
-
fix at least one bug in this patch
--- krb5-1.4.2/src/lib/krb5/os/an_to_ln.c.realm-specific_an_to_ln 2004-07-02 17:32:17.000000000 -0400
+++ krb5-1.4.2/src/lib/krb5/os/an_to_ln.c 2005-09-28 09:34:42.042924673 -0400
@@ -614,8 +614,7 @@
#endif /* AN_TO_LN_RULES */

/*
- * Implementation: This version checks the realm to see if it is the local
- * realm; if so, and there is exactly one non-realm component to the name,
+ * Implementation: If there is exactly one non-realm component to the name,
* that name is returned as the lname.
*/
static krb5_error_code
@@ -630,11 +629,6 @@
if ((retval = krb5_get_default_realm(context, &def_realm))) {
return(retval);
}
- if (((size_t) realm_length != strlen(def_realm)) ||
- (memcmp(def_realm, krb5_princ_realm(context, aname)->data, realm_length))) {
- free(def_realm);
- return KRB5_LNAME_NOTRANS;
- }

if (krb5_princ_size(context, aname) != 1) {
if (krb5_princ_size(context, aname) == 2 ) {
@@ -687,6 +681,9 @@
char *cp, *s;
char *typep, *argp;
unsigned int lnsize;
+ const krb5_data *conven_prealm;
+ krb5_boolean defaulting_to_default_realm;
+

if (lnsize_in < 0)
return KRB5_CONFIG_NOTENUFSPACE;
@@ -694,9 +691,15 @@
lnsize = lnsize_in; /* Unsigned */

/*
- * First get the default realm.
+ * First get the *incoming* principal's realm
*/
- if (!(kret = krb5_get_default_realm(context, &realm))) {
+ conven_prealm = krb5_princ_realm(context, aname);
+ realm = malloc(conven_prealm->length + 1);
+ kret = ENOMEM;
+
+ if (realm) {
+ strncpy(realm, conven_prealm->data, conven_prealm->length);
+ realm[conven_prealm->length] = '\0';
/* Flatten the name */
if (!(kret = krb5_unparse_name(context, aname, &pname))) {
if ((mname = aname_full_to_mapping_name(pname))) {
@@ -743,6 +746,9 @@
*
* [realms]->realm->"auth_to_local"
*
+ * Check first for the realm of the incoming princ.
+ * In the absence of any config for it, try the default realm.
+ *
* This can have one or more of the following kinds of
* values:
* DB:<filename> - Look up principal in aname database.
@@ -750,13 +756,26 @@
* DEFAULT - Use default rule.
* The first rule to find a match is used.
*/
+ defaulting_to_default_realm = FALSE;
hierarchy[0] = "realms";
hierarchy[1] = realm;
hierarchy[2] = "auth_to_local";
hierarchy[3] = (char *) NULL;
- if (!(kret = profile_get_values(context->profile,
- hierarchy,
- &mapping_values))) {
+ kret = profile_get_values(context->profile,
+ hierarchy,
+ &mapping_values);
+ if (kret) {
+ kret = krb5_get_default_realm(context, &s);
+ if (!kret) {
+ defaulting_to_default_realm = TRUE;
+ hierarchy[1] = s;
+ kret = profile_get_values(context->profile,
+ hierarchy,
+ &mapping_values);
+ krb5_xfree(s);
+ }
+ }
+ if (!kret) {
/*
* Loop through all the mapping values.
*/
@@ -792,6 +811,12 @@
else
#endif /* AN_TO_LN_RULES */
if (!strcmp(typep, "DEFAULT") && !argp) {
+ /* only honor a DEFAULT mapping if we didn't
+ * land here b/c we have no auth_to_local
+ * info for the principal's crealm
+ */
+ kret = KRB5_LNAME_NOTRANS;
+ if (!defaulting_to_default_realm) {
kret = default_an_to_ln(context,
aname,
lnsize,
@@ -799,6 +824,7 @@
if (kret != KRB5_LNAME_NOTRANS)
break;
}
+ }
else {
kret = KRB5_CONFIG_BADFORMAT;
break;
@@ -810,12 +836,20 @@
}
else {
/*
- * No profile relation found, try default mapping.
+ * No profile relation found, try default mapping,
+ * if principal is from local realm.
*/
- kret = default_an_to_ln(context,
- aname,
- lnsize,
- lname);
+ kret = KRB5_LNAME_NOTRANS;
+ if (!(kret = krb5_get_default_realm(context, &s))) {
+ if (strlen(realm) == strlen(s) &&
+ !strcmp(realm, s)) {
+ kret = default_an_to_ln(context,
+ aname,
+ lnsize,
+ lname);
+ }
+ krb5_xfree(s);
+ }
}
}
free(mname);
@@ -824,7 +858,7 @@
kret = ENOMEM;
krb5_xfree(pname);
}
- krb5_xfree(realm);
+ free(realm);
}
return(kret);
}