diff options
-rw-r--r-- | proxy/src/gp_config.c | 69 | ||||
-rw-r--r-- | proxy/src/gp_creds.c | 46 | ||||
-rw-r--r-- | proxy/src/gp_proxy.h | 5 |
3 files changed, 73 insertions, 47 deletions
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index dfc7800..42ab973 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -55,13 +55,26 @@ static void free_str_array(const char ***a, int *count) safefree(*a); } +void free_cred_store_elements(gss_key_value_set_desc *cs) +{ + int i; + + if (!cs->elements) return; + + for (i = 0; i < cs->count; i++) { + safefree(cs->elements[i].key); + safefree(cs->elements[i].value); + } + safefree(cs->elements); + cs->count = 0; +} + static void gp_service_free(struct gp_service *svc) { free(svc->name); if (svc->mechs & GP_CRED_KRB5) { free(svc->krb5.principal); - free_str_array(&(svc->krb5.cred_store), - &svc->krb5.cred_count); + free_cred_store_elements(&svc->krb5.store); gp_free_creds_handle(&svc->krb5.creds_handle); } SELINUX_context_free(svc->selinux_ctx); @@ -73,9 +86,9 @@ static int setup_krb5_creds_handle(struct gp_service *svc) uint32_t ret_maj, ret_min; const char *keytab = NULL; - for (unsigned i = 0; i < svc->krb5.cred_count; i++) { - if (strncmp(svc->krb5.cred_store[i], "keytab:", 7) == 0) { - keytab = svc->krb5.cred_store[i] + 7; + for (unsigned i = 0; i < svc->krb5.store.count; i++) { + if (strcmp(svc->krb5.store.elements[i].key, "keytab") == 0) { + keytab = svc->krb5.store.elements[i].value; break; } } @@ -99,6 +112,8 @@ static int get_krb5_mech_cfg(struct gp_service *svc, {"krb5_client_keytab", "client_keytab" } }; const char *value; + const char **strings = NULL; + int count = 0; int i; int ret; @@ -127,11 +142,43 @@ static int get_krb5_mech_cfg(struct gp_service *svc, } /* instead look for the cred_store parameter */ - ret = gp_config_get_string_array(ctx, secname, - "cred_store", - &svc->krb5.cred_count, - &svc->krb5.cred_store); - if (ret == ENOENT) { + ret = gp_config_get_string_array(ctx, secname, "cred_store", + &count, &strings); + if (ret == 0) { + const char *p; + size_t len; + char *key; + + svc->krb5.store.elements = + calloc(count, sizeof(gss_key_value_element_desc)); + if (!svc->krb5.store.elements) { + ret = ENOMEM; + goto done; + } + svc->krb5.store.count = count; + + for (int c = 0; c < count; c++) { + p = strchr(strings[c], ':'); + if (!p) { + GPERROR("Invalid cred_store value, no ':' separator found in" + " [%s].\n", strings[c]); + ret = EINVAL; + goto done; + } + len = asprintf(&key, "%.*s", (int)(p - strings[c]), strings[c]); + if (len == -1) { + ret = ENOMEM; + goto done; + } + svc->krb5.store.elements[c].key = key; + svc->krb5.store.elements[c].value = strdup(p + 1); + if (!svc->krb5.store.elements[c].value) { + ret = ENOMEM; + goto done; + } + } + + } else if (ret == ENOENT) { /* when not there we ignore */ ret = 0; } @@ -140,6 +187,8 @@ static int get_krb5_mech_cfg(struct gp_service *svc, ret = setup_krb5_creds_handle(svc); } +done: + free_str_array(&strings, &count); return ret; } diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c index 8280ef2..05ec659 100644 --- a/proxy/src/gp_creds.c +++ b/proxy/src/gp_creds.c @@ -181,17 +181,6 @@ done: return str; } -static void free_cred_store_elements(gss_key_value_set_desc *cs) -{ - int i; - - for (i = 0; i < cs->count; i++) { - safefree(cs->elements[i].key); - safefree(cs->elements[i].value); - } - safefree(cs->elements); -} - int gp_get_acquire_type(struct gssx_arg_acquire_cred *arg) { struct gssx_option *val = NULL; @@ -240,9 +229,6 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall, uint32_t ret_maj = 0; uint32_t ret_min = 0; uid_t target_uid; - const char *fmtstr; - const char *p; - char *str; bool user_requested = false; bool use_service_keytab = false; int ret = -1; @@ -301,6 +287,7 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall, /* impersonation case (only for initiation) */ if (user_requested) { if (try_impersonate(svc, *cred_usage, ACQ_NORMAL)) { + char *str; /* When impersonating we want to use the service keytab to * acquire initial credential ... */ use_service_keytab = true; @@ -342,47 +329,36 @@ static int gp_get_cred_environment(struct gp_call_ctx *gpcall, } } - if (svc->krb5.cred_store == NULL) { + if (svc->krb5.store.count == 0) { return 0; } /* allocate 1 more than in source, just in case we need to add * an internal client_keytab element */ - cs->elements = calloc(svc->krb5.cred_count + 1, + cs->elements = calloc(svc->krb5.store.count + 1, sizeof(gss_key_value_element_desc)); if (!cs->elements) { ret = ENOMEM; goto done; } - for (d = 0; d < svc->krb5.cred_count; d++) { - p = strchr(svc->krb5.cred_store[d], ':'); - if (!p) { - GPERROR("Invalid cred_store value" - "no ':' separator found in [%s].\n", - svc->krb5.cred_store[d]); - ret = EINVAL; - goto done; - } - - if (strncmp(svc->krb5.cred_store[d], "client_keytab:", 14) == 0) { + for (d = 0; d < svc->krb5.store.count; d++) { + if (strcmp(svc->krb5.store.elements[d].key, "client_keytab") == 0) { ck_num = cs->count; - } else if (strncmp(svc->krb5.cred_store[d], "keytab:", 7) == 0) { + } else if (strcmp(svc->krb5.store.elements[d].key, "keytab") == 0) { k_num = cs->count; } - ret = asprintf(&str, "%.*s", (int)(p - svc->krb5.cred_store[d]), - svc->krb5.cred_store[d]); - if (ret == -1) { + cs->elements[cs->count].key = strdup(svc->krb5.store.elements[d].key); + if (!cs->elements[cs->count].key) { ret = ENOMEM; goto done; } - cs->elements[cs->count].key = str; - fmtstr = p + 1; cs->elements[cs->count].value = - get_formatted_string(fmtstr, target_uid); + get_formatted_string(svc->krb5.store.elements[d].value, + target_uid); if (!cs->elements[cs->count].value) { - safefree(str); + safefree(cs->elements[cs->count].key); GPDEBUG("Failed to build credential store formatted string.\n"); ret = ENOMEM; goto done; diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index c7f4bb2..abcd201 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -6,6 +6,7 @@ #include <libintl.h> #include <stdbool.h> #include <stdint.h> +#include <gssapi/gssapi_ext.h> #include "verto.h" #include "gp_common.h" #include "gp_selinux.h" @@ -21,8 +22,7 @@ struct gp_creds_handle; struct gp_cred_krb5 { char *principal; - const char **cred_store; - int cred_count; + gss_key_value_set_desc store; struct gp_creds_handle *creds_handle; }; @@ -86,6 +86,7 @@ struct gp_config *read_config(char *config_file, char *config_dir, char *socket_name, int opt_daemonize); struct gp_creds_handle *gp_service_get_creds_handle(struct gp_service *svc); void free_config(struct gp_config **config); +void free_cred_store_elements(gss_key_value_set_desc *cs); /* from gp_init.c */ void init_server(bool daemonize, int *wait_fd); |