* New implementation to map a gss name to localname
authorSam Hartman <hartmans@mit.edu>
Wed, 21 Sep 2011 18:40:43 +0000 (18:40 +0000)
committerSam Hartman <hartmans@mit.edu>
Wed, 21 Sep 2011 18:40:43 +0000 (18:40 +0000)
* 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 <hartmans@painless-security.com>
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
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/libgssapi_krb5.exports
src/lib/gssapi/mechglue/g_initialize.c
src/lib/gssapi/mechglue/gssd_pname_to_uid.c
src/lib/gssapi/mechglue/mglueP.h
src/tests/gssapi/t_gssexts.c

index 174bef670eb32e061213a9323ea8d102aa92bdb3..07f0c688eee7870902c656234ada22fb2e0bf666 100644 (file)
@@ -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.
  *
index 4d4f545f5cad5a0ce71f930869a65e88502fe71f..48918b461bc08fe27e0ca959f15ea4a38b08b79c 100644 (file)
@@ -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,
index 2f85a7189c506baf7cd16d15050c34a38037e882..2ca736c6fb6e0380b4994a0390d698981ed974e4 100644 (file)
@@ -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
index 30395312eb99377e30ce968edce68ecfb1455fd1..e0bbd5ae535a32b20063dc8622da2017d85a9135 100644 (file)
@@ -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;
 
index 13ba1f0ca87ab85daa8a409c2ce7854d5eabc323..23e2cf931f44692cba40c4d78e1b31c7d7b7aab5 100644 (file)
 #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*/
index b34dd7ce316f9f49093f09e3eb5333968ea19180..356dc68776a2f30bedd978c3da06e4b187724de5 100644 (file)
@@ -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);
index 7992cdfdd166d50a4c0149d84dd6fd75fccda9e9..d4cb292cb66fe438ae36d5ca0badc3a28545e066 100644 (file)
@@ -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;
     }