diff options
author | Günther Deschner <gdeschner@redhat.com> | 2013-02-15 19:15:56 +0100 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2013-03-22 19:28:33 +0100 |
commit | 5978b221c7d91ac04954ecc39d8ab89a5c3d0b3e (patch) | |
tree | 1da6ff047c8efe0438268a18e9aa1a0eb9ef1ea9 | |
parent | 95894ff4467995659c4ce5e2523f3c8058d9c676 (diff) | |
download | nfs-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.c | 141 |
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. |