svn rev #24869: trunk/src/lib/gssapi/ generic/ krb5/ mechglue/

ghudson@MIT.EDU ghudson at MIT.EDU
Sun Apr 10 11:42:11 EDT 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=24869
Commit By: ghudson
Log Message:
ticket: 6891

Implement gss_authorize_localname, as discussed on the kitten list,
and make gss_userok a wrapper around it matching the Gnu GSS
prototype.  The SPI for gss_authorize_localname doesn't match the API
since we have no way of representing the contents of an internal name
to a mech at the moment.  From r24855, r24857, r24858, r24862, r24863,
r24864, r24866, r24867, and r24868 in
users/lhoward/moonshot-mechglue-fixes.



Changed Files:
U   trunk/src/lib/gssapi/generic/gssapi_ext.h
U   trunk/src/lib/gssapi/krb5/gssapi_krb5.c
U   trunk/src/lib/gssapi/libgssapi_krb5.exports
U   trunk/src/lib/gssapi/mechglue/Makefile.in
A   trunk/src/lib/gssapi/mechglue/g_authorize_localname.c
U   trunk/src/lib/gssapi/mechglue/g_initialize.c
D   trunk/src/lib/gssapi/mechglue/g_userok.c
U   trunk/src/lib/gssapi/mechglue/mglueP.h
Modified: trunk/src/lib/gssapi/generic/gssapi_ext.h
===================================================================
--- trunk/src/lib/gssapi/generic/gssapi_ext.h	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/generic/gssapi_ext.h	2011-04-10 15:42:11 UTC (rev 24869)
@@ -41,11 +41,14 @@
 	 const gss_OID mech_type,
 	 uid_t *uidOut);
 
+int KRB5_CALLCONV
+gss_userok(const gss_name_t name,
+           const char *username);
+
 OM_uint32 KRB5_CALLCONV
