Keep all internal/known parameter names in one place, and use

enum constants everywhere else.
This commit is contained in:
jamie 2010-10-27 16:22:54 +00:00
parent 0f098ddf66
commit 235aefe219
3 changed files with 151 additions and 160 deletions

View File

@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
struct ipspec {
const char *name;
enum intparam ipnum;
unsigned flags;
};
@ -53,52 +52,57 @@ extern int yynerrs;
struct cfjails cfjails = TAILQ_HEAD_INITIALIZER(cfjails);
static int cmp_intparam(const void *a, const void *b);
static void free_param(struct cfparams *pp, struct cfparam *p);
static void free_param_strings(struct cfparam *p);
/* Note these must be in sort order */
static const struct ipspec intparams[] = {
{"allow.dying", IP_ALLOW_DYING, PF_INTERNAL | PF_BOOL },
{"allow.nodying", IP_ALLOW_DYING, PF_INTERNAL | PF_BOOL },
{"command", IP_COMMAND, PF_INTERNAL },
{"depend", IP_DEPEND, PF_INTERNAL },
{"exec.clean", IP_EXEC_CLEAN, PF_INTERNAL | PF_BOOL },
{"exec.consolelog", IP_EXEC_CONSOLELOG, PF_INTERNAL },
{"exec.fib", IP_EXEC_FIB, PF_INTERNAL | PF_INT },
{"exec.jail_user", IP_EXEC_JAIL_USER, PF_INTERNAL },
{"exec.noclean", IP_EXEC_CLEAN, PF_INTERNAL | PF_BOOL },
{"exec.nosystem_jail_user",IP_EXEC_SYSTEM_JAIL_USER,PF_INTERNAL | PF_BOOL },
{"exec.poststart", IP_EXEC_POSTSTART, PF_INTERNAL },
{"exec.poststop", IP_EXEC_POSTSTOP, PF_INTERNAL },
{"exec.prestart", IP_EXEC_PRESTART, PF_INTERNAL },
{"exec.prestop", IP_EXEC_PRESTOP, PF_INTERNAL },
{"exec.start", IP_EXEC_START, PF_INTERNAL },
{"exec.stop", IP_EXEC_STOP, PF_INTERNAL },
{"exec.system_jail_user", IP_EXEC_SYSTEM_JAIL_USER, PF_INTERNAL | PF_BOOL },
{"exec.system_user", IP_EXEC_SYSTEM_USER, PF_INTERNAL },
{"exec.timeout", IP_EXEC_TIMEOUT, PF_INTERNAL | PF_INT },
{"host.hostname", KP_HOSTNAME, 0 },
{"interface", IP_INTERFACE, PF_INTERNAL },
{"ip4.addr", KP_IP4_ADDR, 0 },
[IP_ALLOW_DYING] = {"allow.dying", PF_INTERNAL | PF_BOOL},
[IP_COMMAND] = {"command", PF_INTERNAL},
[IP_DEPEND] = {"depend", PF_INTERNAL},
[IP_EXEC_CLEAN] = {"exec.clean", PF_INTERNAL | PF_BOOL},
[IP_EXEC_CONSOLELOG] = {"exec.consolelog", PF_INTERNAL},
[IP_EXEC_FIB] = {"exec.fib", PF_INTERNAL | PF_INT},
[IP_EXEC_JAIL_USER] = {"exec.jail_user", PF_INTERNAL},
[IP_EXEC_POSTSTART] = {"exec.poststart", PF_INTERNAL},
[IP_EXEC_POSTSTOP] = {"exec.poststop", PF_INTERNAL},
[IP_EXEC_PRESTART] = {"exec.prestart", PF_INTERNAL},
[IP_EXEC_PRESTOP] = {"exec.prestop", PF_INTERNAL},
[IP_EXEC_START] = {"exec.start", PF_INTERNAL},
[IP_EXEC_STOP] = {"exec.stop", PF_INTERNAL},
[IP_EXEC_SYSTEM_JAIL_USER]= {"exec.system_jail_user",
PF_INTERNAL | PF_BOOL},
[IP_EXEC_SYSTEM_USER] = {"exec.system_user", PF_INTERNAL},
[IP_EXEC_TIMEOUT] = {"exec.timeout", PF_INTERNAL | PF_INT},
[IP_INTERFACE] = {"interface", PF_INTERNAL},
[IP_IP_HOSTNAME] = {"ip_hostname", PF_INTERNAL | PF_BOOL},
[IP_MOUNT] = {"mount", PF_INTERNAL},
[IP_MOUNT_DEVFS] = {"mount.devfs", PF_INTERNAL | PF_BOOL},
[IP_MOUNT_DEVFS_RULESET]= {"mount.devfs.ruleset", PF_INTERNAL},
[IP_MOUNT_FSTAB] = {"mount.fstab", PF_INTERNAL},
[IP_STOP_TIMEOUT] = {"stop.timeout", PF_INTERNAL | PF_INT},
[IP_VNET_INTERFACE] = {"vnet.interface", PF_INTERNAL},
[IP__IP4_IFADDR] = {"ip4.addr", PF_INTERNAL | PF_CONV},
#ifdef INET6
{"ip6.addr", KP_IP6_ADDR, 0 },
[IP__IP6_IFADDR] = {"ip6.addr", PF_INTERNAL | PF_CONV},
#endif
{"ip_hostname", IP_IP_HOSTNAME, PF_INTERNAL | PF_BOOL },
{"jid", KP_JID, PF_INT },
{"mount", IP_MOUNT, PF_INTERNAL },
{"mount.devfs", IP_MOUNT_DEVFS, PF_INTERNAL | PF_BOOL },
{"mount.devfs.ruleset", IP_MOUNT_DEVFS_RULESET, PF_INTERNAL },
{"mount.fstab", IP_MOUNT_FSTAB, PF_INTERNAL },
{"mount.nodevfs", IP_MOUNT_DEVFS, PF_INTERNAL | PF_BOOL },
{"name", KP_NAME, 0 },
{"noip_hostname", IP_IP_HOSTNAME, PF_INTERNAL | PF_BOOL },
{"nopersist", KP_PERSIST, PF_BOOL },
{"path", KP_PATH, 0 },
{"persist", KP_PERSIST, PF_BOOL },
{"stop.timeout", IP_STOP_TIMEOUT, PF_INTERNAL | PF_INT },
{"vnet", KP_VNET, 0 },
{"vnet.interface", IP_VNET_INTERFACE, PF_INTERNAL },
[KP_ALLOW_CHFLAGS] = {"allow.chflags", 0},
[KP_ALLOW_MOUNT] = {"allow.mount", 0},
[KP_ALLOW_RAW_SOCKETS] = {"allow.raw_sockets", 0},
[KP_ALLOW_SET_HOSTNAME]= {"allow.set_hostname", 0},
[KP_ALLOW_SOCKET_AF] = {"allow.socket_af", 0},
[KP_ALLOW_SYSVIPC] = {"allow.sysvipc", 0},
[KP_ENFORCE_STATFS] = {"enforce_statfs", 0},
[KP_HOST_HOSTNAME] = {"host.hostname", 0},
[KP_IP4_ADDR] = {"ip4.addr", 0},
#ifdef INET6
[KP_IP6_ADDR] = {"ip6.addr", 0},
#endif
[KP_JID] = {"jid", 0},
[KP_NAME] = {"name", 0},
[KP_PATH] = {"path", 0},
[KP_PERSIST] = {"persist", 0},
[KP_SECURELEVEL] = {"securelevel", 0},
[KP_VNET] = {"vnet", 0},
};
/*
@ -146,7 +150,7 @@ load_config(void)
* though they may also be explicitly set later on.
*/
add_param(j, NULL,
strtol(j->name, &ep, 10) && !*ep ? "jid" : "name",
strtol(j->name, &ep, 10) && !*ep ? KP_JID : KP_NAME,
j->name);
/*
* Collect parameters for the jail, global parameters/variables,
@ -156,16 +160,16 @@ load_config(void)
TAILQ_FOREACH(wj, &wild, tq) {
if (j->seq < wj->seq && !did_self) {
TAILQ_FOREACH(p, &opp, tq)
add_param(j, p, NULL, NULL);
add_param(j, p, 0, NULL);
did_self = 1;
}
if (wild_jail_match(j->name, wj->name))
TAILQ_FOREACH(p, &wj->params, tq)
add_param(j, p, NULL, NULL);
add_param(j, p, 0, NULL);
}
if (!did_self)
TAILQ_FOREACH(p, &opp, tq)
add_param(j, p, NULL, NULL);
add_param(j, p, 0, NULL);
/* Resolve any variable substitutions. */
pgen = 0;
@ -274,13 +278,16 @@ add_jail(void)
* Add a parameter to a jail.
*/
void
add_param(struct cfjail *j, const struct cfparam *p, const char *name,
add_param(struct cfjail *j, const struct cfparam *p, enum intparam ipnum,
const char *value)
{
struct cfstrings nss;
struct cfparam *dp, *np;
struct cfstring *s, *ns;
struct cfvar *v, *nv;
struct ipspec *ips;
const char *name;
char *cs, *tname;
unsigned flags;
if (j == NULL) {
@ -312,6 +319,18 @@ add_param(struct cfjail *j, const struct cfparam *p, const char *name,
}
} else {
flags = PF_APPEND;
if (ipnum != 0) {
name = intparams[ipnum].name;
flags |= intparams[ipnum].flags;
} else if ((cs = strchr(value, '='))) {
tname = alloca(cs - value + 1);
strlcpy(tname, value, cs - value + 1);
name = tname;
value = cs + 1;
} else {
name = value;
value = NULL;
}
if (value != NULL) {
ns = emalloc(sizeof(struct cfstring));
ns->s = estrdup(value);
@ -322,8 +341,13 @@ add_param(struct cfjail *j, const struct cfparam *p, const char *name,
}
/* See if this parameter has already been added. */
TAILQ_FOREACH(dp, &j->params, tq) {
if (equalopts(dp->name, name)) {
if (ipnum != 0)
dp = j->intparams[ipnum];
else
TAILQ_FOREACH(dp, &j->params, tq)
if (!(dp->flags & PF_CONV) && equalopts(dp->name, name))
break;
if (dp != NULL) {
/* Found it - append or replace. */
if (strcmp(dp->name, name)) {
free(dp->name);
@ -333,10 +357,7 @@ add_param(struct cfjail *j, const struct cfparam *p, const char *name,
free_param_strings(dp);
STAILQ_CONCAT(&dp->val, &nss);
dp->flags |= flags;
break;
}
}
if (dp == NULL) {
} else {
/* Not found - add it. */
np = emalloc(sizeof(struct cfparam));
np->name = estrdup(name);
@ -345,28 +366,15 @@ add_param(struct cfjail *j, const struct cfparam *p, const char *name,
np->flags = flags;
np->gen = 0;
TAILQ_INSERT_TAIL(&j->params, np, tq);
}
}
/*
* Find internal or known parameters.
*/
void
find_intparams(void)
{
struct cfjail *j;
struct cfparam *p;
struct ipspec *ip;
TAILQ_FOREACH(j, &cfjails, tq) {
TAILQ_FOREACH(p, &j->params, tq) {
ip = bsearch(p->name, intparams,
sizeof(intparams) / sizeof(intparams[0]),
sizeof(struct ipspec), cmp_intparam);
if (ip != NULL) {
j->intparams[ip->ipnum] = p;
p->flags |= ip->flags;
}
if (ipnum != 0)
j->intparams[ipnum] = np;
else
for (ipnum = 1; ipnum < IP_NPARAM; ipnum++)
if (!(intparams[ipnum].flags & PF_CONV) &&
equalopts(name, intparams[ipnum].name)) {
j->intparams[ipnum] = np;
np->flags |= intparams[ipnum].flags;
break;
}
}
}
@ -457,7 +465,6 @@ ip_params(struct cfjail *j)
{
struct in_addr addr4;
struct addrinfo hints, *ai0, *ai;
struct cfparam *np;
struct cfstring *s, *ns;
char *cs, *ep;
const char *hostname;
@ -477,7 +484,7 @@ ip_params(struct cfjail *j)
* for any IP addresses it finds.
*/
if (bool_param(j->intparams[IP_IP_HOSTNAME]) &&
(hostname = string_param(j->intparams[KP_HOSTNAME]))) {
(hostname = string_param(j->intparams[KP_HOST_HOSTNAME]))) {
j->intparams[IP_IP_HOSTNAME] = NULL;
/*
* Silently ignore unsupported address families from
@ -526,7 +533,7 @@ ip_params(struct cfjail *j)
&addr4, avalue4,
INET_ADDRSTRLEN) == NULL)
err(1, "inet_ntop");
add_param(j, NULL, "ip4.addr",
add_param(j, NULL, KP_IP4_ADDR,
avalue4);
break;
#ifdef INET6
@ -539,7 +546,7 @@ ip_params(struct cfjail *j)
&addr6, avalue6,
INET6_ADDRSTRLEN) == NULL)
err(1, "inet_ntop");
add_param(j, NULL, "ip6.addr",
add_param(j, NULL, KP_IP6_ADDR,
avalue6);
break;
#endif
@ -562,28 +569,14 @@ ip_params(struct cfjail *j)
{
if (j->intparams[KP_IP4_ADDR + isip6] == NULL)
continue;
np = j->intparams[IP__IP4_IFADDR + isip6];
STAILQ_FOREACH(s, &j->intparams[KP_IP4_ADDR + isip6]->val, tq) {
cs = strchr(s->s, '|');
if (cs || defif) {
if (np == NULL) {
np = j->intparams[IP__IP4_IFADDR +
isip6] =
emalloc(sizeof(struct cfparam));
np->name = estrdup(j->intparams
[KP_IP4_ADDR + isip6]->name);
STAILQ_INIT(&np->val);
np->flags = PF_INTERNAL;
}
ns = emalloc(sizeof(struct cfstring));
ns->s = estrdup(s->s);
ns->len = s->len;
STAILQ_INIT(&ns->vars);
STAILQ_INSERT_TAIL(&np->val, ns, tq);
if (cs != NULL) {
if (cs || defif)
add_param(j, NULL, IP__IP4_IFADDR + isip6,
s->s);
if (cs) {
strcpy(s->s, cs + 1);
s->len -= cs - s->s + 1;
}
s->len -= cs + 1 - s->s;
}
if ((cs = strchr(s->s, '/'))) {
prefix = strtol(cs + 1, &ep, 10);
@ -745,16 +738,6 @@ wild_jail_name(const char *wname)
return 0;
}
/*
* Compare strings and intparams for bsearch.
*/
static int
cmp_intparam(const void *a, const void *b)
{
return strcmp((const char *)a, ((const struct ipspec *)b)->name);
}
/*
* Free a parameter record and all its strings and variables.
*/

View File

@ -48,6 +48,12 @@ __FBSDID("$FreeBSD$");
#define JP_RDTUN(jp) (((jp)->jp_ctltype & CTLFLAG_RDTUN) == CTLFLAG_RDTUN)
struct permspec {
const char *name;
enum intparam ipnum;
int rev;
};
const char *cfname;
int verbose;
@ -63,19 +69,13 @@ static void print_param(FILE *fp, const struct cfparam *p, int sep, int doname);
static void quoted_print(FILE *fp, char *str);
static void usage(void);
static const char *perm_sysctl[][3] = {
{ "security.jail.set_hostname_allowed",
"allow.noset_hostname", "allow.set_hostname" },
{ "security.jail.sysvipc_allowed",
"allow.nosysvipc", "allow.sysvipc" },
{ "security.jail.allow_raw_sockets",
"allow.noraw_sockets", "allow.raw_sockets" },
{ "security.jail.chflags_allowed",
"allow.nochflags", "allow.chflags" },
{ "security.jail.mount_allowed",
"allow.nomount", "allow.mount" },
{ "security.jail.socket_unixiproute_only",
"allow.socket_af", "allow.nosocket_af" },
static struct permspec perm_sysctl[] = {
{ "security.jail.set_hostname_allowed", KP_ALLOW_SET_HOSTNAME, 0 },
{ "security.jail.sysvipc_allowed", KP_ALLOW_SYSVIPC, 0 },
{ "security.jail.allow_raw_sockets", KP_ALLOW_RAW_SOCKETS, 0 },
{ "security.jail.chflags_allowed", KP_ALLOW_CHFLAGS, 0 },
{ "security.jail.mount_allowed", KP_ALLOW_MOUNT, 0 },
{ "security.jail.socket_unixiproute_only", KP_ALLOW_SOCKET_AF, 1 },
};
int
@ -113,7 +113,7 @@ main(int argc, char **argv)
cfname = optarg;
break;
case 'h':
add_param(NULL, NULL, "ip_hostname", NULL);
add_param(NULL, NULL, IP_IP_HOSTNAME, NULL);
docf = 0;
break;
case 'i':
@ -124,14 +124,14 @@ main(int argc, char **argv)
JidFile = optarg;
break;
case 'l':
add_param(NULL, NULL, "exec.clean", NULL);
add_param(NULL, NULL, IP_EXEC_CLEAN, NULL);
docf = 0;
break;
case 'm':
op |= JF_SET;
break;
case 'n':
add_param(NULL, NULL, "name", optarg);
add_param(NULL, NULL, KP_NAME, optarg);
docf = 0;
break;
case 'p':
@ -150,17 +150,18 @@ main(int argc, char **argv)
Rflag = 1;
break;
case 's':
add_param(NULL, NULL, "securelevel", optarg);
add_param(NULL, NULL, KP_SECURELEVEL, optarg);
docf = 0;
break;
case 'u':
add_param(NULL, NULL, "exec.jail_user", optarg);
add_param(NULL, NULL, "exec.system_jail_user", NULL);
add_param(NULL, NULL, IP_EXEC_JAIL_USER, optarg);
add_param(NULL, NULL, IP_EXEC_SYSTEM_JAIL_USER, NULL);
docf = 0;
break;
case 'U':
add_param(NULL, NULL, "exec.jail_user", optarg);
add_param(NULL, NULL, "exec.nosystem_jail_user", NULL);
add_param(NULL, NULL, IP_EXEC_JAIL_USER, optarg);
add_param(NULL, NULL, IP_EXEC_SYSTEM_JAIL_USER,
"false");
docf = 0;
break;
case 'v':
@ -182,8 +183,8 @@ main(int argc, char **argv)
op = JF_START;
docf = 0;
oldcl = 1;
add_param(NULL, NULL, "path", argv[0]);
add_param(NULL, NULL, "host.hostname", argv[1]);
add_param(NULL, NULL, KP_PATH, argv[0]);
add_param(NULL, NULL, KP_HOST_HOSTNAME, argv[1]);
if (argv[2][0] != '\0') {
for (cs = argv[2];; cs = ncs + 1) {
ncs = strchr(cs, ',');
@ -192,15 +193,15 @@ main(int argc, char **argv)
add_param(NULL, NULL,
#ifdef INET6
inet_pton(AF_INET6, cs, &addr6) == 1
? "ip6.addr" :
? KP_IP6_ADDR :
#endif
"ip4.addr", cs);
KP_IP4_ADDR, cs);
if (!ncs)
break;
}
}
for (i = 3; i < argc; i++)
add_param(NULL, NULL, "command", argv[i]);
add_param(NULL, NULL, IP_COMMAND, argv[i]);
/* Emulate the defaults from security.jail.* sysctls. */
sysvallen = sizeof(sysval);
if (sysctlbyname("security.jail.jailed", &sysval, &sysvallen,
@ -208,18 +209,20 @@ main(int argc, char **argv)
for (pi = 0; pi < sizeof(perm_sysctl) /
sizeof(perm_sysctl[0]); pi++) {
sysvallen = sizeof(sysval);
if (sysctlbyname(perm_sysctl[pi][0],
if (sysctlbyname(perm_sysctl[pi].name,
&sysval, &sysvallen, NULL, 0) == 0)
add_param(NULL, NULL,
perm_sysctl[pi][sysval ? 2 : 1],
NULL);
perm_sysctl[pi].ipnum,
(sysval ? 1 : 0) ^
perm_sysctl[pi].rev
? NULL : "false");
}
sysvallen = sizeof(sysval);
if (sysctlbyname("security.jail.enforce_statfs",
&sysval, &sysvallen, NULL, 0) == 0) {
snprintf(enforce_statfs,
sizeof(enforce_statfs), "%d", sysval);
add_param(NULL, NULL, "enforce_statfs",
add_param(NULL, NULL, KP_ENFORCE_STATFS,
enforce_statfs);
}
}
@ -243,16 +246,14 @@ main(int argc, char **argv)
if (!strncmp(argv[i], "command", 7) &&
(argv[i][7] == '\0' || argv[i][7] == '=')) {
if (argv[i][7] == '=')
add_param(NULL, NULL, "command",
add_param(NULL, NULL, IP_COMMAND,
argv[i] + 8);
for (i++; i < argc; i++)
add_param(NULL, NULL, "command",
add_param(NULL, NULL, IP_COMMAND,
argv[i]);
break;
}
if ((cs = strchr(argv[i], '=')))
*cs++ = '\0';
add_param(NULL, NULL, argv[i], cs);
add_param(NULL, NULL, 0, argv[i]);
}
} else {
/* From the config file, perhaps with a specified jail */
@ -262,7 +263,6 @@ main(int argc, char **argv)
}
/* Find out which jails will be run. */
find_intparams();
dep_setup(docf);
error = 0;
if (op == JF_STOP) {
@ -315,7 +315,7 @@ main(int argc, char **argv)
{
j->flags |= JF_CHECKINT;
if (dflag)
add_param(j, NULL, "allow.dying", NULL);
add_param(j, NULL, IP_ALLOW_DYING, NULL);
if (check_intparams(j) < 0)
continue;
}
@ -959,7 +959,7 @@ print_jail(FILE *fp, struct cfjail *j, int oldcl)
fprintf(fp, "%d\t", j->jid);
print_param(fp, j->intparams[KP_PATH], ',', 0);
putc('\t', fp);
print_param(fp, j->intparams[KP_HOSTNAME], ',', 0);
print_param(fp, j->intparams[KP_HOST_HOSTNAME], ',', 0);
putc('\t', fp);
print_param(fp, j->intparams[KP_IP4_ADDR], ',', 0);
#ifdef INET6

View File

@ -49,6 +49,7 @@
#define PF_INTERNAL 0x08 /* Internal parameter, not passed to kernel */
#define PF_BOOL 0x10 /* Boolean parameter */
#define PF_INT 0x20 /* Integer parameter */
#define PF_CONV 0x40 /* Parameter duplicated in converted form */
#define JF_START 0x0001 /* -c */
#define JF_SET 0x0002 /* -m */
@ -93,16 +94,23 @@ enum intparam {
IP_INTERFACE, /* Add IP addresses to this interface */
IP_IP_HOSTNAME, /* Get jail IP address(es) from hostname */
IP_MOUNT, /* Mount points in fstab(5) form */
IP_MOUNT_FSTAB, /* A standard fstab(5) file */
IP_MOUNT_DEVFS, /* Mount /dev under prison root */
IP_MOUNT_DEVFS_RULESET, /* Ruleset for the devfs mount */
IP_MOUNT_FSTAB, /* A standard fstab(5) file */
IP_STOP_TIMEOUT, /* Time to wait after sending SIGTERM */
IP_VNET_INTERFACE, /* Assign interface(s) to vnet jail */
IP__IP4_IFADDR, /* Copy of ip4.addr with interface/netmask */
#ifdef INET6
IP__IP6_IFADDR, /* Copy of ip6.addr with interface/prefixlen */
#endif
IP_VNET_INTERFACE, /* Assign interface(s) to vnet jail */
KP_HOSTNAME,
KP_ALLOW_CHFLAGS,
KP_ALLOW_MOUNT,
KP_ALLOW_RAW_SOCKETS,
KP_ALLOW_SET_HOSTNAME,
KP_ALLOW_SOCKET_AF,
KP_ALLOW_SYSVIPC,
KP_ENFORCE_STATFS,
KP_HOST_HOSTNAME,
KP_IP4_ADDR,
#ifdef INET6
KP_IP6_ADDR,
@ -111,6 +119,7 @@ enum intparam {
KP_NAME,
KP_PATH,
KP_PERSIST,
KP_SECURELEVEL,
KP_VNET,
IP_NPARAM
};
@ -187,8 +196,7 @@ extern int term_procs(struct cfjail *j);
extern void load_config(void);
extern struct cfjail *add_jail(void);
extern void add_param(struct cfjail *j, const struct cfparam *p,
const char *name, const char *value);
extern void find_intparams(void);
enum intparam ipnum, const char *value);
extern int check_intparams(struct cfjail *j);
extern int bool_param(const struct cfparam *p);
extern int int_param(const struct cfparam *p, int *ip);