/*
* 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.
*
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) {
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,
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,
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
#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
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);
* 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);
*
* 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;
#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,
&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;
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;
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*/
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)
(
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);
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] "
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;
}