aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gssapi
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2011-03-17 12:44:43 +0000
committerLuke Howard <lukeh@padl.com>2011-03-17 12:44:43 +0000
commit5cf261cf481d297a17cdf7ca59561dbd0c3f76ee (patch)
tree05703fbffac81da59df3ecfa25c05e76a319f618 /src/lib/gssapi
parent7f0522e1d37f561dcb1b7df695550ee1ebec5d90 (diff)
downloadkrb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.zip
krb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.tar.gz
krb5-5cf261cf481d297a17cdf7ca59561dbd0c3f76ee.tar.bz2
implement attribute-based userok authorisation logic as suggested
by Sam Hartman git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/moonshot-mechglue-fixes@24717 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/mechglue/g_userok.c145
1 files changed, 121 insertions, 24 deletions
diff --git a/src/lib/gssapi/mechglue/g_userok.c b/src/lib/gssapi/mechglue/g_userok.c
index 1fbca2d..2544b72 100644
--- a/src/lib/gssapi/mechglue/g_userok.c
+++ b/src/lib/gssapi/mechglue/g_userok.c
@@ -1,4 +1,27 @@
/*
+ * Copyright (C) 2011 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -12,14 +35,92 @@
#include <mglueP.h>
#include <gssapi/gssapi.h>
+static const char localLoginUserAttr[] = "local-login-user";
static OM_uint32
-compare_names(OM_uint32 *minor,
- const gss_OID mech_type,
+mech_userok(OM_uint32 *minor,
+ const gss_union_name_t unionName,
+ const char *user,
+ int *user_ok)
+{
+ OM_uint32 major = GSS_S_UNAVAILABLE;
+ gss_mechanism mech;
+
+ /* may need to import the name if this is not MN */
+ if (unionName->mech_type == GSS_C_NO_OID)
+ return (GSS_S_FAILURE);
+
+ mech = gssint_get_mechanism(unionName->mech_type);
+ if (mech == NULL)
+ return (GSS_S_UNAVAILABLE);
+
+ if (mech->gss_userok) {
+ major = mech->gss_userok(minor, unionName->mech_name, user, user_ok);
+ if (major != GSS_S_COMPLETE)
+ map_error(minor, mech);
+ }
+
+ return (major);
+}
+
+/*
+ * Naming extensions based local login authorization.
+ */
+static OM_uint32
+attr_userok(OM_uint32 *minor,
const gss_name_t name,
const char *user,
int *user_ok)
{
+ OM_uint32 major = GSS_S_UNAVAILABLE;
+ OM_uint32 tmpMinor;
+ size_t userLen = strlen(user);
+ int more = -1;
+ gss_buffer_desc attribute;
+
+ *user_ok = 0;
+
+ attribute.length = sizeof(localLoginUserAttr) - 1;
+ attribute.value = (void *)localLoginUserAttr;
+
+ while (more != 0 && *user_ok == 0) {
+ gss_buffer_desc value;
+ gss_buffer_desc display_value;
+ int authenticated = 0, complete = 0;
+
+ major = gss_get_name_attribute(minor,
+ name,
+ &attribute,
+ &authenticated,
+ &complete,
+ &value,
+ &display_value,
+ &more);
+ if (GSS_ERROR(major))
+ break;
+
+ if (authenticated && complete &&
+ value.length == userLen &&
+ memcmp(value.value, user, userLen) == 0)
+ *user_ok = 1;
+
+ gss_release_buffer(&tmpMinor, &value);
+ gss_release_buffer(&tmpMinor, &display_value);
+ }
+
+ return (major);
+}
+
+/*
+ * Equality based local login authorization.
+ */
+static OM_uint32
+compare_names_userok(OM_uint32 *minor,
+ const gss_OID mech_type,
+ const gss_name_t name,
+ const char *user,
+ int *user_ok)
+{
OM_uint32 status, tmpMinor;
gss_name_t imported_name;
@@ -30,7 +131,9 @@ compare_names(OM_uint32 *minor,
*user_ok = 0;
gss_user.value = (void *)user;
- if (!gss_user.value || !name || !mech_type)
+ if (gss_user.value == NULL ||
+ name == GSS_C_NO_NAME ||
+ mech_type == GSS_C_NO_OID)
return (GSS_S_BAD_NAME);
gss_user.length = strlen(gss_user.value);
@@ -74,10 +177,8 @@ gss_userok(OM_uint32 *minor,
int *user_ok)
{
- gss_mechanism mech;
- gss_union_name_t intName;
- gss_name_t mechName = NULL;
OM_uint32 major;
+ gss_union_name_t unionName;
if (minor == NULL || user_ok == NULL)
return (GSS_S_CALL_INACCESSIBLE_WRITE);
@@ -86,28 +187,24 @@ gss_userok(OM_uint32 *minor,
return (GSS_S_CALL_INACCESSIBLE_READ);
*user_ok = 0;
- *minor = GSS_S_COMPLETE;
+ *minor = 0;
- intName = (gss_union_name_t)name;
+ unionName = (gss_union_name_t)name;
- /* may need to import the name if this is not MN */
- if (intName->mech_type == GSS_C_NO_OID)
- return (GSS_S_FAILURE);
- else
- mechName = intName->mech_name;
+ /* If mech returns yes, we return yes */
+ major = mech_userok(minor, unionName, user, user_ok);
+ if (major == GSS_S_COMPLETE && *user_ok)
+ return (GSS_S_COMPLETE);
- mech = gssint_get_mechanism(intName->mech_type);
- if (mech == NULL)
- return (GSS_S_UNAVAILABLE);
+ /* If attribute exists, we evaluate attribute */
+ if (attr_userok(minor, name, user, user_ok) == GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE);
- if (mech->gss_userok) {
- major = mech->gss_userok(minor, mechName,
- user, user_ok);
- if (major != GSS_S_COMPLETE)
- map_error(minor, mech);
- } else
- major = compare_names(minor, intName->mech_type,
- name, user, user_ok);
+ /* If mech returns unavail, we compare the local name */
+ if (major == GSS_S_UNAVAILABLE) {
+ major = compare_names_userok(minor, unionName->mech_type,
+ name, user, user_ok);
+ }
return (major);
} /* gss_userok */