|
Packit Service |
9f2c4a |
/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
#include "config.h"
|
|
Packit Service |
9f2c4a |
#include <stdio.h>
|
|
Packit Service |
9f2c4a |
#include <stdlib.h>
|
|
Packit Service |
9f2c4a |
#include <string.h>
|
|
Packit Service |
9f2c4a |
#include <errno.h>
|
|
Packit Service |
9f2c4a |
#include <pwd.h>
|
|
Packit Service |
9f2c4a |
#include "gp_proxy.h"
|
|
Packit Service |
9f2c4a |
#include "gp_config.h"
|
|
Packit Service |
9f2c4a |
#include "gp_selinux.h"
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
#include <gssapi/gssapi.h>
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
#include <ini_configobj.h>
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
struct gp_flag_def {
|
|
Packit Service |
9f2c4a |
const char *name;
|
|
Packit Service |
9f2c4a |
uint32_t value;
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
struct gp_flag_def flag_names[] = {
|
|
Packit Service |
9f2c4a |
{ "DELEGATE", GSS_C_DELEG_FLAG },
|
|
Packit Service |
9f2c4a |
{ "MUTUAL_AUTH", GSS_C_MUTUAL_FLAG },
|
|
Packit Service |
9f2c4a |
{ "REPLAY_DETECT", GSS_C_REPLAY_FLAG },
|
|
Packit Service |
9f2c4a |
{ "SEQUENCE", GSS_C_SEQUENCE_FLAG },
|
|
Packit Service |
9f2c4a |
{ "CONFIDENTIALITY", GSS_C_CONF_FLAG },
|
|
Packit Service |
9f2c4a |
{ "INTEGRITIY", GSS_C_INTEG_FLAG },
|
|
Packit Service |
9f2c4a |
{ "ANONYMOUS", GSS_C_ANON_FLAG },
|
|
Packit Service |
9f2c4a |
{ NULL, 0 }
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
#define DEFAULT_FILTERED_FLAGS GSS_C_DELEG_FLAG
|
|
Packit Service |
9f2c4a |
#define DEFAULT_ENFORCED_FLAGS 0
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static void free_str_array(const char ***a, int *count)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
const char **array;
|
|
Packit Service |
9f2c4a |
int i;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!a) {
|
|
Packit Service |
9f2c4a |
return;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
array = *a;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (count) {
|
|
Packit Service |
9f2c4a |
for (i = 0; i < *count; i++) {
|
|
Packit Service |
9f2c4a |
safefree(array[i]);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
for (i = 0; array[i]; i++) {
|
|
Packit Service |
9f2c4a |
safefree(array[i]);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
safefree(*a);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
void free_cred_store_elements(gss_key_value_set_desc *cs)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
if (!cs->elements) return;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (unsigned i = 0; i < cs->count; i++) {
|
|
Packit Service |
9f2c4a |
safefree(cs->elements[i].key);
|
|
Packit Service |
9f2c4a |
safefree(cs->elements[i].value);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
safefree(cs->elements);
|
|
Packit Service |
9f2c4a |
cs->count = 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static void gp_service_free(struct gp_service *svc)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
free(svc->name);
|
|
Packit Service |
9f2c4a |
if (svc->mechs & GP_CRED_KRB5) {
|
|
Packit Service |
9f2c4a |
free(svc->krb5.principal);
|
|
Packit Service |
9f2c4a |
free_cred_store_elements(&svc->krb5.store);
|
|
Packit Service |
9f2c4a |
gp_free_creds_handle(&svc->krb5.creds_handle);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
free(svc->socket);
|
|
Packit Service |
9f2c4a |
free(svc->program);
|
|
Packit Service |
9f2c4a |
SELINUX_context_free(svc->selinux_ctx);
|
|
Packit Service |
9f2c4a |
memset(svc, 0, sizeof(struct gp_service));
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int setup_krb5_creds_handle(struct gp_service *svc)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
uint32_t ret_maj, ret_min;
|
|
Packit Service |
9f2c4a |
const char *keytab = NULL;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (unsigned i = 0; i < svc->krb5.store.count; i++) {
|
|
Packit Service |
9f2c4a |
if (strcmp(svc->krb5.store.elements[i].key, "keytab") == 0) {
|
|
Packit Service |
9f2c4a |
keytab = svc->krb5.store.elements[i].value;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret_maj = gp_init_creds_handle(&ret_min, svc->name, keytab,
|
|
Packit Service |
9f2c4a |
&svc->krb5.creds_handle);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
return ret_min;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int get_krb5_mech_cfg(struct gp_service *svc,
|
|
Packit Service |
9f2c4a |
struct gp_ini_context *ctx,
|
|
Packit Service |
9f2c4a |
const char *secname)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct { const char *a; const char *b; } deprecated_vals[] = {
|
|
Packit Service |
9f2c4a |
{"krb5_keytab", "keytab" },
|
|
Packit Service |
9f2c4a |
{"krb5_ccache", "ccache" },
|
|
Packit Service |
9f2c4a |
{"krb5_client_keytab", "client_keytab" }
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
const char *value;
|
|
Packit Service |
9f2c4a |
const char **strings = NULL;
|
|
Packit Service |
9f2c4a |
int count = 0;
|
|
Packit Service |
9f2c4a |
int i;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "krb5_principal", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
svc->krb5.principal = strdup(value);
|
|
Packit Service |
9f2c4a |
if (!svc->krb5.principal) {
|
|
Packit Service |
9f2c4a |
return ENOMEM;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else if (ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* check for deprecated options */
|
|
Packit Service |
9f2c4a |
for (i = 0; i < 3; i++) {
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, deprecated_vals[i].a, &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
GPERROR("\"%s = %s\" is deprecated, "
|
|
Packit Service |
9f2c4a |
"please use \"cred_store = %s:%s\"\n",
|
|
Packit Service |
9f2c4a |
deprecated_vals[i].a, value,
|
|
Packit Service |
9f2c4a |
deprecated_vals[i].b, value);
|
|
Packit Service |
9f2c4a |
return EINVAL;
|
|
Packit Service |
9f2c4a |
} else if (ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* instead look for the cred_store parameter */
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string_array(ctx, secname, "cred_store",
|
|
Packit Service |
9f2c4a |
&count, &strings);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
const char *p;
|
|
Packit Service |
9f2c4a |
ssize_t len;
|
|
Packit Service |
9f2c4a |
char *key;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
svc->krb5.store.elements =
|
|
Packit Service |
9f2c4a |
calloc(count, sizeof(gss_key_value_element_desc));
|
|
Packit Service |
9f2c4a |
if (!svc->krb5.store.elements) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
svc->krb5.store.count = count;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (int c = 0; c < count; c++) {
|
|
Packit Service |
9f2c4a |
p = strchr(strings[c], ':');
|
|
Packit Service |
9f2c4a |
if (!p) {
|
|
Packit Service |
9f2c4a |
GPERROR("Invalid cred_store value, no ':' separator found in"
|
|
Packit Service |
9f2c4a |
" [%s].\n", strings[c]);
|
|
Packit Service |
9f2c4a |
ret = EINVAL;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
len = asprintf(&key, "%.*s", (int)(p - strings[c]), strings[c]);
|
|
Packit Service |
9f2c4a |
if (len == -1) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
svc->krb5.store.elements[c].key = key;
|
|
Packit Service |
9f2c4a |
svc->krb5.store.elements[c].value = strdup(p + 1);
|
|
Packit Service |
9f2c4a |
if (!svc->krb5.store.elements[c].value) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
} else if (ret == ENOENT) {
|
|
Packit Service |
9f2c4a |
/* when not there we ignore */
|
|
Packit Service |
9f2c4a |
ret = 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
ret = setup_krb5_creds_handle(svc);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
free_str_array(&strings, &count);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int parse_flags(const char *value, uint32_t *storage)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
char *handle;
|
|
Packit Service |
9f2c4a |
char *token;
|
|
Packit Service |
9f2c4a |
char *str;
|
|
Packit Service |
9f2c4a |
bool add;
|
|
Packit Service |
9f2c4a |
unsigned long int conv;
|
|
Packit Service |
9f2c4a |
uint32_t flagval;
|
|
Packit Service |
9f2c4a |
int i;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
str = strdup(value);
|
|
Packit Service |
9f2c4a |
if (!str) {
|
|
Packit Service |
9f2c4a |
return ENOMEM;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (token = strtok_r(str, ", ", &handle);
|
|
Packit Service |
9f2c4a |
token != NULL;
|
|
Packit Service |
9f2c4a |
token = strtok_r(NULL, ", ", &handle)) {
|
|
Packit Service |
9f2c4a |
switch (token[0]) {
|
|
Packit Service |
9f2c4a |
case '+':
|
|
Packit Service |
9f2c4a |
add = true;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
case '-':
|
|
Packit Service |
9f2c4a |
add = false;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
default:
|
|
Packit Service |
9f2c4a |
GPERROR("Ignoring flag [%s], missing +/- qualifier.\n", token);
|
|
Packit Service |
9f2c4a |
continue;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
token++;
|
|
Packit Service |
9f2c4a |
for (i = 0; flag_names[i].name != NULL; i++) {
|
|
Packit Service |
9f2c4a |
if (strcasecmp(token, flag_names[i].name) == 0) {
|
|
Packit Service |
9f2c4a |
flagval = flag_names[i].value;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (flag_names[i].name == NULL) {
|
|
Packit Service |
9f2c4a |
conv = strtoul(token, &handle, 0);
|
|
Packit Service |
9f2c4a |
if (conv == 0 || conv == ULONG_MAX || *handle != '\0') {
|
|
Packit Service |
9f2c4a |
GPERROR("Ignoring flag [%s], unrecognized value.\n", token);
|
|
Packit Service |
9f2c4a |
continue;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
flagval = conv;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
GPDEBUG("%s Flag %s (%u).\n", add?"Add":"Remove", token, flagval);
|
|
Packit Service |
9f2c4a |
if (add) *storage |= flagval;
|
|
Packit Service |
9f2c4a |
else *storage &= ~flagval;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
safefree(str);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int check_services(const struct gp_config *cfg)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
int i, j;
|
|
Packit Service |
9f2c4a |
struct gp_service *isvc, *jsvc;
|
|
Packit Service |
9f2c4a |
const char *isock, *jsock;
|
|
Packit Service |
9f2c4a |
int ret = 0;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* [gssproxy] section does not get placed in svcs */
|
|
Packit Service |
9f2c4a |
for (i = 0; i < cfg->num_svcs; i++) {
|
|
Packit Service |
9f2c4a |
isvc = cfg->svcs[i];
|
|
Packit Service |
9f2c4a |
isock = isvc->socket;
|
|
Packit Service |
9f2c4a |
if (!isock) {
|
|
Packit Service |
9f2c4a |
isock = GP_SOCKET_NAME;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (isvc->program) {
|
|
Packit Service |
9f2c4a |
if (isvc->program[0] != '/') {
|
|
Packit Service |
9f2c4a |
ret = 1;
|
|
Packit Service |
9f2c4a |
GPERROR("Program paths must be absolute!\n");
|
|
Packit Service |
9f2c4a |
} else if (strchr(isvc->program, '|')) {
|
|
Packit Service |
9f2c4a |
ret = 1;
|
|
Packit Service |
9f2c4a |
GPERROR("The character '|' is invalid in program paths!\n");
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (j = 0; j < i; j++) {
|
|
Packit Service |
9f2c4a |
jsvc = cfg->svcs[j];
|
|
Packit Service |
9f2c4a |
jsock = jsvc->socket;
|
|
Packit Service |
9f2c4a |
if (!jsock) {
|
|
Packit Service |
9f2c4a |
jsock = GP_SOCKET_NAME;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!gp_same(isock, jsock) ||
|
|
Packit Service |
9f2c4a |
!gp_same(isvc->program, jsvc->program) ||
|
|
Packit Service |
9f2c4a |
!gp_selinux_ctx_equal(isvc->selinux_ctx, jsvc->selinux_ctx)) {
|
|
Packit Service |
9f2c4a |
continue;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (jsvc->any_uid) {
|
|
Packit Service |
9f2c4a |
ret = 1;
|
|
Packit Service |
9f2c4a |
GPERROR("%s sets allow_any_uid with the same socket, "
|
|
Packit Service |
9f2c4a |
"selinux_context, and program as %s!\n",
|
|
Packit Service |
9f2c4a |
jsvc->name, isvc->name);
|
|
Packit Service |
9f2c4a |
} else if (jsvc->euid == isvc->euid) {
|
|
Packit Service |
9f2c4a |
ret = 1;
|
|
Packit Service |
9f2c4a |
GPERROR("socket, selinux_context, euid, and program for "
|
|
Packit Service |
9f2c4a |
"%s and %s should not match!\n",
|
|
Packit Service |
9f2c4a |
isvc->name, jsvc->name);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
int num_sec;
|
|
Packit Service |
9f2c4a |
char *secname = NULL;
|
|
Packit Service |
9f2c4a |
const char *value;
|
|
Packit Service |
9f2c4a |
char *vcopy;
|
|
Packit Service |
9f2c4a |
char *token;
|
|
Packit Service |
9f2c4a |
char *handle;
|
|
Packit Service |
9f2c4a |
int valnum;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
int i, n;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
num_sec = gp_config_get_nsec(ctx);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* allocate enough space for num_sec services,
|
|
Packit Service |
9f2c4a |
* we won't waste too much space by overallocating */
|
|
Packit Service |
9f2c4a |
cfg->svcs = calloc(num_sec, sizeof(struct gp_service *));
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (i = 0; i < num_sec; i++) {
|
|
Packit Service |
9f2c4a |
secname = gp_config_get_secname(ctx, i);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = strncmp(secname, "service/", 8);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
n = cfg->num_svcs;
|
|
Packit Service |
9f2c4a |
cfg->svcs[n] = calloc(1, sizeof(struct gp_service));
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs[n]) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
cfg->num_svcs++;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* by default allow both */
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->cred_usage = GSS_C_BOTH;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->name = strdup(secname + 8);
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs[n]->name) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* euid can be a string or an int */
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_int(ctx, secname, "euid", &valnum);
|
|
Packit Service |
9f2c4a |
if (ret != 0) {
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "euid", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
struct passwd *eu_passwd; /* static; do not free */
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
errno = 0; /* needs to be 0; otherwise it won't be set */
|
|
Packit Service |
9f2c4a |
eu_passwd = getpwnam(value);
|
|
Packit Service |
9f2c4a |
if (!eu_passwd) {
|
|
Packit Service |
9f2c4a |
ret = errno;
|
|
Packit Service |
9f2c4a |
if (ret == 0) { /* not that it gets set anyway... */
|
|
Packit Service |
9f2c4a |
ret = ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
valnum = eu_passwd->pw_uid;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (ret != 0) {
|
|
Packit Service |
9f2c4a |
/* if euid is missing or there is an error retrieving it
|
|
Packit Service |
9f2c4a |
* return an error and end. This is a fatal condition. */
|
|
Packit Service |
9f2c4a |
if (ret == ENOENT) {
|
|
Packit Service |
9f2c4a |
GPERROR("Option 'euid' is missing from [%s].\n", secname);
|
|
Packit Service |
9f2c4a |
ret = EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
gp_service_free(cfg->svcs[n]);
|
|
Packit Service |
9f2c4a |
cfg->num_svcs--;
|
|
Packit Service |
9f2c4a |
safefree(secname);
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->euid = valnum;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "allow_any_uid", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->any_uid = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname,
|
|
Packit Service |
9f2c4a |
"allow_protocol_transition", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->allow_proto_trans = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname,
|
|
Packit Service |
9f2c4a |
"allow_constrained_delegation", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->allow_const_deleg = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname,
|
|
Packit Service |
9f2c4a |
"allow_client_ccache_sync", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->allow_cc_sync = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "trusted", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->trusted = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "kernel_nfsd", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->kernel_nfsd = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "impersonate", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(value)) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->impersonate = true;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "socket", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->socket = strdup(value);
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs[n]->socket) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "mechs", &value);
|
|
Packit Service |
9f2c4a |
if (ret != 0) {
|
|
Packit Service |
9f2c4a |
/* if mechs is missing or there is an error retrieving it
|
|
Packit Service |
9f2c4a |
* return an error and end. This is a fatal condition. */
|
|
Packit Service |
9f2c4a |
if (ret == ENOENT) {
|
|
Packit Service |
9f2c4a |
GPERROR("Option 'mechs' is missing from [%s].\n", secname);
|
|
Packit Service |
9f2c4a |
ret = EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
gp_service_free(cfg->svcs[n]);
|
|
Packit Service |
9f2c4a |
cfg->num_svcs--;
|
|
Packit Service |
9f2c4a |
safefree(secname);
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
vcopy = strdup(value);
|
|
Packit Service |
9f2c4a |
if (!vcopy) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
token = strtok_r(vcopy, ", ", &handle);
|
|
Packit Service |
9f2c4a |
do {
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = strcmp(value, "krb5");
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
ret = get_krb5_mech_cfg(cfg->svcs[n], ctx, secname);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->mechs |= GP_CRED_KRB5;
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
GPERROR("Failed to read krb5 config for %s.\n",
|
|
Packit Service |
9f2c4a |
secname);
|
|
Packit Service |
9f2c4a |
safefree(vcopy);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
GPERROR("Unknown mech: %s in [%s], ignoring.\n",
|
|
Packit Service |
9f2c4a |
token, secname);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
token = strtok_r(NULL, ", ", &handle);
|
|
Packit Service |
9f2c4a |
} while (token != NULL);
|
|
Packit Service |
9f2c4a |
safefree(vcopy);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (cfg->svcs[n]->mechs == 0) {
|
|
Packit Service |
9f2c4a |
GPDEBUG("No mechs found for [%s], ignoring.\n", secname);
|
|
Packit Service |
9f2c4a |
gp_service_free(cfg->svcs[n]);
|
|
Packit Service |
9f2c4a |
cfg->num_svcs--;
|
|
Packit Service |
9f2c4a |
safefree(secname);
|
|
Packit Service |
9f2c4a |
continue;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname,
|
|
Packit Service |
9f2c4a |
"selinux_context", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
GPDEBUG(
|
|
Packit Service |
9f2c4a |
"selinux_ctx is deprecated; use euid/socket instead.\n");
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->selinux_ctx = SELINUX_context_new(value);
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs[n]->selinux_ctx) {
|
|
Packit Service |
9f2c4a |
ret = EINVAL;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "cred_usage", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (strcasecmp(value, "initiate") == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->cred_usage = GSS_C_INITIATE;
|
|
Packit Service |
9f2c4a |
} else if (strcasecmp(value, "accept") == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->cred_usage = GSS_C_ACCEPT;
|
|
Packit Service |
9f2c4a |
} else if (strcasecmp(value, "both") == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->cred_usage = GSS_C_BOTH;
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
GPDEBUG("Invalid value '%s' for cred_usage in [%s].\n",
|
|
Packit Service |
9f2c4a |
value, secname);
|
|
Packit Service |
9f2c4a |
ret = EINVAL;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->filter_flags = DEFAULT_FILTERED_FLAGS;
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "filter_flags", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
parse_flags(value, &cfg->svcs[n]->filter_flags);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->enforce_flags = DEFAULT_ENFORCED_FLAGS;
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "enforce_flags", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
ret = parse_flags(value, &cfg->svcs[n]->enforce_flags);
|
|
Packit Service |
9f2c4a |
if (ret) goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, secname, "program", &value);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
cfg->svcs[n]->program = strdup(value);
|
|
Packit Service |
9f2c4a |
if (!cfg->svcs[n]->program) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
safefree(secname);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (cfg->num_svcs == 0) {
|
|
Packit Service |
9f2c4a |
GPERROR("No service sections configured!\n");
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = check_services(cfg);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
safefree(secname);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int gp_init_ini_context(const char *config_file,
|
|
Packit Service |
9f2c4a |
const char *config_dir,
|
|
Packit Service |
9f2c4a |
struct gp_ini_context **ctxp)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct gp_ini_context *ctx;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!ctxp) {
|
|
Packit Service |
9f2c4a |
return EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ctx = calloc(1, sizeof(struct gp_ini_context));
|
|
Packit Service |
9f2c4a |
if (!ctx) {
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_init(config_file, config_dir, ctx);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
free(ctx);
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
*ctxp = ctx;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int load_config(struct gp_config *cfg)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct gp_ini_context *ctx;
|
|
Packit Service |
9f2c4a |
const char *tmpstr;
|
|
Packit Service |
9f2c4a |
int tmp_dbg_lvl = 0;
|
|
Packit Service |
9f2c4a |
int tmpint = 0;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_init_ini_context(cfg->config_file, cfg->config_dir, &ctx;;
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, "gssproxy", "debug", &tmpstr);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
if (gp_boolean_is_true(tmpstr)) {
|
|
Packit Service |
9f2c4a |
if (tmp_dbg_lvl == 0) {
|
|
Packit Service |
9f2c4a |
tmp_dbg_lvl = 1;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else if (ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_int(ctx, "gssproxy", "debug_level", &tmpint);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
tmp_dbg_lvl = tmpint;
|
|
Packit Service |
9f2c4a |
} else if (ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_string(ctx, "gssproxy", "run_as_user", &tmpstr);
|
|
Packit Service |
9f2c4a |
if (ret == 0) {
|
|
Packit Service |
9f2c4a |
cfg->proxy_user = strdup(tmpstr);
|
|
Packit Service |
9f2c4a |
if (!cfg->proxy_user) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else if (ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = gp_config_get_int(ctx, "gssproxy", "worker threads",
|
|
Packit Service |
9f2c4a |
&cfg->num_workers);
|
|
Packit Service |
9f2c4a |
if (ret != 0 && ret != ENOENT) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = load_services(cfg, ctx);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
if (ret != 0) {
|
|
Packit Service |
9f2c4a |
GPERROR("Error reading configuration %d: %s", ret, gp_strerror(ret));
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
gp_debug_toggle(tmp_dbg_lvl);
|
|
Packit Service |
9f2c4a |
gp_config_close(ctx);
|
|
Packit Service |
9f2c4a |
safefree(ctx);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
struct gp_config *read_config(char *config_file, char *config_dir,
|
|
Packit Service |
9f2c4a |
char *socket_name, int opt_daemonize)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
const char *socket = GP_SOCKET_NAME;
|
|
Packit Service |
9f2c4a |
const char *dir = NULL;
|
|
Packit Service |
9f2c4a |
struct gp_config *cfg;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
cfg = calloc(1, sizeof(struct gp_config));
|
|
Packit Service |
9f2c4a |
if (!cfg) {
|
|
Packit Service |
9f2c4a |
return NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (config_file) {
|
|
Packit Service |
9f2c4a |
cfg->config_file = strdup(config_file);
|
|
Packit Service |
9f2c4a |
if (!cfg->config_file) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
ret = asprintf(&cfg->config_file, "%s/gssproxy.conf", PUBCONF_PATH);
|
|
Packit Service |
9f2c4a |
if (ret == -1) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (config_dir) {
|
|
Packit Service |
9f2c4a |
dir = config_dir;
|
|
Packit Service |
9f2c4a |
} else if (!config_file) {
|
|
Packit Service |
9f2c4a |
dir = PUBCONF_PATH;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (dir) {
|
|
Packit Service |
9f2c4a |
cfg->config_dir = strdup(dir);
|
|
Packit Service |
9f2c4a |
if (!cfg->config_dir) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (socket_name) socket = socket_name;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
cfg->socket_name = strdup(socket);
|
|
Packit Service |
9f2c4a |
if (cfg->socket_name == NULL) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
switch (opt_daemonize) {
|
|
Packit Service |
9f2c4a |
case 0:
|
|
Packit Service |
9f2c4a |
/* daemonize by default */
|
|
Packit Service |
9f2c4a |
case 1:
|
|
Packit Service |
9f2c4a |
cfg->daemonize = true;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
case 2:
|
|
Packit Service |
9f2c4a |
cfg->daemonize = false;
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = load_config(cfg);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
GPDEBUG("Config file(s) not found!\n");
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
/* recursively frees cfg */
|
|
Packit Service |
9f2c4a |
free_config(&cfg;;
|
|
Packit Service |
9f2c4a |
return NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return cfg;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
struct gp_creds_handle *gp_service_get_creds_handle(struct gp_service *svc)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
return svc->krb5.creds_handle;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
void free_config(struct gp_config **cfg)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct gp_config *config = *cfg;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!config) {
|
|
Packit Service |
9f2c4a |
return;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
free(config->config_file);
|
|
Packit Service |
9f2c4a |
free(config->config_dir);
|
|
Packit Service |
9f2c4a |
free(config->socket_name);
|
|
Packit Service |
9f2c4a |
free(config->proxy_user);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
for (int i = 0; i < config->num_svcs; i++) {
|
|
Packit Service |
9f2c4a |
gp_service_free(config->svcs[i]);
|
|
Packit Service |
9f2c4a |
safefree(config->svcs[i]);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
free(config->svcs);
|
|
Packit Service |
9f2c4a |
free(config);
|
|
Packit Service |
9f2c4a |
*cfg = NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int gp_config_from_file(const char *config_file,
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config,
|
|
Packit Service |
9f2c4a |
const uint32_t collision_flags)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgfile *file_ctx = NULL;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_config_file_open(config_file,
|
|
Packit Service |
9f2c4a |
0, /* metadata_flags, FIXME */
|
|
Packit Service |
9f2c4a |
&file_ctx);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
GPERROR("Failed to open config file: %d (%s)\n",
|
|
Packit Service |
9f2c4a |
ret, gp_strerror(ret));
|
|
Packit Service |
9f2c4a |
ini_config_destroy(ini_config);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_config_parse(file_ctx,
|
|
Packit Service |
9f2c4a |
INI_STOP_ON_ANY, /* error_level */
|
|
Packit Service |
9f2c4a |
collision_flags,
|
|
Packit Service |
9f2c4a |
INI_PARSE_NOWRAP, /* parse_flags */
|
|
Packit Service |
9f2c4a |
ini_config);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
char **errors = NULL;
|
|
Packit Service |
9f2c4a |
/* we had a parsing failure */
|
|
Packit Service |
9f2c4a |
GPERROR("Failed to parse config file: %d (%s)\n",
|
|
Packit Service |
9f2c4a |
ret, gp_strerror(ret));
|
|
Packit Service |
9f2c4a |
if (ini_config_error_count(ini_config)) {
|
|
Packit Service |
9f2c4a |
ini_config_get_errors(ini_config, &errors);
|
|
Packit Service |
9f2c4a |
if (errors) {
|
|
Packit Service |
9f2c4a |
ini_config_print_errors(stderr, errors);
|
|
Packit Service |
9f2c4a |
ini_config_free_errors(errors);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ini_config_file_destroy(file_ctx);
|
|
Packit Service |
9f2c4a |
ini_config_destroy(ini_config);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ini_config_file_destroy(file_ctx);
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
static int gp_config_from_dir(const char *config_dir,
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj **ini_config,
|
|
Packit Service |
9f2c4a |
const uint32_t collision_flags)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *result_cfg = NULL;
|
|
Packit Service |
9f2c4a |
struct ref_array *error_list = NULL;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
const char *patterns[] = {
|
|
Packit Service |
9f2c4a |
/* match only files starting with "##-" and ending in ".conf" */
|
|
Packit Service |
9f2c4a |
"^[0-9]\\{2\\}-.\\{1,\\}\\.conf$",
|
|
Packit Service |
9f2c4a |
NULL,
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
const char *sections[] = {
|
|
Packit Service |
9f2c4a |
/* match either "gssproxy" or sections that start with "service/" */
|
|
Packit Service |
9f2c4a |
"^gssproxy$",
|
|
Packit Service |
9f2c4a |
"^service/.*$",
|
|
Packit Service |
9f2c4a |
NULL,
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* Permission check failures silently skip the file, so they are not
|
|
Packit Service |
9f2c4a |
* useful to us. */
|
|
Packit Service |
9f2c4a |
ret = ini_config_augment(*ini_config,
|
|
Packit Service |
9f2c4a |
config_dir,
|
|
Packit Service |
9f2c4a |
patterns,
|
|
Packit Service |
9f2c4a |
sections,
|
|
Packit Service |
9f2c4a |
NULL, /* check_perm */
|
|
Packit Service |
9f2c4a |
INI_STOP_ON_ANY, /* error_level */
|
|
Packit Service |
9f2c4a |
collision_flags,
|
|
Packit Service |
9f2c4a |
INI_PARSE_NOWRAP,
|
|
Packit Service |
9f2c4a |
/* allow sections with the same name in
|
|
Packit Service |
9f2c4a |
* different files, but log warnings */
|
|
Packit Service |
9f2c4a |
INI_MS_DETECT | INI_MS_PRESERVE,
|
|
Packit Service |
9f2c4a |
&result_cfg,
|
|
Packit Service |
9f2c4a |
&error_list,
|
|
Packit Service |
9f2c4a |
NULL);
|
|
Packit Service |
9f2c4a |
if (error_list) {
|
|
Packit Service |
9f2c4a |
uint32_t len;
|
|
Packit Service |
9f2c4a |
len = ref_array_len(error_list);
|
|
Packit Service |
9f2c4a |
for (uint32_t i = 0; i < len; i++) {
|
|
Packit Service |
9f2c4a |
/* libini has an unfixable bug where error strings are (char **) */
|
|
Packit Service |
9f2c4a |
GPAUDIT("Error when reading config directory: %s\n",
|
|
Packit Service |
9f2c4a |
*(char **)ref_array_get(error_list, i, NULL));
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ref_array_destroy(error_list);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (ret && ret != EEXIST) {
|
|
Packit Service |
9f2c4a |
GPERROR("Error when reading config directory number: %d\n", ret);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ref_array_destroy(error_list);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* if we read no new files, result_cfg will be NULL */
|
|
Packit Service |
9f2c4a |
if (result_cfg) {
|
|
Packit Service |
9f2c4a |
ini_config_destroy(*ini_config);
|
|
Packit Service |
9f2c4a |
*ini_config = result_cfg;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_init(const char *config_file, const char *config_dir,
|
|
Packit Service |
9f2c4a |
struct gp_ini_context *ctx)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = NULL;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
/* Within a single file, merge all collisions */
|
|
Packit Service |
9f2c4a |
const uint32_t collision_flags =
|
|
Packit Service |
9f2c4a |
INI_MS_MERGE | INI_MV1S_ALLOW | INI_MV2S_ALLOW;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!ctx) {
|
|
Packit Service |
9f2c4a |
return EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_config_create(&ini_config);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (config_file) {
|
|
Packit Service |
9f2c4a |
ret = gp_config_from_file(config_file, ini_config, collision_flags);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
GPDEBUG("Error when trying to read config file %s.\n",
|
|
Packit Service |
9f2c4a |
config_file);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (config_dir) {
|
|
Packit Service |
9f2c4a |
ret = gp_config_from_dir(config_dir, &ini_config, collision_flags);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
GPDEBUG("Error when trying to read config directory %s.\n",
|
|
Packit Service |
9f2c4a |
config_dir);
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ctx->private_data = ini_config;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_get_string(struct gp_ini_context *ctx,
|
|
Packit Service |
9f2c4a |
const char *secname,
|
|
Packit Service |
9f2c4a |
const char *keyname,
|
|
Packit Service |
9f2c4a |
const char **value)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
struct value_obj *vo = NULL;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
const char *val;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!value) {
|
|
Packit Service |
9f2c4a |
return -1;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*value = NULL;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_get_config_valueobj(secname,
|
|
Packit Service |
9f2c4a |
keyname,
|
|
Packit Service |
9f2c4a |
ini_config,
|
|
Packit Service |
9f2c4a |
INI_GET_FIRST_VALUE,
|
|
Packit Service |
9f2c4a |
&vo);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (!vo) {
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
val = ini_get_const_string_config_value(vo, &ret;;
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*value = val;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_get_string_array(struct gp_ini_context *ctx,
|
|
Packit Service |
9f2c4a |
const char *secname,
|
|
Packit Service |
9f2c4a |
const char *keyname,
|
|
Packit Service |
9f2c4a |
int *num_values,
|
|
Packit Service |
9f2c4a |
const char ***values)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
struct value_obj *vo = NULL;
|
|
Packit Service |
9f2c4a |
const char *value;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
int i, count = 0;
|
|
Packit Service |
9f2c4a |
const char **array = NULL;
|
|
Packit Service |
9f2c4a |
const char **t_array;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!values || !num_values) {
|
|
Packit Service |
9f2c4a |
return EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*num_values = 0;
|
|
Packit Service |
9f2c4a |
*values = NULL;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_get_config_valueobj(secname,
|
|
Packit Service |
9f2c4a |
keyname,
|
|
Packit Service |
9f2c4a |
ini_config,
|
|
Packit Service |
9f2c4a |
INI_GET_FIRST_VALUE,
|
|
Packit Service |
9f2c4a |
&vo);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (!vo) {
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
value = ini_get_const_string_config_value(vo, &ret;;
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
array = calloc(1, sizeof(char *));
|
|
Packit Service |
9f2c4a |
if (array == NULL) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
array[count] = strdup(value);
|
|
Packit Service |
9f2c4a |
if (array[count] == NULL) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
count++;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
do {
|
|
Packit Service |
9f2c4a |
ret = ini_get_config_valueobj(secname,
|
|
Packit Service |
9f2c4a |
keyname,
|
|
Packit Service |
9f2c4a |
ini_config,
|
|
Packit Service |
9f2c4a |
INI_GET_NEXT_VALUE,
|
|
Packit Service |
9f2c4a |
&vo);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (!vo) {
|
|
Packit Service |
9f2c4a |
break;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
value = ini_get_const_string_config_value(vo, &ret;;
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
t_array = realloc(array, (count+1) * sizeof(char *));
|
|
Packit Service |
9f2c4a |
if (t_array == NULL) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
array = t_array;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
array[count] = strdup(value);
|
|
Packit Service |
9f2c4a |
if (array[count] == NULL) {
|
|
Packit Service |
9f2c4a |
ret = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
count++;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
} while (1);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*num_values = count;
|
|
Packit Service |
9f2c4a |
*values = array;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = 0;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
if (ret && array) {
|
|
Packit Service |
9f2c4a |
for (i = 0; i < count; i++) {
|
|
Packit Service |
9f2c4a |
safefree(array[i]);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
safefree(array);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_get_int(struct gp_ini_context *ctx,
|
|
Packit Service |
9f2c4a |
const char *secname,
|
|
Packit Service |
9f2c4a |
const char *keyname,
|
|
Packit Service |
9f2c4a |
int *value)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
struct value_obj *vo = NULL;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
int val;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!value) {
|
|
Packit Service |
9f2c4a |
return EINVAL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*value = -1;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret = ini_get_config_valueobj(secname,
|
|
Packit Service |
9f2c4a |
keyname,
|
|
Packit Service |
9f2c4a |
ini_config,
|
|
Packit Service |
9f2c4a |
INI_GET_FIRST_VALUE,
|
|
Packit Service |
9f2c4a |
&vo);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (!vo) {
|
|
Packit Service |
9f2c4a |
return ENOENT;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
val = ini_get_int_config_value(vo,
|
|
Packit Service |
9f2c4a |
0, /* strict */
|
|
Packit Service |
9f2c4a |
0, /* default */
|
|
Packit Service |
9f2c4a |
&ret;;
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
*value = val;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_get_nsec(struct gp_ini_context *ctx)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
char **list = NULL;
|
|
Packit Service |
9f2c4a |
int count;
|
|
Packit Service |
9f2c4a |
int error;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
list = ini_get_section_list(ini_config, &count, &error);
|
|
Packit Service |
9f2c4a |
if (error) {
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ini_free_section_list(list);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return count;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
char *gp_config_get_secname(struct gp_ini_context *ctx,
|
|
Packit Service |
9f2c4a |
int i)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
char **list = NULL;
|
|
Packit Service |
9f2c4a |
int count;
|
|
Packit Service |
9f2c4a |
int error;
|
|
Packit Service |
9f2c4a |
char *secname;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
list = ini_get_section_list(ini_config, &count, &error);
|
|
Packit Service |
9f2c4a |
if (error) {
|
|
Packit Service |
9f2c4a |
return NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (i >= count) {
|
|
Packit Service |
9f2c4a |
return NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
secname = strdup(list[i]);
|
|
Packit Service |
9f2c4a |
ini_free_section_list(list);
|
|
Packit Service |
9f2c4a |
if (!secname) {
|
|
Packit Service |
9f2c4a |
return NULL;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return secname;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_config_close(struct gp_ini_context *ctx)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct ini_cfgobj *ini_config = NULL;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (!ctx) {
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ini_config = (struct ini_cfgobj *)ctx->private_data;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ini_config_destroy(ini_config);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return 0;
|
|
Packit Service |
9f2c4a |
}
|