diff options
author | Luke Howard <lukeh@padl.com> | 2011-03-17 12:44:43 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2011-03-17 12:44:43 +0000 |
commit | 5cf261cf481d297a17cdf7ca59561dbd0c3f76ee (patch) | |
tree | 05703fbffac81da59df3ecfa25c05e76a319f618 /src/lib/gssapi | |
parent | 7f0522e1d37f561dcb1b7df695550ee1ebec5d90 (diff) | |
download | krb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.zip krb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.tar.gz krb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.tar.bz2 |
implement attribute-based userok authorisation logic as suggested
by Sam Hartman
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/moonshot-mechglue-fixes@24717 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r-- | src/lib/gssapi/mechglue/g_userok.c | 145 |
1 files changed, 121 insertions, 24 deletions
diff --git a/src/lib/gssapi/mechglue/g_userok.c b/src/lib/gssapi/mechglue/g_userok.c index 1fbca2d..2544b72 100644 --- a/src/lib/gssapi/mechglue/g_userok.c +++ b/src/lib/gssapi/mechglue/g_userok.c @@ -1,4 +1,27 @@ /* + * Copyright (C) 2011 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ +/* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -12,14 +35,92 @@ #include <mglueP.h> #include <gssapi/gssapi.h> +static const char localLoginUserAttr[] = "local-login-user"; static OM_uint32 -compare_names(OM_uint32 *minor, - const gss_OID mech_type, +mech_userok(OM_uint32 *minor, + const gss_union_name_t unionName, + const char *user, + int *user_ok) +{ + OM_uint32 major = GSS_S_UNAVAILABLE; + gss_mechanism mech; + + /* may need to import the name if this is not MN */ + if (unionName->mech_type == GSS_C_NO_OID) + return (GSS_S_FAILURE); + + mech = gssint_get_mechanism(unionName->mech_type); + if (mech == NULL) + return (GSS_S_UNAVAILABLE); + + if (mech->gss_userok) { + major = mech->gss_userok(minor, unionName->mech_name, user, user_ok); + if (major != GSS_S_COMPLETE) + map_error(minor, mech); + } + + return (major); +} + +/* + * Naming extensions based local login authorization. + */ +static OM_uint32 +attr_userok(OM_uint32 *minor, const gss_name_t name, const char *user, int *user_ok) { + OM_uint32 major = GSS_S_UNAVAILABLE; + OM_uint32 tmpMinor; + size_t userLen = strlen(user); + int more = -1; + gss_buffer_desc attribute; + + *user_ok = 0; + + attribute.length = sizeof(localLoginUserAttr) - 1; + attribute.value = (void *)localLoginUserAttr; + + while (more != 0 && *user_ok == 0) { + gss_buffer_desc value; + gss_buffer_desc display_value; + int authenticated = 0, complete = 0; + + major = gss_get_name_attribute(minor, + name, + &attribute, + &authenticated, + &complete, + &value, + &display_value, + &more); + if (GSS_ERROR(major)) + break; + + if (authenticated && complete && + value.length == userLen && + memcmp(value.value, user, userLen) == 0) + *user_ok = 1; + + gss_release_buffer(&tmpMinor, &value); + gss_release_buffer(&tmpMinor, &display_value); + } + + return (major); +} + +/* + * Equality based local login authorization. + */ +static OM_uint32 +compare_names_userok(OM_uint32 *minor, + const gss_OID mech_type, + const gss_name_t name, + const char *user, + int *user_ok) +{ OM_uint32 status, tmpMinor; gss_name_t imported_name; @@ -30,7 +131,9 @@ compare_names(OM_uint32 *minor, *user_ok = 0; gss_user.value = (void *)user; - if (!gss_user.value || !name || !mech_type) + if (gss_user.value == NULL || + name == GSS_C_NO_NAME || + mech_type == GSS_C_NO_OID) return (GSS_S_BAD_NAME); gss_user.length = strlen(gss_user.value); @@ -74,10 +177,8 @@ gss_userok(OM_uint32 *minor, int *user_ok) { - gss_mechanism mech; - gss_union_name_t intName; - gss_name_t mechName = NULL; OM_uint32 major; + gss_union_name_t unionName; if (minor == NULL || user_ok == NULL) return (GSS_S_CALL_INACCESSIBLE_WRITE); @@ -86,28 +187,24 @@ gss_userok(OM_uint32 *minor, return (GSS_S_CALL_INACCESSIBLE_READ); *user_ok = 0; - *minor = GSS_S_COMPLETE; + *minor = 0; - intName = (gss_union_name_t)name; + unionName = (gss_union_name_t)name; - /* may need to import the name if this is not MN */ - if (intName->mech_type == GSS_C_NO_OID) - return (GSS_S_FAILURE); - else - mechName = intName->mech_name; + /* If mech returns yes, we return yes */ + major = mech_userok(minor, unionName, user, user_ok); + if (major == GSS_S_COMPLETE && *user_ok) + return (GSS_S_COMPLETE); - mech = gssint_get_mechanism(intName->mech_type); - if (mech == NULL) - return (GSS_S_UNAVAILABLE); + /* If attribute exists, we evaluate attribute */ + if (attr_userok(minor, name, user, user_ok) == GSS_S_COMPLETE) + return (GSS_S_COMPLETE); - if (mech->gss_userok) { - major = mech->gss_userok(minor, mechName, - user, user_ok); - if (major != GSS_S_COMPLETE) - map_error(minor, mech); - } else - major = compare_names(minor, intName->mech_type, - name, user, user_ok); + /* If mech returns unavail, we compare the local name */ + if (major == GSS_S_UNAVAILABLE) { + major = compare_names_userok(minor, unionName->mech_type, + name, user, user_ok); + } return (major); } /* gss_userok */ |