From 07777511d19e43e57057ca93f7eed2e1f4428699 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sat, 8 Oct 2011 12:15:09 +1100 Subject: [PATCH] implement gss_localname --- lib/gssapi/gssapi/gssapi.h | 7 ++ lib/gssapi/gssapi_mech.h | 6 +- lib/gssapi/krb5/external.c | 2 +- lib/gssapi/krb5/pname_to_uid.c | 41 +++---- lib/gssapi/libgssapi-exports.def | 1 + lib/gssapi/mech/gss_mech_switch.c | 2 +- lib/gssapi/mech/gss_pname_to_uid.c | 168 ++++++++++++++++------------- lib/gssapi/version-script.map | 1 + 8 files changed, 119 insertions(+), 109 deletions(-) diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index bbb2fd54c..131f193a4 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -1029,6 +1029,13 @@ GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred_with_password ( OM_uint32 * /*acceptor_time_rec*/ ); +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_localname( + OM_uint32 *minor, + const gss_name_t name, + const gss_OID mech_type, + gss_buffer_t localname); + GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_pname_to_uid( OM_uint32 *minor, diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index e4ccfdb0c..95c42fec8 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -460,11 +460,11 @@ struct gss_mo_desc_struct { int (*set)(gss_const_OID, gss_mo_desc *, int, gss_buffer_t); }; -typedef OM_uint32 GSSAPI_CALLCONV _gss_pname_to_uid_t ( +typedef OM_uint32 GSSAPI_CALLCONV _gss_localname_t ( OM_uint32 *, /* minor_status */ const gss_name_t, /* name */ const gss_OID, /* mech_type */ - uid_t * /* uidOut */ + gss_buffer_t /* localname */ ); typedef OM_uint32 GSSAPI_CALLCONV _gss_authorize_localname_t ( @@ -536,7 +536,7 @@ typedef struct gssapi_mech_interface_desc { _gss_cred_label_set_t *gm_cred_label_set; gss_mo_desc *gm_mo; size_t gm_mo_num; - _gss_pname_to_uid_t *gm_pname_to_uid; + _gss_localname_t *gm_localname; _gss_authorize_localname_t *gm_authorize_localname; _gss_display_name_ext_t *gm_display_name_ext; _gss_inquire_name_t *gm_inquire_name; diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index 26ede2487..f31244678 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -324,7 +324,7 @@ static gssapi_mech_interface_desc krb5_mech = { NULL, krb5_mo, sizeof(krb5_mo) / sizeof(krb5_mo[0]), - _gsskrb5_pname_to_uid, + _gsskrb5_localname, _gsskrb5_authorize_localname, NULL, NULL, diff --git a/lib/gssapi/krb5/pname_to_uid.c b/lib/gssapi/krb5/pname_to_uid.c index ff754e779..7f21c87b5 100644 --- a/lib/gssapi/krb5/pname_to_uid.c +++ b/lib/gssapi/krb5/pname_to_uid.c @@ -33,53 +33,38 @@ #include "gsskrb5_locl.h" OM_uint32 GSSAPI_CALLCONV -_gsskrb5_pname_to_uid(OM_uint32 *minor_status, - const gss_name_t pname, - const gss_OID mech_type, - uid_t *uidp) +_gsskrb5_localname(OM_uint32 *minor_status, + const gss_name_t pname, + const gss_OID mech_type, + gss_buffer_t localname) { -#ifdef NO_LOCALNAME - *minor_status = KRB5_NO_LOCALNAME; - return GSS_S_FAILURE; -#else krb5_error_code ret; krb5_context context; krb5_const_principal princ = (krb5_const_principal)pname; - char localname[256]; -#ifdef POSIX_GETPWNAM_R - char pwbuf[2048]; - struct passwd pw, *pwd; -#else - struct passwd *pwd; -#endif + char lnamebuf[256]; GSSAPI_KRB5_INIT(&context); *minor_status = 0; ret = krb5_aname_to_localname(context, princ, - sizeof(localname), localname); + sizeof(lnamebuf), lnamebuf); if (ret != 0) { *minor_status = ret; return GSS_S_FAILURE; } -#ifdef POSIX_GETPWNAM_R - if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) { - *minor_status = KRB5_NO_LOCALNAME; - return GSS_S_FAILURE; - } -#else - pwd = getpwnam(localname); -#endif + localname->length = strlen(lnamebuf); - if (pwd == NULL) { - *minor_status = KRB5_NO_LOCALNAME; + localname->value = malloc(localname->length + 1); + if (localname->value == NULL) { + localname->length = 0; + *minor_status = ENOMEM; return GSS_S_FAILURE; } - *uidp = pwd->pw_uid; + memcpy(localname->value, lnamebuf, localname->length + 1); + *minor_status = 0; return GSS_S_COMPLETE; -#endif /* NO_LOCALNAME */ } diff --git a/lib/gssapi/libgssapi-exports.def b/lib/gssapi/libgssapi-exports.def index 3cbcc4eb1..1c04698b6 100644 --- a/lib/gssapi/libgssapi-exports.def +++ b/lib/gssapi/libgssapi-exports.def @@ -65,6 +65,7 @@ EXPORTS gss_krb5_get_tkt_flags gss_krb5_import_cred gss_krb5_set_allowable_enctypes + gss_localname gss_mg_collect_error gss_mo_get gss_mo_set diff --git a/lib/gssapi/mech/gss_mech_switch.c b/lib/gssapi/mech/gss_mech_switch.c index 55e01094f..de3c80956 100644 --- a/lib/gssapi/mech/gss_mech_switch.c +++ b/lib/gssapi/mech/gss_mech_switch.c @@ -381,7 +381,7 @@ _gss_load_mech(void) OPTSYM(set_name_attribute); OPTSYM(delete_name_attribute); OPTSYM(export_name_composite); - OPTSYM(pname_to_uid); + OPTSYM(localname); OPTSPISYM(authorize_localname); mi = dlsym(so, "gss_mo_init"); diff --git a/lib/gssapi/mech/gss_pname_to_uid.c b/lib/gssapi/mech/gss_pname_to_uid.c index c5f26949f..d60d93783 100644 --- a/lib/gssapi/mech/gss_pname_to_uid.c +++ b/lib/gssapi/mech/gss_pname_to_uid.c @@ -33,21 +33,21 @@ #include "mech_locl.h" static OM_uint32 -mech_pname_to_uid(OM_uint32 *minor_status, - struct _gss_mechanism_name *mn, - uid_t *uidp) +mech_localname(OM_uint32 *minor_status, + struct _gss_mechanism_name *mn, + gss_buffer_t localname) { OM_uint32 major_status = GSS_S_UNAVAILABLE; *minor_status = 0; - if (mn->gmn_mech->gm_pname_to_uid == NULL) + if (mn->gmn_mech->gm_localname == NULL) return GSS_S_UNAVAILABLE; - major_status = mn->gmn_mech->gm_pname_to_uid(minor_status, - mn->gmn_name, - mn->gmn_mech_oid, - uidp); + major_status = mn->gmn_mech->gm_localname(minor_status, + mn->gmn_name, + mn->gmn_mech_oid, + localname); if (GSS_ERROR(major_status)) _gss_mg_error(mn->gmn_mech, major_status, *minor_status); @@ -55,86 +55,45 @@ mech_pname_to_uid(OM_uint32 *minor_status, } static OM_uint32 -attr_pname_to_uid(OM_uint32 *minor_status, - struct _gss_mechanism_name *mn, - uid_t *uidp) +attr_localname(OM_uint32 *minor_status, + struct _gss_mechanism_name *mn, + gss_buffer_t localname) { -#ifdef NO_LOCALNAME - return GSS_S_UNAVAILABLE; -#else OM_uint32 major_status = GSS_S_UNAVAILABLE; OM_uint32 tmpMinor; + gss_buffer_desc display_value = GSS_C_EMPTY_BUFFER; + int authenticated = 0, complete = 0; int more = -1; *minor_status = 0; + localname->length = 0; + localname->value = NULL; + if (mn->gmn_mech->gm_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; -#ifdef POSIX_GETPWNAM_R - char pwbuf[2048]; - struct passwd pw, *pwd; -#else - struct passwd *pwd; -#endif - char *localname; - - major_status = mn->gmn_mech->gm_get_name_attribute(minor_status, - mn->gmn_name, - GSS_C_ATTR_LOCAL_LOGIN_USER, - &authenticated, - &complete, - &value, - &display_value, - &more); - if (GSS_ERROR(major_status)) { - _gss_mg_error(mn->gmn_mech, major_status, *minor_status); - break; - } - - localname = malloc(value.length + 1); - if (localname == NULL) { - major_status = GSS_S_FAILURE; - *minor_status = ENOMEM; - break; - } - - memcpy(localname, value.value, value.length); - localname[value.length] = '\0'; - -#ifdef POSIX_GETPWNAM_R - if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) - pwd = NULL; -#else - pwd = getpwnam(localname); -#endif - - free(localname); - gss_release_buffer(&tmpMinor, &value); + major_status = mn->gmn_mech->gm_get_name_attribute(minor_status, + mn->gmn_name, + GSS_C_ATTR_LOCAL_LOGIN_USER, + &authenticated, + &complete, + localname, + &display_value, + &more); + if (GSS_ERROR(major_status)) + _gss_mg_error(mn->gmn_mech, major_status, *minor_status); + else gss_release_buffer(&tmpMinor, &display_value); - if (pwd != NULL) { - *uidp = pwd->pw_uid; - major_status = GSS_S_COMPLETE; - *minor_status = 0; - break; - } else - major_status = GSS_S_UNAVAILABLE; - } - return major_status; -#endif /* NO_LOCALNAME */ } GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL -gss_pname_to_uid(OM_uint32 *minor_status, - const gss_name_t pname, - const gss_OID mech_type, - uid_t *uidp) +gss_localname(OM_uint32 *minor_status, + const gss_name_t pname, + const gss_OID mech_type, + gss_buffer_t localname) { OM_uint32 major_status = GSS_S_UNAVAILABLE; struct _gss_name *name = (struct _gss_name *) pname; @@ -147,14 +106,14 @@ gss_pname_to_uid(OM_uint32 *minor_status, if (GSS_ERROR(major_status)) return major_status; - major_status = mech_pname_to_uid(minor_status, mn, uidp); + major_status = mech_localname(minor_status, mn, localname); if (major_status != GSS_S_COMPLETE) - major_status = attr_pname_to_uid(minor_status, mn, uidp); + major_status = attr_localname(minor_status, mn, localname); } else { HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { - major_status = mech_pname_to_uid(minor_status, mn, uidp); + major_status = mech_localname(minor_status, mn, localname); if (major_status != GSS_S_COMPLETE) - major_status = attr_pname_to_uid(minor_status, mn, uidp); + major_status = attr_localname(minor_status, mn, localname); if (major_status != GSS_S_UNAVAILABLE) break; } @@ -165,3 +124,60 @@ gss_pname_to_uid(OM_uint32 *minor_status, return major_status; } + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_pname_to_uid(OM_uint32 *minor_status, + const gss_name_t pname, + const gss_OID mech_type, + uid_t *uidp) +{ +#ifdef NO_LOCALNAME + return GSS_S_UNAVAILABLE; +#else + OM_uint32 major, tmpMinor; + gss_buffer_desc localname = GSS_C_EMPTY_BUFFER; + char *szLocalname; +#ifdef POSIX_GETPWNAM_R + char pwbuf[2048]; + struct passwd pw, *pwd; +#else + struct passwd *pwd; +#endif + + major = gss_localname(minor_status, pname, mech_type, &localname); + if (GSS_ERROR(major)) + return major; + + szLocalname = malloc(localname.length + 1); + if (szLocalname == NULL) { + gss_release_buffer(&tmpMinor, &localname); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(szLocalname, localname.value, localname.length); + szLocalname[localname.length] = '\0'; + +#ifdef POSIX_GETPWNAM_R + if (getpwnam_r(szLocalname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) + pwd = NULL; +#else + pwd = getpwnam(szLocalname); +#endif + + gss_release_buffer(&tmpMinor, &localname); + free(szLocalname); + + *minor_status = 0; + + if (pwd != NULL) { + *uidp = pwd->pw_uid; + major = GSS_S_COMPLETE; + } else { + major = GSS_S_UNAVAILABLE; + } + + return major; +#endif +} diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index bcb79bf8f..57667a760 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -65,6 +65,7 @@ HEIMDAL_GSS_2.0 { gss_krb5_get_tkt_flags; gss_krb5_import_cred; gss_krb5_set_allowable_enctypes; + gss_localname; gss_mg_collect_error; gss_oid_equal; gss_oid_to_str;