-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);
 
 OM_uint32 KRB5_CALLCONV
 gss_acquire_cred_with_password(

Modified: trunk/src/lib/gssapi/krb5/gssapi_krb5.c
===================================================================
--- trunk/src/lib/gssapi/krb5/gssapi_krb5.c	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/krb5/gssapi_krb5.c	2011-04-10 15:42:11 UTC (rev 24869)
@@ -797,37 +797,52 @@
 #endif /* !NO_PASSWORD */
 
 static OM_uint32
-krb5_gss_userok(OM_uint32 *minor,
-                const gss_name_t pname,
-                const char *local_user,
-                int *user_ok)
+krb5_gss_authorize_localname(OM_uint32 *minor,
+                             const gss_name_t pname,
+                             gss_const_buffer_t local_user,
+                             gss_const_OID name_type)
 {
     krb5_context context;
     krb5_error_code code;
     krb5_gss_name_t kname;
+    char *user;
+    int user_ok;
 
-    *minor = 0;
-    *user_ok = 0;
+    if (name_type != GSS_C_NO_OID &&
+        !g_OID_equal(name_type, GSS_C_NT_USER_NAME)) {
+        return GSS_S_BAD_NAMETYPE;
+    }
 
+    if (!kg_validate_name(pname)) {
+        *minor = (OM_uint32)G_VALIDATE_FAILED;
+        return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME;
+    }
+
+    kname = (krb5_gss_name_t)pname;
+
     code = krb5_gss_init_context(&context);
     if (code != 0) {
         *minor = code;
         return GSS_S_FAILURE;
     }
 
-    if (!kg_validate_name(pname)) {
-        *minor = (OM_uint32)G_VALIDATE_FAILED;
+    user = k5alloc(local_user->length + 1, &code);
+    if (user == NULL) {
+        *minor = code;
         krb5_free_context(context);
-        return GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME;
+        return GSS_S_FAILURE;
     }
 
-    kname = (krb5_gss_name_t)pname;
+    memcpy(user, local_user->value, local_user->length);
+    user[local_user->length] = '\0';
 
-    *user_ok = krb5_kuserok(context, kname->princ, local_user);
+    user_ok = krb5_kuserok(context, kname->princ, user);
 
+    free(user);
     krb5_free_context(context);
 
-    return GSS_S_COMPLETE;
+    *minor = 0;
+    return user_ok ? GSS_S_COMPLETE : GSS_S_UNAUTHORIZED;
 }
 
 static struct gss_config krb5_mechanism = {
@@ -881,7 +896,7 @@
 #else
     krb5_gss_pname_to_uid,
 #endif
-    krb5_gss_userok,
+    krb5_gss_authorize_localname,
     krb5_gss_export_name,
     krb5_gss_duplicate_name,
     krb5_gss_store_cred,

Modified: trunk/src/lib/gssapi/libgssapi_krb5.exports
===================================================================
--- trunk/src/lib/gssapi/libgssapi_krb5.exports	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/libgssapi_krb5.exports	2011-04-10 15:42:11 UTC (rev 24869)
@@ -43,6 +43,7 @@
 gss_add_cred
 gss_add_cred_impersonate_name
 gss_add_oid_set_member
+gss_authorize_localname
 gss_canonicalize_name
 gss_compare_name
 gss_complete_auth_token

Modified: trunk/src/lib/gssapi/mechglue/Makefile.in
===================================================================
--- trunk/src/lib/gssapi/mechglue/Makefile.in	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/mechglue/Makefile.in	2011-04-10 15:42:11 UTC (rev 24869)
@@ -14,6 +14,7 @@
 	$(srcdir)/g_acquire_cred.c \
 	$(srcdir)/g_acquire_cred_with_pw.c \
 	$(srcdir)/g_acquire_cred_imp_name.c \
+	$(srcdir)/g_authorize_localname.c \
 	$(srcdir)/g_buffer_set.c \
 	$(srcdir)/g_canon_name.c \
 	$(srcdir)/g_compare_name.c \
@@ -65,7 +66,6 @@
 	$(srcdir)/g_unseal.c \
 	$(srcdir)/g_unwrap_aead.c \
 	$(srcdir)/g_unwrap_iov.c \
-	$(srcdir)/g_userok.c \
 	$(srcdir)/g_verify.c \
 	$(srcdir)/g_wrap_aead.c \
 	$(srcdir)/g_wrap_iov.c \
@@ -76,6 +76,7 @@
 	$(OUTPRE)g_acquire_cred.$(OBJEXT) \
 	$(OUTPRE)g_acquire_cred_with_pw.$(OBJEXT) \
 	$(OUTPRE)g_acquire_cred_imp_name.$(OBJEXT) \
+	$(OUTPRE)g_authorize_localname.$(OBJEXT) \
 	$(OUTPRE)g_buffer_set.$(OBJEXT) \
 	$(OUTPRE)g_canon_name.$(OBJEXT) \
 	$(OUTPRE)g_compare_name.$(OBJEXT) \
@@ -127,7 +128,6 @@
 	$(OUTPRE)g_unseal.$(OBJEXT) \
 	$(OUTPRE)g_unwrap_aead.$(OBJEXT) \
 	$(OUTPRE)g_unwrap_iov.$(OBJEXT) \
-	$(OUTPRE)g_userok.$(OBJEXT) \
 	$(OUTPRE)g_verify.$(OBJEXT) \
 	$(OUTPRE)g_wrap_aead.$(OBJEXT) \
 	$(OUTPRE)g_wrap_iov.$(OBJEXT) \
@@ -138,6 +138,7 @@
 	g_acquire_cred.o \
 	g_acquire_cred_with_pw.o \
 	g_acquire_cred_imp_name.o \
+	g_authorize_localname.o \
 	g_buffer_set.o \
 	g_canon_name.o \
 	g_compare_name.o \
@@ -189,7 +190,6 @@
 	g_unseal.o \
 	g_unwrap_aead.o \
 	g_unwrap_iov.o \
-	g_userok.o \
 	g_verify.o \
 	g_wrap_aead.o \
 	g_wrap_iov.o \

Copied: trunk/src/lib/gssapi/mechglue/g_authorize_localname.c (from rev 24862, users/lhoward/moonshot-mechglue-fixes/src/lib/gssapi/mechglue/g_authorize_localname.c)
===================================================================
--- trunk/src/lib/gssapi/mechglue/g_authorize_localname.c	                        (rev 0)
+++ trunk/src/lib/gssapi/mechglue/g_authorize_localname.c	2011-04-10 15:42:11 UTC (rev 24869)
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2011, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* #pragma ident	"@(#)g_userok.c	1.1	04/03/25 SMI" */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <mglueP.h>
+#include <gssapi/gssapi.h>
+
+static OM_uint32
+mech_authorize_localname(OM_uint32 *minor,
+			 const gss_union_name_t unionName,
+			 const gss_union_name_t unionUser)
+{
+	OM_uint32 major = GSS_S_UNAVAILABLE;
+	gss_mechanism mech;
+
+	if (unionName->mech_type == GSS_C_NO_OID)
+		return (GSS_S_NAME_NOT_MN);
+
+	mech = gssint_get_mechanism(unionName->mech_type);
+	if (mech == NULL)
+		return (GSS_S_UNAVAILABLE);
+
+	if (mech->gssspi_authorize_localname != NULL) {
+		major = mech->gssspi_authorize_localname(minor,
+							 unionName->mech_name,
+							 unionUser->external_name,
+							 unionUser->name_type);
+		if (major != GSS_S_COMPLETE)
+			map_error(minor, mech);
+	}
+
+	return (major);
+}
+
+/*
+ * Naming extensions based local login authorization.
+ */
+static OM_uint32
+attr_authorize_localname(OM_uint32 *minor,
+			 const gss_name_t name,
+			 const gss_union_name_t unionUser)
+{
+	OM_uint32 major = GSS_S_UNAVAILABLE; /* attribute not present */
+	gss_buffer_t externalName;
+	int more = -1;
+
+	if (unionUser->name_type != GSS_C_NO_OID &&
+	    !g_OID_equal(unionUser->name_type, GSS_C_NT_USER_NAME))
+		return (GSS_S_BAD_NAMETYPE);
+
+	externalName = unionUser->external_name;
+	assert(externalName != GSS_C_NO_BUFFER);
+
+	while (more != 0 && major != GSS_S_COMPLETE) {
+		OM_uint32 tmpMajor, tmpMinor;
+		gss_buffer_desc value;
+		gss_buffer_desc display_value;
+		int authenticated = 0, complete = 0;
+
+		tmpMajor = gss_get_name_attribute(minor,
+						  name,
+						  GSS_C_ATTR_LOCAL_LOGIN_USER,
+						  &authenticated,
+						  &complete,
+						  &value,
+						  &display_value,
+						  &more);
+		if (GSS_ERROR(tmpMajor)) {
+			major = tmpMajor;
+			break;
+		}
+
+		if (authenticated &&
+		    value.length == externalName->length &&
+		    memcmp(value.value, externalName->value, externalName->length) == 0)
+			major = GSS_S_COMPLETE;
+		else
+			major = GSS_S_UNAUTHORIZED;
+
+		gss_release_buffer(&tmpMinor, &value);
+		gss_release_buffer(&tmpMinor, &display_value);
+	}
+
+	return (major);
+}
+
+/*
+ * Equality based local login authorization.
+ */
+static OM_uint32
+compare_names_authorize_localname(OM_uint32 *minor,
+				 const gss_union_name_t unionName,
+				 const gss_name_t user)
+{
+
+	OM_uint32 status, tmpMinor;
+	gss_name_t canonName;
+	int match = 0;
+
+	status = gss_canonicalize_name(minor,
+				       user,
+				       unionName->mech_type,
+				       &canonName);
+	if (status != GSS_S_COMPLETE)
+		return (status);
+
+	status = gss_compare_name(minor,
+				  (gss_name_t)unionName,
+				  canonName,
+				  &match);
+	if (status == GSS_S_COMPLETE && match == 0)
+		status = GSS_S_UNAUTHORIZED;
+
+	(void) gss_release_name(&tmpMinor, &canonName);
+
+	return (status);
+}
+
+OM_uint32
+gss_authorize_localname(OM_uint32 *minor,
+			const gss_name_t name,
+			const gss_name_t user)
+
+{
+	OM_uint32 major;
+	gss_union_name_t unionName;
+	gss_union_name_t unionUser;
+	int mechAvailable = 0;
+
+	if (minor == NULL)
+		return (GSS_S_CALL_INACCESSIBLE_WRITE);
+
+	if (name == GSS_C_NO_NAME || user == GSS_C_NO_NAME)
+		return (GSS_S_CALL_INACCESSIBLE_READ);
+
+	*minor = 0;
+
+	unionName = (gss_union_name_t)name;
+	unionUser = (gss_union_name_t)user;
+
+	if (unionUser->mech_type != GSS_C_NO_OID)
+		return (GSS_S_BAD_NAME);
+
+	/* If mech returns yes, we return yes */
+	major = mech_authorize_localname(minor, unionName, unionUser);
+	if (major == GSS_S_COMPLETE)
+		return (GSS_S_COMPLETE);
+	else if (major != GSS_S_UNAVAILABLE)
+		mechAvailable = 1;
+
+	/* If attribute exists, we evaluate attribute */
+	major = attr_authorize_localname(minor, unionName, unionUser);
+	if (major == GSS_S_COMPLETE || major == GSS_S_UNAUTHORIZED)
+		return (major);
+
+	/* If mech did not implement SPI, compare the local name */
+	if (mechAvailable == 0 &&
+	    unionName->mech_type != GSS_C_NO_OID) {
+		major = compare_names_authorize_localname(minor,
+							  unionName,
+							  unionUser);
+	}
+
+	return (major);
+}
+
+int
+gss_userok(const gss_name_t name,
+	   const char *user)
+{
+	OM_uint32 major, minor;
+	gss_buffer_desc userBuf;
+	gss_name_t userName;
+
+	userBuf.value = (void *)user;
+	userBuf.length = strlen(user);
+
+	major = gss_import_name(&minor, &userBuf, GSS_C_NT_USER_NAME, &userName);
+	if (GSS_ERROR(major))
+		return (0);
+
+	major = gss_authorize_localname(&minor, name, userName);
+
+	(void) gss_release_name(&minor, &userName);
+
+	return (major == GSS_S_COMPLETE);
+}

Modified: trunk/src/lib/gssapi/mechglue/g_initialize.c
===================================================================
--- trunk/src/lib/gssapi/mechglue/g_initialize.c	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/mechglue/g_initialize.c	2011-04-10 15:42:11 UTC (rev 24869)
@@ -777,7 +777,7 @@
 	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_userok);
+	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);
 	GSS_ADD_DYNAMIC_METHOD_NOLOOP(dl, mech, gss_store_cred);

Modified: trunk/src/lib/gssapi/mechglue/mglueP.h
===================================================================
--- trunk/src/lib/gssapi/mechglue/mglueP.h	2011-04-09 03:40:43 UTC (rev 24868)
+++ trunk/src/lib/gssapi/mechglue/mglueP.h	2011-04-10 15:42:11 UTC (rev 24869)
@@ -342,12 +342,12 @@
 		    const gss_OID,	/* mech_type */
 		    uid_t *		/* uid */
 	    );
-	OM_uint32		(*gss_userok)
+	OM_uint32		(*gssspi_authorize_localname)
 	(
 		    OM_uint32 *,	/* minor_status */
 		    const gss_name_t,	/* pname */
-		    const char *,	/* local user */
-		    int *		/* user ok? */
+		    gss_const_buffer_t,	/* local user */
+		    gss_const_OID	/* local nametype */
 	/* */);
 	OM_uint32		(*gss_export_name)
 	(
@@ -723,14 +723,6 @@
 	int arrayLen			/* length of passed in array */
 );
 
-OM_uint32
-gssint_userok(
-	OM_uint32 *,		/* minor */
-	const gss_name_t,	/* name */
-	const char *,		/* user */
-	int *			/* user_ok */
-);
-
 int
 gssint_get_der_length(
 	unsigned char **,	/* buf */




More information about the cvs-krb5 mailing list