Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/jail/config.c
Context not available. | |||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <glob.h> | |||||
#include <netdb.h> | #include <netdb.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
Context not available. | |||||
unsigned flags; | unsigned flags; | ||||
}; | }; | ||||
extern FILE *yyin; | extern int yylex_init_extra(struct cflex *extra, void *scanner); | ||||
extern int yynerrs; | extern int yylex_destroy(void *scanner); | ||||
extern int yyparse(void *scanner); | |||||
extern int yyparse(void); | extern int yyset_in(FILE *fp, void *scanner); | ||||
struct cfjails cfjails = TAILQ_HEAD_INITIALIZER(cfjails); | struct cfjails cfjails = TAILQ_HEAD_INITIALIZER(cfjails); | ||||
static void parse_config(const char *fname, int is_stdin, | |||||
struct cfjail *injail); | |||||
static void free_param(struct cfparams *pp, struct cfparam *p); | static void free_param(struct cfparams *pp, struct cfparam *p); | ||||
static void free_param_strings(struct cfparam *p); | |||||
static const struct ipspec intparams[] = { | static const struct ipspec intparams[] = { | ||||
[IP_ALLOW_DYING] = {"allow.dying", PF_INTERNAL | PF_BOOL}, | [IP_ALLOW_DYING] = {"allow.dying", PF_INTERNAL | PF_BOOL}, | ||||
Context not available. | |||||
}; | }; | ||||
/* | /* | ||||
* Parse the jail configuration file. | * Parse a jail config file, either initially from main, or from | ||||
* an include within another config file. | |||||
*/ | */ | ||||
void | void | ||||
load_config(void) | load_config(const char *cfname) | ||||
{ | { | ||||
struct cfjails wild; | struct cfjails wild; | ||||
struct cfparams opp; | struct cfparams opp; | ||||
Context not available. | |||||
char *ep; | char *ep; | ||||
int did_self, jseq, pgen; | int did_self, jseq, pgen; | ||||
if (!strcmp(cfname, "-")) { | parse_config(cfname, !strcmp(cfname, "-"), NULL); | ||||
cfname = "STDIN"; | |||||
yyin = stdin; | |||||
} else { | |||||
yyin = fopen(cfname, "r"); | |||||
if (!yyin) | |||||
err(1, "%s", cfname); | |||||
} | |||||
if (yyparse() || yynerrs) | |||||
exit(1); | |||||
/* Separate the wildcard jails out from the actual jails. */ | /* Separate the wildcard jails out from the actual jails. */ | ||||
jseq = 0; | jseq = 0; | ||||
Context not available. | |||||
} | } | ||||
} | } | ||||
void | |||||
include_config(const char *cfname, struct cflex *cflex, int from_stdin) | |||||
{ | |||||
glob_t g; | |||||
meka_tilda.center: Initialize all glob_t vars to zero/NULL. | |||||
const char *slash; | |||||
char *fullpath = NULL; | |||||
/* Base relative pathnames on the current config file. */ | |||||
if (!from_stdin && cfname[0] != '/' && | |||||
(slash = strrchr(cflex->cfname, '/')) != NULL) { | |||||
size_t dirlen = (slash - cflex->cfname) + 1; | |||||
fullpath = emalloc(dirlen + strlen(cfname) + 1); | |||||
strncpy(fullpath, cflex->cfname, dirlen); | |||||
strcpy(fullpath + dirlen, cfname); | |||||
cfname = fullpath; | |||||
} | |||||
/* | |||||
* Check if the include statement had a filename glob. | |||||
* Globbing doesn't need to catch any files, but a non-glob | |||||
* file needs to exist (enforced by parse_config). | |||||
*/ | |||||
if (glob(cfname, GLOB_NOCHECK, NULL, &g) != 0) | |||||
errx(1, "filename glob failed"); | |||||
if (g.gl_flags & GLOB_MAGCHAR) { | |||||
Done Inline ActionsChecking if the file was already included would need to happen somewhere here. ihor_antonovs.family: Checking if the file was already included would need to happen somewhere here. | |||||
for (size_t gi = 0; gi < g.gl_matchc; gi++) | |||||
parse_config(g.gl_pathv[gi], 0, cflex->injail); | |||||
} else | |||||
parse_config(cfname, 0, cflex->injail); | |||||
if (fullpath) | |||||
free(fullpath); | |||||
} | |||||
static void | |||||
parse_config(const char *cfname, int is_stdin, struct cfjail *injail) | |||||
{ | |||||
struct cflex cflex = {.cfname = cfname, .injail = injail, .error = 0}; | |||||
void *scanner; | |||||
yylex_init_extra(&cflex, &scanner); | |||||
if (is_stdin) { | |||||
yyset_in(stdin, scanner); | |||||
} else { | |||||
FILE *cfp = fopen(cfname, "r"); | |||||
if (!cfp) | |||||
err(1, "%s", cfname); | |||||
yyset_in(cfp, scanner); | |||||
} | |||||
if (yyparse(scanner) || cflex.error) | |||||
exit(1); | |||||
yylex_destroy(scanner); | |||||
} | |||||
/* | /* | ||||
* Create a new jail record. | * Create a new jail record. | ||||
*/ | */ | ||||
Context not available. | |||||
free(p); | free(p); | ||||
} | } | ||||
static void | void | ||||
free_param_strings(struct cfparam *p) | free_param_strings(struct cfparam *p) | ||||
{ | { | ||||
struct cfstring *s; | struct cfstring *s; | ||||
Context not available. |
Initialize all glob_t vars to zero/NULL.