From 6c6e483e0038a77a850da8899e82afeb2a2b480d Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 8 Apr 2011 10:58:57 +1000 Subject: [PATCH] gss_authorize_localname implementation --- lib/gssapi/Makefile.am | 4 +- lib/gssapi/gssapi/gssapi.h | 15 ++- lib/gssapi/gssapi_mech.h | 8 +- .../krb5/{userok.c => authorize_localname.c} | 22 ++- lib/gssapi/krb5/external.c | 2 +- ...gss_userok.c => gss_authorize_localname.c} | 126 +++++++++--------- lib/gssapi/mech/gss_mech_switch.c | 2 +- lib/gssapi/mech/gss_pname_to_uid.c | 6 +- lib/gssapi/version-script.map | 3 +- 9 files changed, 103 insertions(+), 85 deletions(-) rename lib/gssapi/krb5/{userok.c => authorize_localname.c} (77%) rename lib/gssapi/mech/{gss_userok.c => gss_authorize_localname.c} (57%) diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index 10d9a9bd9..1b5fd5515 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -71,7 +71,7 @@ krb5src = \ krb5/set_sec_context_option.c \ krb5/ticket_flags.c \ krb5/unwrap.c \ - krb5/userok.c \ + krb5/authorize_localname.c \ krb5/verify_mic.c \ krb5/wrap.c @@ -142,7 +142,7 @@ mechsrc = \ mech/gss_test_oid_set_member.c \ mech/gss_unseal.c \ mech/gss_unwrap.c \ - mech/gss_userok.c \ + mech/gss_authorize_localname.c \ mech/gss_utils.c \ mech/gss_verify.c \ mech/gss_verify_mic.c \ diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index c74ff86c9..9b7608953 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -1033,10 +1033,17 @@ gss_pname_to_uid( uid_t *uidOut); GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL -gss_userok(OM_uint32 *minor, - const gss_name_t name, - const char *user, - int *user_ok); +gss_authorize_localname( + OM_uint32 *minor, + const gss_name_t name, + const gss_name_t user, + int *authorized); + +GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL +gss_userok(const gss_name_t name, + const char *user); + +extern GSSAPI_LIB_VARIABLE gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER; /* * Naming extensions diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index 43d737ef9..96171739f 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -495,11 +495,11 @@ typedef OM_uint32 GSSAPI_CALLCONV _gss_pname_to_uid_t ( uid_t * /* uidOut */ ); -typedef OM_uint32 GSSAPI_CALLCONV _gss_userok_t ( +typedef OM_uint32 GSSAPI_CALLCONV _gss_authorize_localname_t ( OM_uint32 *, /* minor_status */ const gss_name_t, /* name */ - const char *, /* user */ - int * /*user_ok */ + gss_const_buffer_t, /* user */ + int * /* user_ok */ ); /* mechglue internal */ @@ -565,7 +565,7 @@ typedef struct gssapi_mech_interface_desc { gss_mo_desc *gm_mo; size_t gm_mo_num; _gss_pname_to_uid_t *gm_pname_to_uid; - _gss_userok_t *gm_userok; + _gss_authorize_localname_t *gm_authorize_localname; _gss_display_name_ext_t *gm_display_name_ext; _gss_inquire_name_t *gm_inquire_name; _gss_get_name_attribute_t *gm_get_name_attribute; diff --git a/lib/gssapi/krb5/userok.c b/lib/gssapi/krb5/authorize_localname.c similarity index 77% rename from lib/gssapi/krb5/userok.c rename to lib/gssapi/krb5/authorize_localname.c index af53ea735..49688d5a8 100644 --- a/lib/gssapi/krb5/userok.c +++ b/lib/gssapi/krb5/authorize_localname.c @@ -33,18 +33,30 @@ #include "gsskrb5_locl.h" OM_uint32 -_gsskrb5_userok(OM_uint32 *minor_status, - const gss_name_t input_name, - const char *user, - int *user_ok) +_gsskrb5_authorize_localname(OM_uint32 *minor_status, + const gss_name_t input_name, + gss_const_buffer_t user_name, + int *user_ok) { krb5_context context; - krb5_const_principal princ = (krb5_const_principal)input_name; + krb5_principal princ = (krb5_principal)input_name; + char *user; GSSAPI_KRB5_INIT(&context); + user = malloc(user_name->length + 1); + if (user == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(user, user_name->value, user_name->length); + user[user_name->length] = '\0'; + *minor_status = 0; *user_ok = krb5_kuserok(context, princ, user); + free(user); + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index 59d5bba7b..dbbd8edb0 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -325,7 +325,7 @@ static gssapi_mech_interface_desc krb5_mech = { krb5_mo, sizeof(krb5_mo) / sizeof(krb5_mo[0]), NULL, - _gsskrb5_userok, + _gsskrb5_authorize_localname, _gsskrb5_pname_to_uid }; diff --git a/lib/gssapi/mech/gss_userok.c b/lib/gssapi/mech/gss_authorize_localname.c similarity index 57% rename from lib/gssapi/mech/gss_userok.c rename to lib/gssapi/mech/gss_authorize_localname.c index be6d8d73e..4b973dcde 100644 --- a/lib/gssapi/mech/gss_userok.c +++ b/lib/gssapi/mech/gss_authorize_localname.c @@ -32,13 +32,18 @@ #include "mech_locl.h" -static const char localLoginUserAttr[] = "local-login-user"; +static gss_buffer_desc localLoginUserAttr = { + sizeof("local-login-user"), + "local-login-user" +}; + +gss_buffer_t GSSAPI_LIB_VARIABLE GSS_C_ATTR_LOCAL_LOGIN_USER = &localLoginUserAttr; static OM_uint32 -mech_userok(OM_uint32 *minor_status, - gss_name_t input_name, - const char *user, - int *user_ok) +mech_authorize_localname(OM_uint32 *minor_status, + const gss_name_t input_name, + const struct _gss_name *user, + int *user_ok) { const struct _gss_name *name = (const struct _gss_name *)input_name; OM_uint32 major_status = GSS_S_UNAVAILABLE; @@ -49,13 +54,13 @@ mech_userok(OM_uint32 *minor_status, HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { gssapi_mech_interface m = mn->gmn_mech; - if (!m->gm_userok) + if (!m->gm_authorize_localname) continue; - major_status = m->gm_userok(minor_status, - mn->gmn_name, - user, - user_ok); + major_status = m->gm_authorize_localname(minor_status, + mn->gmn_name, + &user->gn_value, + user_ok); if (GSS_ERROR(major_status) || *user_ok) break; } @@ -67,22 +72,17 @@ mech_userok(OM_uint32 *minor_status, * Naming extensions based local login authorization. */ static OM_uint32 -attr_userok(OM_uint32 *minor_status, - const gss_name_t name, - const char *user, - int *user_ok) +attr_authorize_localname(OM_uint32 *minor_status, + const gss_name_t name, + const struct _gss_name *user, + int *user_ok) { OM_uint32 major_status = 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; @@ -90,7 +90,7 @@ attr_userok(OM_uint32 *minor_status, major_status = gss_get_name_attribute(minor_status, name, - &attribute, + GSS_C_ATTR_LOCAL_LOGIN_USER, &authenticated, &complete, &value, @@ -100,8 +100,8 @@ attr_userok(OM_uint32 *minor_status, break; if (authenticated && - value.length == userLen && - memcmp(value.value, user, userLen) == 0) + value.length == user->gn_value.length && + memcmp(value.value, user->gn_value.value, user->gn_value.length) == 0) *user_ok = 1; gss_release_buffer(&tmpMinor, &value); @@ -111,63 +111,65 @@ attr_userok(OM_uint32 *minor_status, return major_status; } -/* - * Equality based local login authorization. - */ -static OM_uint32 -compare_names_userok(OM_uint32 *minor_status, - const gss_name_t name, - const char *user, - int *user_ok) -{ - OM_uint32 major_status = GSS_S_UNAVAILABLE; - OM_uint32 tmpMinor; - gss_buffer_desc gssUser; - gss_name_t gssUserName = GSS_C_NO_NAME; - - *user_ok = 0; - - gssUser.length = strlen(user); - gssUser.value = (void *)user; - - major_status = gss_import_name(minor_status, &gssUser, - GSS_C_NT_USER_NAME, &gssUserName); - if (GSS_ERROR(major_status)) - return major_status; - - major_status = gss_compare_name(minor_status, name, - gssUserName, user_ok); - - gss_release_name(&tmpMinor, &gssUserName); - - return major_status; -} - OM_uint32 -gss_userok(OM_uint32 *minor_status, - const gss_name_t name, - const char *user, - int *user_ok) +gss_authorize_localname(OM_uint32 *minor_status, + const gss_name_t name, + const gss_name_t user_name, + int *user_ok) { OM_uint32 major_status; + const struct _gss_name *user = (const struct _gss_name *) user_name; *minor_status = 0; *user_ok = 0; + if (name == GSS_C_NO_NAME || user_name == GSS_C_NO_NAME) + return GSS_S_CALL_INACCESSIBLE_READ; + + /* name must not be a MN */ + if (HEIM_SLIST_FIRST(&user->gn_mn) != NULL) + return GSS_S_BAD_NAME; + /* If mech returns yes, we return yes */ - major_status = mech_userok(minor_status, name, user, user_ok); + major_status = mech_authorize_localname(minor_status, + name, user, user_ok); if (major_status == GSS_S_COMPLETE && *user_ok) return GSS_S_COMPLETE; /* If attribute exists, we evaluate attribute */ - if (attr_userok(minor_status, name, user, user_ok) == GSS_S_COMPLETE) + if (attr_authorize_localname(minor_status, + name, user, user_ok) == GSS_S_COMPLETE) return GSS_S_COMPLETE; /* If mech returns unavail, we compare the local name */ if (major_status == GSS_S_UNAVAILABLE) - major_status = compare_names_userok(minor_status, name, - user, user_ok); + major_status = gss_compare_name(minor_status, name, user_name, user_ok); return major_status; } + +int +gss_userok(const gss_name_t name, + const char *user) +{ + OM_uint32 major_status, minor_status; + gss_buffer_desc userBuf; + gss_name_t userName; + int user_ok = 0; + + userBuf.value = (void *)user; + userBuf.length = strlen(user); + + major_status = gss_import_name(&minor_status, &userBuf, GSS_C_NO_OID, &userName); + if (GSS_ERROR(major_status)) + return 0; + + major_status = gss_authorize_localname(&minor_status, name, userName, &user_ok); + if (GSS_ERROR(major_status)) + user_ok = 0; + + gss_release_name(&minor_status, &userName); + + return user_ok; +} diff --git a/lib/gssapi/mech/gss_mech_switch.c b/lib/gssapi/mech/gss_mech_switch.c index d272958c3..efded1e38 100644 --- a/lib/gssapi/mech/gss_mech_switch.c +++ b/lib/gssapi/mech/gss_mech_switch.c @@ -360,7 +360,7 @@ _gss_load_mech(void) OPTSPISYM(acquire_cred_with_password); OPTSYM(add_cred_with_password); OPTSYM(pname_to_uid); - OPTSYM(userok); + OPTSPISYM(authorize_localname); mi = dlsym(so, "gss_mo_init"); if (mi != NULL) { diff --git a/lib/gssapi/mech/gss_pname_to_uid.c b/lib/gssapi/mech/gss_pname_to_uid.c index 437241c44..659cf6a82 100644 --- a/lib/gssapi/mech/gss_pname_to_uid.c +++ b/lib/gssapi/mech/gss_pname_to_uid.c @@ -62,16 +62,12 @@ attr_pname_to_uid(OM_uint32 *minor_status, OM_uint32 major_status = GSS_S_UNAVAILABLE; OM_uint32 tmpMinor; int more = -1; - gss_buffer_desc attribute; *minor_status = 0; if (mn->gmn_mech->gm_get_name_attribute == NULL) return GSS_S_UNAVAILABLE; - attribute.length = sizeof("local-login-user") - 1; - attribute.value = "local-login-user"; - while (more != 0) { gss_buffer_desc value; gss_buffer_desc display_value; @@ -86,7 +82,7 @@ attr_pname_to_uid(OM_uint32 *minor_status, major_status = mn->gmn_mech->gm_get_name_attribute(minor_status, mn->gmn_name, - &attribute, + GSS_C_ATTR_LOCAL_LOGIN_USER, &authenticated, &complete, &value, diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 9570559d1..1df3fc7f0 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -12,6 +12,7 @@ HEIMDAL_GSS_2.0 { __gss_c_nt_user_name_oid_desc; __gss_krb5_nt_principal_name_oid_desc; __gss_c_attr_stream_sizes_oid_desc; + GSS_C_ATTR_LOCAL_LOGIN_USER; gss_accept_sec_context; gss_acquire_cred; gss_acquire_cred_with_password; @@ -19,6 +20,7 @@ HEIMDAL_GSS_2.0 { gss_add_cred; gss_add_cred_with_password; gss_add_oid_set_member; + gss_authorize_localname; gss_canonicalize_name; gss_compare_name; gss_context_query_attributes; @@ -84,7 +86,6 @@ HEIMDAL_GSS_2.0 { gss_unseal; gss_unwrap; gss_unwrap_iov; - gss_userok; gss_verify; gss_verify_mic; gss_wrap;