summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proxy/src/gp_config.c69
-rw-r--r--proxy/src/gp_creds.c46
-rw-r--r--proxy/src/gp_proxy.h5
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);