summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobbie Harwood (frozencemetery) <rharwood@redhat.com>2015-08-25 14:10:37 -0400
committerSimo Sorce <simo@redhat.com>2015-09-04 14:25:09 -0400
commitf2385558dd9542ca0a88f3386aa5833a23e5eb8b (patch)
treefbacdf78d30d92cbf752439cc2d9d200f225bfab
parent9f1a8a8777ae144ccf34c6406e9bc8fa930e0047 (diff)
downloadgss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.tar.gz
gss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.tar.xz
gss-proxy-f2385558dd9542ca0a88f3386aa5833a23e5eb8b.zip
Add support for config directories
Option '-C|--configdir' has been added, and defaults to /etc/gssproxy. File "gssproxy.conf" and all files of the form "##-foo.conf" will be read from that directory. Ticket: https://fedorahosted.org/gss-proxy/ticket/122 Signed-off-by: Robbie Harwood <rharwood@redhat.com> Reviewed-by: Simo Sorce <simo@redhat.com>
-rw-r--r--proxy/src/gp_config.c154
-rw-r--r--proxy/src/gp_config.h2
-rw-r--r--proxy/src/gp_proxy.h5
-rw-r--r--proxy/src/gssproxy.c11
4 files changed, 142 insertions, 30 deletions
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
index 2812e88..61e32b8 100644
--- a/proxy/src/gp_config.c
+++ b/proxy/src/gp_config.c
@@ -427,6 +427,7 @@ done:
}
static int gp_init_ini_context(const char *config_file,
+ const char *config_dir,
struct gp_ini_context **ctxp)
{
struct gp_ini_context *ctx;
@@ -441,7 +442,7 @@ static int gp_init_ini_context(const char *config_file,
return ENOENT;
}
- ret = gp_config_init(config_file, ctx);
+ ret = gp_config_init(config_file, config_dir, ctx);
if (ret) {
free(ctx);
@@ -457,7 +458,7 @@ int load_config(struct gp_config *cfg)
const char *tmpstr;
int ret;
- ret = gp_init_ini_context(cfg->config_file, &ctx);
+ ret = gp_init_ini_context(cfg->config_file, cfg->config_dir, &ctx);
if (ret) {
return ret;
}
@@ -499,10 +500,11 @@ done:
return ret;
}
-struct gp_config *read_config(char *config_file, char *socket_name,
- int opt_daemonize)
+struct gp_config *read_config(char *config_file, char *config_dir,
+ char *socket_name, int opt_daemonize)
{
const char *socket = GP_SOCKET_NAME;
+ const char *dir = PUBCONF_PATH;
struct gp_config *cfg;
int ret;
@@ -514,17 +516,24 @@ struct gp_config *read_config(char *config_file, char *socket_name,
if (config_file) {
cfg->config_file = strdup(config_file);
if (!cfg->config_file) {
- free(cfg);
- return NULL;
+ ret = ENOMEM;
+ goto done;
}
} else {
ret = asprintf(&cfg->config_file, "%s/gssproxy.conf", PUBCONF_PATH);
if (ret == -1) {
- free(cfg);
- return NULL;
+ goto done;
}
}
+ if (config_dir) dir = config_dir;
+
+ cfg->config_dir = strdup(dir);
+ if (!cfg->config_dir) {
+ ret = ENOMEM;
+ goto done;
+ }
+
if (socket_name) socket = socket_name;
cfg->socket_name = strdup(socket);
@@ -546,12 +555,14 @@ struct gp_config *read_config(char *config_file, char *socket_name,
ret = load_config(cfg);
if (ret) {
- GPDEBUG("Config file not found!\n");
+ GPDEBUG("Config file(s) not found!\n");
}
done:
if (ret) {
+ /* recursively frees cfg */
free_config(&cfg);
+ return NULL;
}
return cfg;
@@ -585,45 +596,34 @@ void free_config(struct gp_config **cfg)
*cfg = NULL;
}
-int gp_config_init(const char *config_file,
- struct gp_ini_context *ctx)
+static int gp_config_from_file(const char *config_file,
+ struct gp_ini_context *ctx,
+ struct ini_cfgobj *ini_config,
+ const uint32_t collision_flags)
{
- struct ini_cfgobj *ini_config = NULL;
struct ini_cfgfile *file_ctx = NULL;
int ret;
- if (!ctx) {
- return EINVAL;
- }
-
- ret = ini_config_create(&ini_config);
- if (ret) {
- return ENOENT;
- }
-
ret = ini_config_file_open(config_file,
0, /* metadata_flags, FIXME */
&file_ctx);
if (ret) {
GPDEBUG("Failed to open config file: %d (%s)\n",
- ret, gp_strerror(ret));
+ ret, gp_strerror(ret));
ini_config_destroy(ini_config);
return ret;
}
ret = ini_config_parse(file_ctx,
INI_STOP_ON_ANY, /* error_level */
- /* Merge section but allow duplicates */
- INI_MS_MERGE |
- INI_MV1S_ALLOW |
- INI_MV2S_ALLOW,
+ collision_flags,
INI_PARSE_NOWRAP, /* parse_flags */
ini_config);
if (ret) {
char **errors = NULL;
/* we had a parsing failure */
GPDEBUG("Failed to parse config file: %d (%s)\n",
- ret, gp_strerror(ret));
+ ret, gp_strerror(ret));
if (ini_config_error_count(ini_config)) {
ini_config_get_errors(ini_config, &errors);
if (errors) {
@@ -637,6 +637,106 @@ int gp_config_init(const char *config_file,
}
ini_config_file_destroy(file_ctx);
+ return 0;
+}
+
+static int gp_config_from_dir(const char *config_dir,
+ struct gp_ini_context *ctx,
+ struct ini_cfgobj **ini_config,
+ const uint32_t collision_flags)
+{
+ struct ini_cfgobj *result_cfg = NULL;
+ struct ref_array *error_list = NULL;
+ int ret;
+
+ const char *patterns[] = {
+ /* match only files starting with "##-" and ending in ".conf" */
+ "^[0-9]\\{2\\}-.\\{1,\\}\\.conf$",
+ NULL,
+ };
+
+ const char *sections[] = {
+ /* match either "gssproxy" or sections that start with "service/" */
+ "^gssproxy$",
+ "^service/.*$",
+ NULL,
+ };
+
+ /* Permission check failures silently skip the file, so they are not
+ * useful to us. */
+ ret = ini_config_augment(*ini_config,
+ config_dir,
+ patterns,
+ sections,
+ NULL, /* check_perm */
+ INI_STOP_ON_ANY, /* error_level */
+ collision_flags,
+ INI_PARSE_NOWRAP,
+ /* do not allow colliding sections with the same
+ * name in different files */
+ INI_MS_ERROR,
+ &result_cfg,
+ &error_list,
+ NULL);
+ if (ret) {
+ if (error_list) {
+ uint32_t i;
+ uint32_t len = ref_array_getlen(error_list, &i);
+ for (i = 0; i < len; i++) {
+ GPDEBUG("Error when reading config directory: %s\n",
+ (const char *) ref_array_get(error_list, i, NULL));
+ }
+ ref_array_destroy(error_list);
+ } else {
+ GPDEBUG("Error when reading config directory number: %d\n", ret);
+ }
+ return ret;
+ }
+
+ /* if we read no new files, result_cfg will be NULL */
+ if (result_cfg) {
+ ini_config_destroy(*ini_config);
+ *ini_config = result_cfg;
+ }
+ return 0;
+}
+
+int gp_config_init(const char *config_file, const char *config_dir,
+ struct gp_ini_context *ctx)
+{
+ struct ini_cfgobj *ini_config = NULL;
+ int ret;
+
+ /* Within a single file, merge all collisions */
+ const uint32_t collision_flags =
+ INI_MS_MERGE | INI_MV1S_ALLOW | INI_MV2S_ALLOW;
+
+ if (!ctx) {
+ return EINVAL;
+ }
+
+ ret = ini_config_create(&ini_config);
+ if (ret) {
+ return ENOENT;
+ }
+
+ if (config_file) {
+ ret = gp_config_from_file(config_file, ctx, ini_config,
+ collision_flags);
+ if (ret == ENOENT) {
+ GPDEBUG("Expected config file %s but did not find it.\n",
+ config_file);
+ } else if (ret) {
+ return ret;
+ }
+ }
+ if (config_dir) {
+ ret = gp_config_from_dir(config_dir, ctx, &ini_config,
+ collision_flags);
+ if (ret) {
+ return ret;
+ }
+ }
ctx->private_data = ini_config;
diff --git a/proxy/src/gp_config.h b/proxy/src/gp_config.h
index 9d0d1d7..1bc756c 100644
--- a/proxy/src/gp_config.h
+++ b/proxy/src/gp_config.h
@@ -31,7 +31,7 @@ struct gp_ini_context {
void *private_data;
};
-int gp_config_init(const char *config_file,
+int gp_config_init(const char *config_file, const char *config_dir,
struct gp_ini_context *ctx);
int gp_config_get_string(struct gp_ini_context *ctx,
const char *secname,
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index 68c724c..72bbc5c 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -68,6 +68,7 @@ struct gp_service {
struct gp_config {
char *config_file; /* gssproxy configuration file */
+ char *config_dir; /* gssproxy configuration directory */
bool daemonize; /* let gssproxy daemonize */
char *socket_name; /* the socket name to use for */
int num_workers; /* number of worker threads */
@@ -101,8 +102,8 @@ struct gp_call_ctx {
};
/* from gp_config.c */
-struct gp_config *read_config(char *config_file, char *socket_name,
- int opt_daemonize);
+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);
diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c
index 354d595..0e84859 100644
--- a/proxy/src/gssproxy.c
+++ b/proxy/src/gssproxy.c
@@ -36,6 +36,7 @@ int main(int argc, const char *argv[])
int opt_interactive = 0;
int opt_version = 0;
char *opt_config_file = NULL;
+ char *opt_config_dir = NULL;
char *opt_config_socket = NULL;
int opt_debug = 0;
verto_ctx *vctx;
@@ -55,6 +56,8 @@ int main(int argc, const char *argv[])
_("Run interactive (not a daemon)"), NULL}, \
{"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \
_("Specify a non-default config file"), NULL}, \
+ {"configdir", 'C', POPT_ARG_STRING, &opt_config_dir, 0, \
+ _("Specify a non-default config directory"), NULL}, \
{"socket", 's', POPT_ARG_STRING, &opt_config_socket, 0, \
_("Specify a custom default socket"), NULL}, \
{"debug", 'd', POPT_ARG_NONE, &opt_debug, 0, \
@@ -90,6 +93,13 @@ int main(int argc, const char *argv[])
return 1;
}
+ if (opt_config_file && opt_config_dir) {
+ fprintf(stderr, "Option -C|--configdir is not allowed together with"
+ " -c|--config\n");
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+
if (opt_interactive) {
opt_daemon = 2;
}
@@ -97,6 +107,7 @@ int main(int argc, const char *argv[])
gpctx = calloc(1, sizeof(struct gssproxy_ctx));
gpctx->config = read_config(opt_config_file,
+ opt_config_dir,
opt_config_socket,
opt_daemon);
if (!gpctx->config) {