summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGünther Deschner <gdeschner@redhat.com>2013-02-15 19:15:56 +0100
committerGünther Deschner <gd@samba.org>2013-03-22 19:28:33 +0100
commit5978b221c7d91ac04954ecc39d8ab89a5c3d0b3e (patch)
tree1da6ff047c8efe0438268a18e9aa1a0eb9ef1ea9
parent95894ff4467995659c4ce5e2523f3c8058d9c676 (diff)
downloadnfs-utils-5978b221c7d91ac04954ecc39d8ab89a5c3d0b3e.tar.gz
nfs-utils-5978b221c7d91ac04954ecc39d8ab89a5c3d0b3e.tar.xz
nfs-utils-5978b221c7d91ac04954ecc39d8ab89a5c3d0b3e.zip
Add some code to attempt to pre_aquire credentials before calling into rpcgssec.
-rw-r--r--utils/gssd/gssd_proc.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index c17ab3b..016495b 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -791,6 +791,147 @@ set_port:
return 1;
}
+static void gssd_log_failure(uint32_t level, gss_OID mech,
+ uint32_t maj, uint32_t min)
+{
+ uint32_t msgctx;
+ uint32_t discard;
+ gss_buffer_desc tmp;
+
+ printerr(level, "Failed with:");
+
+ if (mech != GSS_C_NO_OID) {
+ gss_oid_to_str(&discard, mech, &tmp);
+ printerr(level, " (OID: %s)", (char *)tmp.value);
+ gss_release_buffer(&discard, &tmp);
+ }
+
+ msgctx = 0;
+ gss_display_status(&discard, maj, GSS_C_GSS_CODE, mech, &msgctx, &tmp);
+ printerr(level, " %s,", (char *)tmp.value);
+ gss_release_buffer(&discard, &tmp);
+
+ msgctx = 0;
+ gss_display_status(&discard, min, GSS_C_MECH_CODE, mech, &msgctx, &tmp);
+ printerr(level, " %s\n", (char *)tmp.value);
+ gss_release_buffer(&discard, &tmp);
+}
+
+static OM_uint32 compose_user_principal(OM_uint32 *ret_min,
+ uid_t uid,
+ const char *realm_name,
+ gss_name_t *composed_name)
+{
+ struct passwd *pwd = NULL;
+ OM_uint32 ret_maj = GSS_S_BAD_NAME;
+ char *s;
+ gss_buffer_desc buf;
+ int ret;
+
+ pwd = getpwuid(uid);
+ if (pwd == NULL) {
+ return ret_maj;
+ }
+
+ if (realm_name == NULL) {
+ return ret_maj;
+ }
+
+ ret = asprintf(&s, "%s@%s", pwd->pw_name, realm_name);
+ if (ret == -1 || s == NULL) {
+ return ret_maj;
+ }
+
+ buf.value = (void *)s;
+ buf.length = strlen(s) + 1;
+
+ printerr(2, "FIXME: importing composed user principal: %s\n", s);
+
+ ret_maj = gss_import_name(ret_min,
+ &buf,
+ GSS_C_NT_USER_NAME,
+ composed_name);
+ free(s);
+ if (ret_maj) {
+ printerr(2, "FIXME: importing composed user principal %s failed: %d\n",
+ s, ret_maj);
+ gssd_log_failure(2, GSS_C_NO_OID, ret_maj, *ret_min);
+ }
+ return ret_maj;
+}
+
+static OM_uint32 gss_pre_aquire_credential(OM_uint32 *ret_min,
+ uid_t uid,
+ gss_cred_id_t *cred_handle)
+{
+ OM_uint32 ret_maj = 0;
+ gss_name_t desired_name = GSS_C_NO_NAME;
+ gss_OID_set desired_mechs = GSS_C_NULL_OID_SET;
+ char *default_realm = NULL;
+
+ gssd_k5_get_default_realm(&default_realm);
+
+ ret_maj = compose_user_principal(ret_min, uid, default_realm,
+ &desired_name);
+ if (ret_maj) {
+ goto failed;
+ }
+
+ ret_maj = gss_create_empty_oid_set(ret_min, &desired_mechs);
+ if (ret_maj) {
+ goto failed;
+ }
+
+ ret_maj = gss_add_oid_set_member(ret_min, (gss_OID)&krb5oid,
+ &desired_mechs);
+ if (ret_maj) {
+ goto failed;
+ }
+
+ ret_maj = gss_acquire_cred(ret_min,
+ desired_name,
+ GSS_C_INDEFINITE,
+ desired_mechs,
+ GSS_C_ACCEPT,
+ cred_handle,
+ NULL,
+ NULL);
+
+ failed:
+ if (desired_name != GSS_C_NO_NAME) {
+ gss_release_name(ret_min, &desired_name);
+ }
+ if (desired_mechs != GSS_C_NULL_OID_SET) {
+ gss_release_oid_set(ret_min, &desired_mechs);
+ }
+
+ /* FIXME: do we need to free default_realm ? guess not */
+
+ return ret_maj;
+}
+
+static gss_cred_id_t pre_aquire_credential(uid_t uid)
+{
+ OM_uint32 ret_maj = 0;
+ OM_uint32 ret_min = 0;
+ gss_cred_id_t cred_handle;
+
+ ret_maj = gss_pre_aquire_credential(&ret_min,
+ uid,
+ &cred_handle);
+ if (ret_maj) {
+ printerr(2, "FIXME: preaquire of credentials for uid %d failed: %d:%d\n",
+ uid, ret_maj, ret_min);
+ gssd_log_failure(2, GSS_C_NO_OID, ret_maj, ret_min);
+ return GSS_C_NO_CREDENTIAL;
+ }
+
+ printerr(2, "FIXME: preaquire of credentials for uid %d succeeded: %d\n",
+ uid, ret_maj);
+
+ return cred_handle;
+}
+
/*
* Create an RPC connection and establish an authenticated
* gss context with a server.