return 1;
}
-FILE *pushgconffile(struct gconffile **cf, const char *path) {
+FILE *pushgconffile(struct gconffile **cf, FILE *file, const char *description) {
int i;
struct gconffile *newcf;
- char *pathcopy;
- FILE *f;
+ char *desc;
- f = fopen(path, "r");
- if (!f) {
- debug(DBG_INFO, "could not read config file %s", path);
+ if (!file) {
+ debug(DBG_INFO, "could not read config from %s", description);
return NULL;
}
- debug(DBG_DBG, "opened config file %s", path);
+ debug(DBG_DBG, "reading config from %s", description);
- pathcopy = stringcopy(path, 0);
- if (!pathcopy)
+ desc = stringcopy(description, 0);
+ if (!desc)
goto errmalloc;
if (!*cf) {
memmove(newcf + 1, newcf, sizeof(struct gconffile) * (i + 1));
memset(newcf, 0, sizeof(struct gconffile));
}
- newcf[0].file = f;
- newcf[0].path = pathcopy;
+ newcf[0].file = file;
+ newcf[0].path = desc;
*cf = newcf;
- return f;
+ return file;
errmalloc:
- free(pathcopy);
- fclose(f);
+ free(desc);
+ fclose(file);
debug(DBG_ERR, "malloc failed");
return NULL;
}
-FILE *pushgconffiles(struct gconffile **cf, const char *cfgpath) {
+FILE *pushgconfpath(struct gconffile **cf, const char *path) {
+ int i;
+ struct gconffile *newcf;
+ char *pathcopy;
+ FILE *f;
+
+ f = fopen(path, "r");
+ return pushgconffile(cf, f, path);
+}
+
+FILE *pushgconfpaths(struct gconffile **cf, const char *cfgpath) {
int i;
FILE *f = NULL;
glob_t globbuf;
}
for (i = globbuf.gl_pathc - 1; i >= 0; i--) {
- f = pushgconffile(cf, globbuf.gl_pathv[i]);
+ f = pushgconfpath(cf, globbuf.gl_pathv[i]);
if (!f)
break;
}
return f;
}
-int popgconffile(struct gconffile **cf) {
+int popgconf(struct gconffile **cf) {
int i;
if (!*cf)
struct gconffile *openconfigfile(const char *file) {
struct gconffile *cf = NULL;
- if (!pushgconffile(&cf, file)) {
+ if (!pushgconfpath(&cf, file)) {
debug(DBG_ERR, "could not read config file %s\n%s", file, strerror(errno));
return NULL;
}
for (;;) {
if (!getlinefromcf(*cf, line, 1024)) {
- if (popgconffile(cf))
+ if (popgconf(cf))
continue;
return 1;
}
return 1;
if (conftype == CONF_STR && !strcasecmp(opt, "include")) {
- if (!pushgconffiles(cf, val)) {
+ if (!pushgconfpaths(cf, val)) {
debug(DBG_ERR, "failed to include config file %s", val);
goto errexit;
}
int getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype);
int getgenericconfig(struct gconffile **cf, char *block, ...);
int pushgconfdata(struct gconffile **cf, const char *data);
-FILE *pushgconffile(struct gconffile **cf, const char *path);
-FILE *pushgconffiles(struct gconffile **cf, const char *path);
+FILE *pushgconfpath(struct gconffile **cf, const char *path);
+FILE *pushgconffile(struct gconffile **cf, FILE *file, const char *description);
+FILE *pushgconfpaths(struct gconffile **cf, const char *path);
int popgconf(struct gconffile **cf);
void freegconf(struct gconffile **cf);
struct gconffile *openconfigfile(const char *file);
pthread_mutex_unlock(&realm->subrealms_mutex);
}
+void dynconfserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
+ char *type = NULL, *tls = NULL, *matchcertattr = NULL, *rewrite = NULL;
+ struct clsrvconf *conf, *resconf;
+
+ debug(DBG_DBG, "dynconfserver_cb called for %s", block);
+
+ conf = malloc(sizeof(struct clsrvconf));
+ if (!conf) {
+ debugx(1, DBG_ERR, "malloc failed");
+ return;
+ }
+ memset(conf, 0, sizeof(struct clsrvconf));
+ conf->certnamecheck = 1;
+
+ if (!getgenericconfig(cf, block,
+ "type", CONF_STR, &type,
+ "host", CONF_STR, &conf->host,
+ "port", CONF_STR, &conf->port,
+ "secret", CONF_STR, &conf->secret,
+ "tls", CONF_STR, &tls,
+ "MatchCertificateAttribute", CONF_STR, &matchcertattr,
+ "rewrite", CONF_STR, &rewrite,
+ "StatusServer", CONF_BLN, &conf->statusserver,
+ "CertificateNameCheck", CONF_BLN, &conf->certnamecheck,
+ "DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,
+ NULL
+ ))
+ debugx(1, DBG_ERR, "configuration error");
+
+ conf->name = stringcopy(val, 0);
+ if (!conf->host)
+ conf->host = stringcopy(val, 0);
+ /* need to copy other params */
+ /* any params used from template needs to be duplicated */
+ resconf = (struct clsrvconf *)arg;
+ resconf->name = conf->name;
+ conf->name = NULL;
+ resconf->host = conf->host;
+ conf->host = NULL;
+ /* free conf here */
+ return;
+}
+
void dynamicconfig(struct server *server) {
- int n, fd[2];
+ int ok, fd[2];
pid_t pid;
- char *host, *s, line[1024];
struct clsrvconf *conf = server->conf;
+ struct gconffile *cf = NULL;
/* for now we only learn hostname/address */
debug(DBG_DBG, "dynamicconfig: need dynamic server config for %s", server->dynamiclookuparg);
}
close(fd[1]);
- n = read(fd[0], line, 1024);
- debug(DBG_DBG, "dynamicconfig: command output: %s", line);
- close(fd[0]);
+ pushgconffile(&cf, fdopen(fd[0], "r"), conf->dynamiclookupcommand);
+ ok = getgenericconfig(&cf, NULL,
+ "Server", CONF_CBK, dynconfserver_cb, (void *)conf,
+ NULL
+ );
+ freegconf(&cf);
+
if (waitpid(pid, NULL, 0) < 0) {
debug(DBG_ERR, "dynamicconfig: wait error");
goto errexit;
}
- debug(DBG_DBG, "dynamicconfig: after exec");
- for (s = line; *s && strchr(" \t\r\n", *s); s++);
- for (host = s; *s && !strchr(" \t\r\n", *s); s++);
- *s = '\0';
- if (!*host) {
- debug(DBG_ERR, "dynamicconfig: invalid dynamic hostname/address");
- goto errexit;
- }
- conf->name = stringcopy(host, 0);
- conf->host = stringcopy(host, 0);
- return;
-
+ if (ok)
+ return;
+
errexit:
server->conf = NULL;
debug(DBG_WARN, "dynamicconfig: failed to obtain dynamic server config");