diff options
author | Simo Sorce <simo@redhat.com> | 2013-03-29 02:06:32 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2013-04-10 09:09:52 -0400 |
commit | a28a79af21adbc8267d214d3341ab1e4a46b756b (patch) | |
tree | a10b36cfe4eb89d6ea36e4170e144e368bfe8092 | |
parent | f678f9857af765d109c502229f07481a7b30c3e8 (diff) | |
download | gss-proxy-a28a79af21adbc8267d214d3341ab1e4a46b756b.tar.gz gss-proxy-a28a79af21adbc8267d214d3341ab1e4a46b756b.tar.xz gss-proxy-a28a79af21adbc8267d214d3341ab1e4a46b756b.zip |
Carefully process desired name based on service
In case the name type is GSS_C_NT_STRING_UID_NAME or GSS_NT_MACHINE_UID_NAME
we want to be able to impersonate the user referenced by the uid.
This is allowed exclusively for trusted services otherwise a generic
unprivileged application would be allowed to impersonate any user if there are
credentials available on the system or client keytabs installed.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
-rw-r--r-- | proxy/src/gp_creds.c | 45 | ||||
-rw-r--r-- | proxy/src/gp_rpc_acquire_cred.c | 28 | ||||
-rw-r--r-- | proxy/src/gp_rpc_creds.h | 2 |
3 files changed, 36 insertions, 39 deletions
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c index 9baa126..5cbb25b 100644 --- a/proxy/src/gp_creds.c +++ b/proxy/src/gp_creds.c @@ -34,6 +34,7 @@ #include "gp_proxy.h" #include "gp_rpc_creds.h" #include "gp_creds.h" +#include "gp_conv.h" #define GSS_MECH_KRB5_OID_LENGTH 9 #define GSS_MECH_KRB5_OID "\052\206\110\206\367\022\001\002\002" @@ -108,9 +109,15 @@ struct gp_service *gp_creds_match_conn(struct gssproxy_ctx *gpctx, } static char *gp_get_ccache_name(struct gp_service *svc, - gss_name_t desired_name) + gssx_name *desired_name, + gss_name_t *requested_name) { + gss_name_t name = GSS_C_NO_NAME; + gss_OID_desc name_type; + uint32_t ret_maj = 0; + uint32_t ret_min = 0; char buffer[2048]; + uid_t target_uid; struct passwd pwd, *res = NULL; char *ccache; char *tmp; @@ -118,13 +125,26 @@ static char *gp_get_ccache_name(struct gp_service *svc, int len, left, right; int ret; - if (svc->krb5.ccache == NULL) { - ret = getpwuid_r(svc->euid, &pwd, buffer, 2048, &res); - if (ret || !res) { - return NULL; + target_uid = svc->euid; + + if (desired_name) { + gp_conv_gssx_to_oid(&desired_name->name_type, &name_type); + + if (svc->trusted && + (gss_oid_equal(&name_type, GSS_C_NT_STRING_UID_NAME) || + gss_oid_equal(&name_type, GSS_C_NT_MACHINE_UID_NAME))) { + target_uid = atol(desired_name->display_name.octet_string_val); + } else { + ret_maj = gp_conv_gssx_to_name(&ret_min, desired_name, &name); + if (ret_maj) { + goto done; + } + *requested_name = name; } + } - ret = asprintf(&ccache, "%s/krb5cc_%s", CCACHE_PATH, pwd.pw_name); + if (svc->krb5.ccache == NULL) { + ret = asprintf(&ccache, "%s/krb5cc_%u", CCACHE_PATH, target_uid); if (ret == -1) { ccache = NULL; goto done; @@ -152,7 +172,7 @@ static char *gp_get_ccache_name(struct gp_service *svc, p++; left = p - ccache; right = len - left; - len = asprintf(&tmp, "%.*s%d%s", left - 2, ccache, svc->euid, p); + len = asprintf(&tmp, "%.*s%d%s", left - 2, ccache, target_uid, p); safefree(ccache); if (len == -1) { goto done; @@ -162,7 +182,7 @@ static char *gp_get_ccache_name(struct gp_service *svc, break; case 'u': if (!res) { - ret = getpwuid_r(svc->euid, &pwd, buffer, 2048, &res); + ret = getpwuid_r(target_uid, &pwd, buffer, 2048, &res); if (ret || !res) { safefree(ccache); goto done; @@ -196,7 +216,7 @@ done: uint32_t gp_add_krb5_creds(uint32_t *min, struct gp_service *svc, gss_cred_id_t in_cred, - gss_name_t desired_name, + gssx_name *desired_name, gss_cred_usage_t cred_usage, uint32_t initiator_time_req, uint32_t acceptor_time_req, @@ -214,6 +234,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min, uint32_t ret_maj = 0; uint32_t ret_min = 0; uint32_t discard; + gss_name_t req_name = GSS_C_NO_NAME; if (!min || !output_cred_handle) { return GSS_S_CALL_INACCESSIBLE_WRITE; @@ -245,7 +266,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min, } if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_INITIATE) { - ccache_name = gp_get_ccache_name(svc, desired_name); + ccache_name = gp_get_ccache_name(svc, desired_name, &req_name); if (!ccache_name) { ret_maj = GSS_S_CRED_UNAVAIL; goto done; @@ -261,10 +282,6 @@ uint32_t gp_add_krb5_creds(uint32_t *min, /* FIXME: initiate ? */ } - if (desired_name) { - /* FIXME: resolve principal name */ - } - if (svc->krb5.keytab) { kerr = krb5_kt_resolve(kctx, svc->krb5.keytab, &keytab); if (kerr != 0) { diff --git a/proxy/src/gp_rpc_acquire_cred.c b/proxy/src/gp_rpc_acquire_cred.c index 3dffc8c..c5bf1a2 100644 --- a/proxy/src/gp_rpc_acquire_cred.c +++ b/proxy/src/gp_rpc_acquire_cred.c @@ -36,7 +36,6 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx, uint32_t ret_maj; uint32_t ret_min; gss_cred_id_t in_cred = GSS_C_NO_CREDENTIAL; - gss_name_t desired_name = GSS_C_NO_NAME; gss_OID_set desired_mechs = GSS_C_NO_OID_SET; gss_OID_set use_mechs = GSS_C_NO_OID_SET; gss_OID desired_mech = GSS_C_NO_OID; @@ -63,14 +62,6 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx, add_out_cred = &out_cred; } - if (aca->desired_name) { - ret_maj = gp_conv_gssx_to_name(&ret_min, - aca->desired_name, &desired_name); - if (ret_maj) { - goto done; - } - } - ret = gp_conv_gssx_to_oid_set(&aca->desired_mechs, &desired_mechs); if (ret) { ret_maj = GSS_S_FAILURE; @@ -125,7 +116,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx, ret_maj = gp_add_krb5_creds(&ret_min, gpsvc, in_cred, - desired_name, + aca->desired_name, cred_usage, aca->initiator_time_req, aca->acceptor_time_req, @@ -137,20 +128,9 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx, goto done; } } else { - ret_maj = gss_add_cred(&ret_min, - in_cred, - desired_name, - desired_mech, - cred_usage, - aca->initiator_time_req, - aca->acceptor_time_req, - add_out_cred, - NULL, - NULL, - NULL); - if (ret_maj) { - goto done; - } + /* we support only the krb5 mech for now */ + ret_maj = GSS_S_BAD_MECH; + goto done; } } diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h index 2c0aea5..50e3392 100644 --- a/proxy/src/gp_rpc_creds.h +++ b/proxy/src/gp_rpc_creds.h @@ -39,7 +39,7 @@ uint32_t gp_get_supported_mechs(uint32_t *min, uint32_t gp_add_krb5_creds(uint32_t *min, struct gp_service *svc, gss_cred_id_t in_cred, - gss_name_t desired_name, + gssx_name *desired_name, gss_cred_usage_t cred_usage, uint32_t initiator_time_req, uint32_t acceptor_time_req, |