diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c --- a/usr.sbin/jail/config.c +++ b/usr.sbin/jail/config.c @@ -470,6 +470,25 @@ } } +/* + * Return if nopersist parameter is explicitly provided. + */ +int +transition_to_nopersist(struct cfjail *j) +{ + struct jailparam *jp; + + // check if outcome of params sequence is that it's still persist + if (bool_param(j->intparams[KP_PERSIST])) + return 0; + + for (jp = j->jp; jp < j->jp + j->njp; jp++) + if (equalopts(jp->jp_name, "persist")) + return 1; + + return 0; +} + /* * Return if a boolean parameter exists and is true. */ diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c --- a/usr.sbin/jail/jail.c +++ b/usr.sbin/jail/jail.c @@ -106,6 +106,13 @@ IP__NULL }; +static const enum intparam startsetcommands[] = { + IP__NULL, + IP_EXEC_START, + IP_COMMAND, + IP__NULL +}; + static const enum intparam stopcommands[] = { IP__NULL, IP_EXEC_PRESTOP, @@ -412,7 +419,7 @@ * depending on the jail's current status. */ case JF_START_SET: - j->flags = j->jid < 0 ? JF_START : JF_SET; + j->flags = j->jid < 0 ? JF_START : JF_START_SET; break; case JF_SET_RESTART: if (j->jid < 0) { @@ -477,6 +484,29 @@ dep_done(j, 0); break; + case JF_START_SET: + if (dep_check(j)) + continue; + if (transition_to_nopersist(j) && + (j->intparams[IP_EXEC_START] || + j->intparams[IP_COMMAND])) { + j->flags |= JF_PERSIST; + } + if (!(j->flags & JF_DEPEND) && j->comparam == NULL) { + if (rdtun_params(j, 1) < 0 || + update_jail(j) < 0) + continue; + if (verbose >= 0 && (j->name || verbose > 0)) + jail_note(j, "updated\n"); + j->comparam = startsetcommands; + j->comstring = NULL; + } + if (next_command(j)) + continue; + clear_persist(j); + dep_done(j, 0); + break; + case JF_STOP: case JF_RESTART: if (j->comparam == NULL) { @@ -758,7 +788,8 @@ ns = 0; for (jp = j->jp; jp < j->jp + j->njp; jp++) - if (!JP_RDTUN(jp)) + if (!JP_RDTUN(jp) && !((j->flags & JF_PERSIST) && + equalopts(jp->jp_name, "persist"))) ns++; if (ns == 0) return 0; @@ -770,7 +801,8 @@ return -1; } for (jp = j->jp; jp < j->jp + j->njp; jp++) - if (!JP_RDTUN(jp)) + if (!JP_RDTUN(jp) && !((j->flags & JF_PERSIST) && + equalopts(jp->jp_name, "persist"))) *++sjp = *jp; jid = jailparam_set_note(j, setparams, ns, diff --git a/usr.sbin/jail/jailp.h b/usr.sbin/jail/jailp.h --- a/usr.sbin/jail/jailp.h +++ b/usr.sbin/jail/jailp.h @@ -218,6 +218,7 @@ extern struct cfjail *add_jail(void); extern void add_param(struct cfjail *j, const struct cfparam *p, enum intparam ipnum, const char *value); +extern int transition_to_nopersist(struct cfjail *j); extern int bool_param(const struct cfparam *p); extern int int_param(const struct cfparam *p, int *ip); extern const char *string_param(const struct cfparam *p);