Add gss_localname support
authorSimo Sorce <simo@redhat.com>
Sat, 12 Jul 2014 12:19:20 +0000 (08:19 -0400)
committerSimo Sorce <simo@redhat.com>
Sat, 12 Jul 2014 12:19:20 +0000 (08:19 -0400)
Uses the fully qualified name and falls back to simple user name and
calls getpwnam_r() to resolve a local name. If the user is not known
to the nsswitch subsystme it returns a failure.

src/gss_names.c
src/gss_ntlmssp.h
src/gss_spi.c

index 64e4df3224652975ae8b10dc537b7c5ad7c42559..f48d1178c6a30c159970e610462d1f69f6e95d66 100644 (file)
@@ -466,3 +466,66 @@ uint32_t gssntlm_display_name(uint32_t *minor_status,
 
     return GSS_S_COMPLETE;
 }
+
+#define PWBUFLEN 1024
+
+uint32_t gssntlm_localname(uint32_t *minor_status,
+                          const gss_name_t name,
+                          gss_const_OID mech_type,
+                          gss_buffer_t localname)
+{
+    struct gssntlm_name *in;
+    char *uname = NULL;
+    char pwbuf[PWBUFLEN];
+    struct passwd pw, *res;
+    uint32_t min = 0;
+    int ret;
+
+    in = (struct gssntlm_name *)name;
+    if (in->type != GSSNTLM_NAME_USER) {
+        *minor_status = EINVAL;
+        return GSS_S_FAILURE;
+    }
+
+    /* TODO: hook up with winbindd/sssd for name resolution ? */
+
+    if (in->data.user.domain) {
+        ret = asprintf(&uname, "%s\\%s",
+                       in->data.user.domain, in->data.user.name);
+        if (ret == -1) {
+            min = ENOMEM;
+            goto done;
+        }
+        ret = getpwnam_r(uname, &pw, pwbuf, PWBUFLEN, &res);
+        if (ret) {
+            min = ret;
+            goto done;
+        }
+        safefree(uname);
+        if (res) {
+            uname = strdup(res->pw_name);
+        }
+    }
+    if (uname == NULL) {
+        ret = getpwnam_r(in->data.user.name, &pw, pwbuf, PWBUFLEN, &res);
+        if (ret != 0 || res == NULL) {
+            min = ret;
+            goto done;
+        }
+        uname = strdup(res->pw_name);
+    }
+    if (!uname) {
+        min = ENOMEM;
+        goto done;
+    }
+
+done:
+    *minor_status = min;
+    if (min) {
+        free(uname);
+        return GSS_S_FAILURE;
+    }
+    localname->value = uname;
+    localname->length = strlen(uname) + 1;
+    return GSS_S_COMPLETE;
+}
index 194e9545fa80098beaf3be4bd9f02488f6d972bd..803b7bf64ae37bddcf9af24c5a3778c35854c2cb 100644 (file)
@@ -313,6 +313,11 @@ uint32_t gssntlm_display_name(uint32_t *minor_status,
                               gss_buffer_t output_name_buffer,
                               gss_OID *output_name_type);
 
+uint32_t gssntlm_localname(uint32_t *minor_status,
+                          const gss_name_t name,
+                          gss_const_OID mech_type,
+                          gss_buffer_t localname);
+
 uint32_t gssntlm_inquire_cred(uint32_t *minor_status,
                               gss_cred_id_t cred_handle,
                               gss_name_t *name,
index a74bacee07f11ebf03893ae2781850ee8e9955c0..220b32c835d1f66776acdf4c82ab0b97b74679cc 100644 (file)
@@ -286,6 +286,17 @@ OM_uint32 gss_display_name(OM_uint32 *minor_status,
                                 output_name_type);
 }
 
+OM_uint32 gss_localname(OM_uint32 *minor_status,
+                       const gss_name_t name,
+                       gss_const_OID mech_type,
+                       gss_buffer_t localname)
+{
+    return gssntlm_localname(minor_status,
+                             name,
+                             mech_type,
+                             localname);
+}
+
 OM_uint32 gss_set_sec_context_option(OM_uint32 *minor_status,
                                      gss_ctx_id_t *context_handle,
                                      const gss_OID desired_object,