Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/jail/jail.c
Context not available. | |||||
static void clear_persist(struct cfjail *j); | static void clear_persist(struct cfjail *j); | ||||
static int update_jail(struct cfjail *j); | static int update_jail(struct cfjail *j); | ||||
static int rdtun_params(struct cfjail *j, int dofail); | static int rdtun_params(struct cfjail *j, int dofail); | ||||
static void running_jid(struct cfjail *j, int dflag); | static void running_jid(struct cfjail *j); | ||||
static void jail_quoted_warnx(const struct cfjail *j, const char *name_msg, | static void jail_quoted_warnx(const struct cfjail *j, const char *name_msg, | ||||
const char *noname_msg); | const char *noname_msg); | ||||
static int jailparam_set_note(const struct cfjail *j, struct jailparam *jp, | static int jailparam_set_note(const struct cfjail *j, struct jailparam *jp, | ||||
Context not available. | |||||
char *JidFile; | char *JidFile; | ||||
size_t sysvallen; | size_t sysvallen; | ||||
unsigned op, pi; | unsigned op, pi; | ||||
int ch, docf, error, i, oldcl, sysval; | int ch, docf, error, i, oldcl, sysval, dying_warned; | ||||
int dflag, Rflag; | int dflag, Rflag; | ||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
char *cs, *ncs; | char *cs, *ncs; | ||||
Context not available. | |||||
* operation on it. When that is done, the jail may be finished, | * operation on it. When that is done, the jail may be finished, | ||||
* or it may go back for the next step. | * or it may go back for the next step. | ||||
*/ | */ | ||||
dying_warned = 0; | |||||
while ((j = next_jail())) | while ((j = next_jail())) | ||||
{ | { | ||||
if (j->flags & JF_FAILED) { | if (j->flags & JF_FAILED) { | ||||
Context not available. | |||||
import_params(j) < 0) | import_params(j) < 0) | ||||
continue; | continue; | ||||
} | } | ||||
if (j->intparams[IP_ALLOW_DYING] && !dying_warned) { | |||||
warnx("%s", "the 'allow.dying' parameter and '-d' flag" | |||||
"are deprecated and have no effect."); | |||||
dying_warned = 1; | |||||
} | |||||
if (!j->jid) | if (!j->jid) | ||||
running_jid(j, | running_jid(j); | ||||
(j->flags & (JF_SET | JF_DEPEND)) == JF_SET | |||||
? dflag || bool_param(j->intparams[IP_ALLOW_DYING]) | |||||
: 0); | |||||
if (finish_command(j)) | if (finish_command(j)) | ||||
continue; | continue; | ||||
Context not available. | |||||
int | int | ||||
create_jail(struct cfjail *j) | create_jail(struct cfjail *j) | ||||
{ | { | ||||
struct iovec jiov[4]; | |||||
struct stat st; | struct stat st; | ||||
struct jailparam *jp, *setparams, *setparams2, *sjp; | struct jailparam *jp, *setparams, *sjp; | ||||
const char *path; | const char *path; | ||||
int dopersist, ns, jid, dying, didfail; | int dopersist, ns; | ||||
/* | /* | ||||
* Check the jail's path, with a better error message than jail_set | * Check the jail's path, with a better error message than jail_set | ||||
Context not available. | |||||
*sjp++ = *jp; | *sjp++ = *jp; | ||||
ns = sjp - setparams; | ns = sjp - setparams; | ||||
didfail = 0; | |||||
j->jid = jailparam_set_note(j, setparams, ns, JAIL_CREATE); | j->jid = jailparam_set_note(j, setparams, ns, JAIL_CREATE); | ||||
if (j->jid < 0 && errno == EEXIST && | if (j->jid < 0) { | ||||
bool_param(j->intparams[IP_ALLOW_DYING]) && | |||||
int_param(j->intparams[KP_JID], &jid) && jid != 0) { | |||||
/* | |||||
* The jail already exists, but may be dying. | |||||
* Make sure it is, in which case an update is appropriate. | |||||
*/ | |||||
jiov[0].iov_base = __DECONST(char *, "jid"); | |||||
jiov[0].iov_len = sizeof("jid"); | |||||
jiov[1].iov_base = &jid; | |||||
jiov[1].iov_len = sizeof(jid); | |||||
jiov[2].iov_base = __DECONST(char *, "dying"); | |||||
jiov[2].iov_len = sizeof("dying"); | |||||
jiov[3].iov_base = &dying; | |||||
jiov[3].iov_len = sizeof(dying); | |||||
if (jail_get(jiov, 4, JAIL_DYING) < 0) { | |||||
/* | |||||
* It could be that the jail just barely finished | |||||
* dying, or it could be that the jid never existed | |||||
* but the name does. In either case, another try | |||||
* at creating the jail should do the right thing. | |||||
*/ | |||||
if (errno == ENOENT) | |||||
j->jid = jailparam_set_note(j, setparams, ns, | |||||
JAIL_CREATE); | |||||
} else if (dying) { | |||||
j->jid = jid; | |||||
if (rdtun_params(j, 1) < 0) { | |||||
j->jid = -1; | |||||
didfail = 1; | |||||
} else { | |||||
sjp = setparams2 = alloca((j->njp + dopersist) * | |||||
sizeof(struct jailparam)); | |||||
for (jp = setparams; jp < setparams + ns; jp++) | |||||
if (!JP_RDTUN(jp) || | |||||
!strcmp(jp->jp_name, "jid")) | |||||
*sjp++ = *jp; | |||||
j->jid = jailparam_set_note(j, setparams2, | |||||
sjp - setparams2, JAIL_UPDATE | JAIL_DYING); | |||||
/* | |||||
* Again, perhaps the jail just finished dying. | |||||
*/ | |||||
if (j->jid < 0 && errno == ENOENT) | |||||
j->jid = jailparam_set_note(j, | |||||
setparams, ns, JAIL_CREATE); | |||||
} | |||||
} | |||||
} | |||||
if (j->jid < 0 && !didfail) { | |||||
jail_warnx(j, "%s", jail_errmsg); | jail_warnx(j, "%s", jail_errmsg); | ||||
failed(j); | failed(j); | ||||
} | } | ||||
Context not available. | |||||
if (!JP_RDTUN(jp)) | if (!JP_RDTUN(jp)) | ||||
*++sjp = *jp; | *++sjp = *jp; | ||||
jid = jailparam_set_note(j, setparams, ns, | jid = jailparam_set_note(j, setparams, ns, JAIL_UPDATE); | ||||
bool_param(j->intparams[IP_ALLOW_DYING]) | |||||
? JAIL_UPDATE | JAIL_DYING : JAIL_UPDATE); | |||||
if (jid < 0) { | if (jid < 0) { | ||||
jail_warnx(j, "%s", jail_errmsg); | jail_warnx(j, "%s", jail_errmsg); | ||||
failed(j); | failed(j); | ||||
Context not available. | |||||
rtjp->jp_value = NULL; | rtjp->jp_value = NULL; | ||||
} | } | ||||
rval = 0; | rval = 0; | ||||
if (jailparam_get(rtparams, nrt, | if (jailparam_get(rtparams, nrt, 0) > 0) { | ||||
bool_param(j->intparams[IP_ALLOW_DYING]) ? JAIL_DYING : 0) > 0) { | |||||
rtjp = rtparams + 1; | rtjp = rtparams + 1; | ||||
for (jp = j->jp; rtjp < rtparams + nrt; jp++) { | for (jp = j->jp; rtjp < rtparams + nrt; jp++) { | ||||
if (JP_RDTUN(jp) && strcmp(jp->jp_name, "jid")) { | if (JP_RDTUN(jp) && strcmp(jp->jp_name, "jid")) { | ||||
Context not available. | |||||
* Get the jail's jid if it is running. | * Get the jail's jid if it is running. | ||||
*/ | */ | ||||
static void | static void | ||||
running_jid(struct cfjail *j, int dflag) | running_jid(struct cfjail *j) | ||||
{ | { | ||||
struct iovec jiov[2]; | struct iovec jiov[2]; | ||||
const char *pval; | const char *pval; | ||||
Context not available. | |||||
j->jid = -1; | j->jid = -1; | ||||
return; | return; | ||||
} | } | ||||
j->jid = jail_get(jiov, 2, dflag ? JAIL_DYING : 0); | j->jid = jail_get(jiov, 2, 0); | ||||
} | } | ||||
static void | static void | ||||
Context not available. | |||||
jid = jailparam_set(jp, njp, flags); | jid = jailparam_set(jp, njp, flags); | ||||
if (verbose > 0) { | if (verbose > 0) { | ||||
jail_note(j, "jail_set(%s%s)", | jail_note(j, "jail_set(%s)", | ||||
(flags & (JAIL_CREATE | JAIL_UPDATE)) == JAIL_CREATE | (flags & (JAIL_CREATE | JAIL_UPDATE)) == JAIL_CREATE | ||||
? "JAIL_CREATE" : "JAIL_UPDATE", | ? "JAIL_CREATE" : "JAIL_UPDATE"); | ||||
(flags & JAIL_DYING) ? " | JAIL_DYING" : ""); | |||||
for (i = 0; i < njp; i++) { | for (i = 0; i < njp; i++) { | ||||
printf(" %s", jp[i].jp_name); | printf(" %s", jp[i].jp_name); | ||||
if (jp[i].jp_value == NULL) | if (jp[i].jp_value == NULL) | ||||
Context not available. |