FreeBSD/usr.sbin/jail/config.c
/*
 * Add a parameter to a jail.
 */
Add a parameter to a jail.
Add a parameter to a jail .
void
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;
	const char *name;
	char *cs, *tname;
	unsigned flags;
	if (j == NULL) {
		j = TAILQ_LAST(&cfjails, cfjails);
		if (j == NULL)
			j = add_jail();
	}
	TAILQ_INIT(&nss);
	if (p != NULL) {
		name = p->name;
		flags = p->flags;
		TAILQ_FOREACH(s, &p->val, tq) {
			ns = emalloc(sizeof(struct cfstring));
			ns->s = estrdup(s->s);
			ns->len = s->len;
			STAILQ_INIT(&ns->vars);
			STAILQ_FOREACH(v, &s->vars, tq) {
				nv = emalloc(sizeof(struct cfvar));
				nv->name = strdup(v->name);
				nv->pos = v->pos;
				STAILQ_INSERT_TAIL(&ns->vars, nv, tq);
			}
			TAILQ_INSERT_TAIL(&nss, ns, tq);
		}
	} else {
		flags = PF_APPEND;
		if (ipnum != IP__NULL) {
			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);
			ns->len = strlen(value);
			STAILQ_INIT(&ns->vars);
			TAILQ_INSERT_TAIL(&nss, ns, tq);
		}
	}
	if (ipnum != IP__NULL)
		dp = j->intparams[ipnum];
	else
		TAILQ_FOREACH(dp, &j->params, tq)
			if (!(dp->flags & PF_CONV) && equalopts(dp->name, name))
				break;
	if (dp != NULL) {
		if (dp->flags & PF_IMMUTABLE) {
			jail_warnx(j, "cannot redefine variable \"%s\".",
			    dp->name);
			return;
		}
		if (strcmp(dp->name, name)) {
			free(dp->name);
			dp->name = estrdup(name);
		}
		if (!(flags & PF_APPEND) || TAILQ_EMPTY(&nss))
			free_param_strings(dp);
		TAILQ_CONCAT(&dp->val, &nss, tq);
		dp->flags |= flags;
	} else {
		np = emalloc(sizeof(struct cfparam));
		np->name = estrdup(name);
		TAILQ_INIT(&np->val);
		TAILQ_CONCAT(&np->val, &nss, tq);
		np->flags = flags;
		np->gen = 0;
		TAILQ_INSERT_TAIL(&j->params, np, tq);
		if (ipnum != IP__NULL)
			j->intparams[ipnum] = np;
		else
			for (ipnum = IP__NULL + 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;
				}
	}
}
void 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 ; const char * name ; char * cs , * tname ; unsigned flags ; if ( j == NULL ) { j = TAILQ_LAST ( & cfjails , cfjails ) ; if ( j == NULL ) j = add_jail ( ) ; } TAILQ_INIT ( & nss ) ; if ( p != NULL ) { name = p -> name ; flags = p -> flags ; TAILQ_FOREACH ( s , & p -> val , tq ) { ns = emalloc ( sizeof ( struct cfstring ) ) ; ns -> s = estrdup ( s -> s ) ; ns -> len = s -> len ; STAILQ_INIT ( & ns -> vars ) ; STAILQ_FOREACH ( v , & s -> vars , tq ) { nv = emalloc ( sizeof ( struct cfvar ) ) ; nv -> name = strdup ( v -> name ) ; nv -> pos = v -> pos ; STAILQ_INSERT_TAIL ( & ns -> vars , nv , tq ) ; } TAILQ_INSERT_TAIL ( & nss , ns , tq ) ; } } else { flags = PF_APPEND ; if ( ipnum != IP__NULL ) { 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 ) ; ns -> len = strlen ( value ) ; STAILQ_INIT ( & ns -> vars ) ; TAILQ_INSERT_TAIL ( & nss , ns , tq ) ; } } if ( ipnum != IP__NULL ) dp = j -> intparams [ ipnum ] ; else TAILQ_FOREACH ( dp , & j -> params , tq ) if ( ! ( dp -> flags & PF_CONV ) && equalopts ( dp -> name , name ) ) break ; if ( dp != NULL ) { if ( dp -> flags & PF_IMMUTABLE ) { jail_warnx ( j , " \" \" " , dp -> name ) ; return ; } if ( strcmp ( dp -> name , name ) ) { free ( dp -> name ) ; dp -> name = estrdup ( name ) ; } if ( ! ( flags & PF_APPEND ) || TAILQ_EMPTY ( & nss ) ) free_param_strings ( dp ) ; TAILQ_CONCAT ( & dp -> val , & nss , tq ) ; dp -> flags |= flags ; } else { np = emalloc ( sizeof ( struct cfparam ) ) ; np -> name = estrdup ( name ) ; TAILQ_INIT ( & np -> val ) ; TAILQ_CONCAT ( & np -> val , & nss , tq ) ; np -> flags = flags ; np -> gen = 0 ; TAILQ_INSERT_TAIL ( & j -> params , np , tq ) ; if ( ipnum != IP__NULL ) j -> intparams [ ipnum ] = np ; else for ( ipnum = IP__NULL + 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 ; } } }
Add a parameter to a jail.
Add a parameter to a jail .
/* Create a single anonymous jail if one doesn't yet exist. */ /*
		 * Make a copy of the parameter's string list,
		 * which may be freed if it's overridden later.
		 */ /* See if this parameter has already been added. */ /* Found it - append or replace. */ /* Not found - add it. */