From fe12e6f6da58abc3cc3e2d30d3925259ad1fbf6a Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Wed, 21 Sep 2011 18:40:43 +0000 Subject: [PATCH] * New implementation to map a gss name to localname * Write gss_pname_to_uid in terms of gss_localname; suppress on win32 * Add test for gss_pname_to_uid indirectly testing gss_localname * gss_localname is the SPI, not gss_pname_to_uid * fix some const gss_OID->gss_const_oid Signed-off-by: Sam Hartman gss_localname: map gss name to localname git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25222 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/generic/gssapi_ext.h | 19 ++++ src/lib/gssapi/krb5/gssapi_krb5.c | 30 ++---- src/lib/gssapi/libgssapi_krb5.exports | 1 + src/lib/gssapi/mechglue/g_initialize.c | 10 +- src/lib/gssapi/mechglue/gssd_pname_to_uid.c | 113 ++++++++++++-------- src/lib/gssapi/mechglue/mglueP.h | 8 +- src/tests/gssapi/t_gssexts.c | 5 +- 7 files changed, 110 insertions(+), 76 deletions(-) diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h index 174bef670..07f0c688e 100644 --- a/src/lib/gssapi/generic/gssapi_ext.h +++ b/src/lib/gssapi/generic/gssapi_ext.h @@ -34,12 +34,31 @@ extern "C" { /* * Solaris extensions */ +#ifndef _WIN32 OM_uint32 KRB5_CALLCONV gss_pname_to_uid (OM_uint32 *minor, const gss_name_t name, const gss_OID mech_type, uid_t *uidOut); +#endif + + /** + * Provides a platform-specific name for a GSSAPI name as + * interpreted by a given mechanism + * @param name The gss name resulting from accept_sec_context + * @param mech_type The mechanism that will be asked to map @a name to a local name + * @param localname pointer to a buffer_desc allocated by the caller + * that will be filled in with the local name on successful completion. + */ +OM_uint32 KRB5_CALLCONV +gss_localname + (OM_uint32 *minor, + const gss_name_t name, + gss_const_OID mech_type, + gss_buffer_t localname); + + /** Determine whether a mechanism name is authorized to act as a username. * diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 4d4f545f5..48918b461 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -739,18 +739,16 @@ cleanup: return major; } -#ifndef NO_PASSWORD static OM_uint32 KRB5_CALLCONV -krb5_gss_pname_to_uid(OM_uint32 *minor, - const gss_name_t pname, - const gss_OID mech_type, - uid_t *uid) +krb5_gss_localname(OM_uint32 *minor, + const gss_name_t pname, + const gss_const_OID mech_type, + gss_buffer_t localname) { krb5_context context; krb5_error_code code; krb5_gss_name_t kname; - char localname[BUFSIZ], pwbuf[BUFSIZ]; - struct passwd pwx, *pw; + char lname[BUFSIZ]; code = krb5_gss_init_context(&context); if (code != 0) { @@ -761,24 +759,21 @@ krb5_gss_pname_to_uid(OM_uint32 *minor, kname = (krb5_gss_name_t)pname; code = krb5_aname_to_localname(context, kname->princ, - sizeof(localname), localname); + sizeof(lname), lname); if (code != 0) { *minor = KRB5_NO_LOCALNAME; krb5_free_context(context); return GSS_S_FAILURE; } - code = k5_getpwnam_r(localname, &pwx, pwbuf, sizeof(pwbuf), &pw); - if (code == 0 && pw != NULL) - *uid = pw->pw_uid; - else - *minor = KRB5_NO_LOCALNAME; krb5_free_context(context); + localname->value = strdup(lname); + localname->length = strlen(lname); return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; } -#endif /* !NO_PASSWORD */ + static OM_uint32 KRB5_CALLCONV krb5_gss_authorize_localname(OM_uint32 *minor, @@ -870,11 +865,8 @@ static struct gss_config krb5_mechanism = { krb5_gss_inquire_context, krb5_gss_internal_release_oid, krb5_gss_wrap_size_limit, -#ifdef NO_PASSWORD - NULL, -#else - krb5_gss_pname_to_uid, -#endif + krb5_gss_localname, + krb5_gss_authorize_localname, krb5_gss_export_name, krb5_gss_duplicate_name, diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports index 2f85a7189..2ca736c6f 100644 --- a/src/lib/gssapi/libgssapi_krb5.exports +++ b/src/lib/gssapi/libgssapi_krb5.exports @@ -91,6 +91,7 @@ gss_krb5int_make_seal_token_v3 gss_krb5int_unseal_token_v3 gsskrb5_extract_authtime_from_sec_context gsskrb5_extract_authz_data_from_sec_context +gss_localname gss_map_name_to_any gss_mech_iakerb gss_mech_krb5 diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c index 30395312e..e0bbd5ae5 100644 --- a/src/lib/gssapi/mechglue/g_initialize.c +++ b/src/lib/gssapi/mechglue/g_initialize.c @@ -59,8 +59,8 @@ #endif /* Local functions */ -static gss_mech_info searchMechList(const gss_OID); static void addConfigEntry(const char *oidStr, const char *oid, const char *sharedLib, const char *kernMod, const char *modOptions); +static gss_mech_info searchMechList(gss_const_OID); static void loadConfigFile(const char *); #if defined(_WIN32) #ifndef MECH_KEY @@ -796,7 +796,7 @@ build_dynamicMech(void *dl, const gss_OID mech_type) GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_inquire_context); GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_internal_release_oid); GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_wrap_size_limit); - GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_pname_to_uid); + GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_localname); GSS_ADD_DYNAMIC_METHOD(dl, mech, gssspi_authorize_localname); GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_export_name); GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_duplicate_name); @@ -896,8 +896,7 @@ freeMechList(void) * module if it has not been already loaded. */ gss_mechanism -gssint_get_mechanism(oid) -const gss_OID oid; +gssint_get_mechanism(gss_const_OID oid) { gss_mech_info aMech; gss_mechanism (*sym)(const gss_OID); @@ -1026,8 +1025,7 @@ const gss_OID oid; * * this needs to be called with g_mechListLock held. */ -static gss_mech_info searchMechList(oid) -const gss_OID oid; +static gss_mech_info searchMechList(gss_const_OID oid) { gss_mech_info aMech = g_mechList; diff --git a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c index 13ba1f0ca..23e2cf931 100644 --- a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c +++ b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c @@ -67,27 +67,23 @@ #endif static OM_uint32 -attr_pname_to_uid(OM_uint32 *minor, +attr_localname(OM_uint32 *minor, const gss_mechanism mech, const gss_name_t mech_name, - uid_t *uidp) + gss_buffer_t localname) { OM_uint32 major = GSS_S_UNAVAILABLE; -#ifndef NO_PASSWORD OM_uint32 tmpMinor; int more = -1; + gss_buffer_desc value; + gss_buffer_desc display_value; + int authenticated = 0, complete = 0; + value.value = NULL; + display_value.value = NULL; if (mech->gss_get_name_attribute == NULL) return GSS_S_UNAVAILABLE; - while (more != 0) { - gss_buffer_desc value; - gss_buffer_desc display_value; - int authenticated = 0, complete = 0, code; - char pwbuf[BUFSIZ]; - struct passwd pw, *pwd; - char *localLoginUser; - major = mech->gss_get_name_attribute(minor, mech_name, GSS_C_ATTR_LOCAL_LOGIN_USER, @@ -98,43 +94,28 @@ attr_pname_to_uid(OM_uint32 *minor, &more); if (GSS_ERROR(major)) { map_error(minor, mech); - break; - } - - localLoginUser = malloc(value.length + 1); - if (localLoginUser == NULL) { - major = GSS_S_FAILURE; - *minor = ENOMEM; - break; + goto cleanup; } - memcpy(localLoginUser, value.value, value.length); - localLoginUser[value.length] = '\0'; - - code = k5_getpwnam_r(localLoginUser, &pw, pwbuf, sizeof(pwbuf), &pwd); - - free(localLoginUser); - gss_release_buffer(&tmpMinor, &value); - gss_release_buffer(&tmpMinor, &display_value); - - if (code == 0 && pwd != NULL) { - *uidp = pwd->pw_uid; - major = GSS_S_COMPLETE; - *minor = 0; - break; - } else - major = GSS_S_UNAVAILABLE; - } -#endif /* !NO_PASSWORD */ - + if (!authenticated) + major = GSS_S_UNAVAILABLE; + else { + localname->value = value.value; + localname->length = value.length; + value.value = NULL; + } +cleanup: + if (display_value.value) + gss_release_buffer(&tmpMinor, &display_value); + if (value.value) + gss_release_buffer(&tmpMinor, &value); return major; } - OM_uint32 KRB5_CALLCONV -gss_pname_to_uid(OM_uint32 *minor, +gss_localname(OM_uint32 *minor, const gss_name_t pname, - const gss_OID mech_type, - uid_t *uidp) + gss_const_OID mech_type, + gss_buffer_t localname) { OM_uint32 major, tmpMinor; gss_mechanism mech; @@ -153,7 +134,7 @@ gss_pname_to_uid(OM_uint32 *minor, if (pname == GSS_C_NO_NAME) return GSS_S_CALL_INACCESSIBLE_READ; - if (uidp == NULL) + if (localname == NULL) return GSS_S_CALL_INACCESSIBLE_WRITE; unionName = (gss_union_name_t)pname; @@ -181,17 +162,57 @@ gss_pname_to_uid(OM_uint32 *minor, major = GSS_S_UNAVAILABLE; - if (mech->gss_pname_to_uid != NULL) { - major = mech->gss_pname_to_uid(minor, mechNameP, mech_type, uidp); + if (mech->gss_localname != NULL) { + major = mech->gss_localname(minor, mechNameP, mech_type, localname); if (GSS_ERROR(major)) map_error(minor, mech); } if (GSS_ERROR(major)) - major = attr_pname_to_uid(minor, mech, mechNameP, uidp); + major = attr_localname(minor, mech, mechNameP, localname); if (mechName != GSS_C_NO_NAME) gssint_release_internal_name(&tmpMinor, &mech->mech_type, &mechName); return major; } + +#ifndef _WIN32 +OM_uint32 KRB5_CALLCONV +gss_pname_to_uid + (OM_uint32 *minor, + const gss_name_t name, + const gss_OID mech_type, + uid_t *uidOut) +{ + OM_uint32 major = GSS_S_UNAVAILABLE, tmpminor; + #ifndef NO_PASSWORD + gss_buffer_desc localname; + char pwbuf[BUFSIZ]; + char *localuser = NULL; + struct passwd *pwd = NULL; + struct passwd pw; + int code = 0; + + localname.value = NULL; + major = gss_localname(minor, name, mech_type, &localname); + if (!GSS_ERROR(major) && localname.value) { + localuser = malloc(localname.length + 1); + if (localuser == NULL) + code = ENOMEM; + if (code == 0) { + memcpy(localuser, localname.value, localname.length); + localuser[localname.length] = '\0'; + code = k5_getpwnam_r(localuser, &pw, pwbuf, sizeof(pwbuf), &pwd); + } + if ((code == 0) && pwd) + *uidOut = pwd->pw_uid; + else major = GSS_S_FAILURE; + } + free(localuser); + if (localname.value) + gss_release_buffer(&tmpminor, &localname); +#endif /*NO_PASSWORD*/ + return major; +} +#endif /*_WIN32*/ diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index b34dd7ce3..356dc6877 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -323,12 +323,12 @@ typedef struct gss_config { OM_uint32, /* req_output_size */ OM_uint32 * /* max_input_size */ ); - OM_uint32 (KRB5_CALLCONV *gss_pname_to_uid) + OM_uint32 (* KRB5_CALLCONV gss_localname) ( OM_uint32 *, /* minor */ const gss_name_t, /* name */ - const gss_OID, /* mech_type */ - uid_t * /* uid */ + gss_const_OID, /* mech_type */ + gss_buffer_t /* localname */ ); OM_uint32 (KRB5_CALLCONV *gssspi_authorize_localname) ( @@ -641,7 +641,7 @@ int gssint_mechglue_init(void); void gssint_mechglue_fini(void); #endif -gss_mechanism gssint_get_mechanism (gss_OID); +gss_mechanism gssint_get_mechanism (gss_const_OID); gss_mechanism_ext gssint_get_mechanism_ext(const gss_OID); OM_uint32 gssint_get_mech_type (gss_OID, gss_buffer_t); char *gssint_get_kmodName(const gss_OID); diff --git a/src/tests/gssapi/t_gssexts.c b/src/tests/gssapi/t_gssexts.c index 7992cdfdd..d4cb292cb 100644 --- a/src/tests/gssapi/t_gssexts.c +++ b/src/tests/gssapi/t_gssexts.c @@ -365,6 +365,7 @@ main(int argc, char *argv[]) gss_OID_set_desc mechs; gss_OID_set actual_mechs = GSS_C_NO_OID_SET; gss_buffer_desc buf; + uid_t uid; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " @@ -385,8 +386,10 @@ main(int argc, char *argv[]) major = gss_import_name(&minor, &buf, (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME, &user); + + major = gss_pname_to_uid(&minor, user, NULL, &uid); if (GSS_ERROR(major)) { - displayStatus("gss_import_name(user)", major, minor); + displayStatus("gss_pname_to_uid(user)", major, minor); goto out; } -- 2.26.2