Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_rctl.c
Show First 20 Lines • Show All 1,169 Lines • ▼ Show 20 Lines | if (subject_idstr == NULL || subject_idstr[0] == '\0') { | ||||
switch (rule->rr_subject_type) { | switch (rule->rr_subject_type) { | ||||
case RCTL_SUBJECT_TYPE_UNDEFINED: | case RCTL_SUBJECT_TYPE_UNDEFINED: | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
case RCTL_SUBJECT_TYPE_PROCESS: | case RCTL_SUBJECT_TYPE_PROCESS: | ||||
error = str2id(subject_idstr, &id); | error = str2id(subject_idstr, &id); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
sx_assert(&allproc_lock, SA_LOCKED); | sx_assert(&V_allproc_lock, SA_LOCKED); | ||||
rule->rr_subject.rs_proc = pfind(id); | rule->rr_subject.rs_proc = pfind(id); | ||||
if (rule->rr_subject.rs_proc == NULL) { | if (rule->rr_subject.rs_proc == NULL) { | ||||
error = ESRCH; | error = ESRCH; | ||||
goto out; | goto out; | ||||
} | } | ||||
PROC_UNLOCK(rule->rr_subject.rs_proc); | PROC_UNLOCK(rule->rr_subject.rs_proc); | ||||
break; | break; | ||||
case RCTL_SUBJECT_TYPE_USER: | case RCTL_SUBJECT_TYPE_USER: | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Link a rule with all the subjects it applies to. | * Link a rule with all the subjects it applies to. | ||||
*/ | */ | ||||
int | int | ||||
rctl_rule_add(struct rctl_rule *rule) | rctl_rule_add(struct rctl_rule *rule) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct proc *p; | struct proc *p; | ||||
struct ucred *cred; | struct ucred *cred; | ||||
struct uidinfo *uip; | struct uidinfo *uip; | ||||
struct prison *pr; | struct prison *pr; | ||||
struct prison_racct *prr; | struct prison_racct *prr; | ||||
struct loginclass *lc; | struct loginclass *lc; | ||||
struct rctl_rule *rule2; | struct rctl_rule *rule2; | ||||
int match; | int match; | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | default: | ||||
panic("rctl_rule_add: unknown subject type %d", | panic("rctl_rule_add: unknown subject type %d", | ||||
rule->rr_subject_type); | rule->rr_subject_type); | ||||
} | } | ||||
/* | /* | ||||
* Now go through all the processes and add the new rule to the ones | * Now go through all the processes and add the new rule to the ones | ||||
* it applies to. | * it applies to. | ||||
*/ | */ | ||||
sx_assert(&allproc_lock, SA_LOCKED); | sx_assert(&V_allproc_lock, SA_LOCKED); | ||||
VPS_LIST_RLOCK(); | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_slock(&V_allproc_lock); | |||||
#endif | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
cred = p->p_ucred; | cred = p->p_ucred; | ||||
switch (rule->rr_subject_type) { | switch (rule->rr_subject_type) { | ||||
case RCTL_SUBJECT_TYPE_USER: | case RCTL_SUBJECT_TYPE_USER: | ||||
if (cred->cr_uidinfo == rule->rr_subject.rs_uip || | if (cred->cr_uidinfo == rule->rr_subject.rs_uip || | ||||
cred->cr_ruidinfo == rule->rr_subject.rs_uip) | cred->cr_ruidinfo == rule->rr_subject.rs_uip) | ||||
break; | break; | ||||
continue; | continue; | ||||
case RCTL_SUBJECT_TYPE_LOGINCLASS: | case RCTL_SUBJECT_TYPE_LOGINCLASS: | ||||
if (cred->cr_loginclass == rule->rr_subject.rs_loginclass) | if (cred->cr_loginclass == rule->rr_subject.rs_loginclass) | ||||
break; | break; | ||||
continue; | continue; | ||||
case RCTL_SUBJECT_TYPE_JAIL: | case RCTL_SUBJECT_TYPE_JAIL: | ||||
match = 0; | match = 0; | ||||
for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) { | for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) { | ||||
if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) { | if (pr->pr_prison_racct == rule->rr_subject.rs_prison_racct) { | ||||
match = 1; | match = 1; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (match) | if (match) | ||||
break; | break; | ||||
continue; | continue; | ||||
default: | default: | ||||
panic("rctl_rule_add: unknown subject type %d", | panic("rctl_rule_add: unknown subject type %d", | ||||
rule->rr_subject_type); | rule->rr_subject_type); | ||||
} | } | ||||
rctl_racct_add_rule(p->p_racct, rule); | rctl_racct_add_rule(p->p_racct, rule); | ||||
} | } | ||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_sunlock(&V_allproc_lock); | |||||
#endif | |||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
rctl_rule_pre_callback(void) | rctl_rule_pre_callback(void) | ||||
{ | { | ||||
Show All 22 Lines | |||||
} | } | ||||
/* | /* | ||||
* Remove all rules that match the filter. | * Remove all rules that match the filter. | ||||
*/ | */ | ||||
int | int | ||||
rctl_rule_remove(struct rctl_rule *filter) | rctl_rule_remove(struct rctl_rule *filter) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct proc *p; | struct proc *p; | ||||
int found = 0; | int found = 0; | ||||
ASSERT_RACCT_ENABLED(); | ASSERT_RACCT_ENABLED(); | ||||
if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && | if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS && | ||||
filter->rr_subject.rs_proc != NULL) { | filter->rr_subject.rs_proc != NULL) { | ||||
p = filter->rr_subject.rs_proc; | p = filter->rr_subject.rs_proc; | ||||
Show All 10 Lines | loginclass_racct_foreach(rctl_rule_remove_callback, | ||||
filter, (void *)&found); | filter, (void *)&found); | ||||
ui_racct_foreach(rctl_rule_remove_callback, | ui_racct_foreach(rctl_rule_remove_callback, | ||||
rctl_rule_pre_callback, rctl_rule_post_callback, | rctl_rule_pre_callback, rctl_rule_post_callback, | ||||
filter, (void *)&found); | filter, (void *)&found); | ||||
prison_racct_foreach(rctl_rule_remove_callback, | prison_racct_foreach(rctl_rule_remove_callback, | ||||
rctl_rule_pre_callback, rctl_rule_post_callback, | rctl_rule_pre_callback, rctl_rule_post_callback, | ||||
filter, (void *)&found); | filter, (void *)&found); | ||||
sx_assert(&allproc_lock, SA_LOCKED); | sx_assert(&V_allproc_lock, SA_LOCKED); | ||||
RACCT_LOCK(); | RACCT_LOCK(); | ||||
VPS_LIST_RLOCK(); | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_slock(&V_allproc_lock); | |||||
#endif | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
found += rctl_racct_remove_rules(p->p_racct, filter); | found += rctl_racct_remove_rules(p->p_racct, filter); | ||||
} | } | ||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_sunlock(&V_allproc_lock); | |||||
#endif | |||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
RACCT_UNLOCK(); | RACCT_UNLOCK(); | ||||
if (found) | if (found) | ||||
return (0); | return (0); | ||||
return (ESRCH); | return (ESRCH); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 150 Lines • ▼ Show 20 Lines | sys_rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap) | ||||
error = priv_check(td, PRIV_RCTL_GET_RACCT); | error = priv_check(td, PRIV_RCTL_GET_RACCT); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sx_slock(&allproc_lock); | sx_slock(&V_allproc_lock); | ||||
error = rctl_string_to_rule(inputstr, &filter); | error = rctl_string_to_rule(inputstr, &filter); | ||||
free(inputstr, M_RCTL); | free(inputstr, M_RCTL); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
switch (filter->rr_subject_type) { | switch (filter->rr_subject_type) { | ||||
case RCTL_SUBJECT_TYPE_PROCESS: | case RCTL_SUBJECT_TYPE_PROCESS: | ||||
p = filter->rr_subject.rs_proc; | p = filter->rr_subject.rs_proc; | ||||
if (p == NULL) { | if (p == NULL) { | ||||
error = EINVAL; | error = EINVAL; | ||||
Show All 25 Lines | case RCTL_SUBJECT_TYPE_JAIL: | ||||
} | } | ||||
outputsbuf = rctl_racct_to_sbuf(prr->prr_racct, 1); | outputsbuf = rctl_racct_to_sbuf(prr->prr_racct, 1); | ||||
break; | break; | ||||
default: | default: | ||||
error = EINVAL; | error = EINVAL; | ||||
} | } | ||||
out: | out: | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen); | error = rctl_write_outbuf(outputsbuf, uap->outbufp, uap->outbuflen); | ||||
return (error); | return (error); | ||||
} | } | ||||
Show All 13 Lines | LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { | ||||
rctl_rule_to_sbuf(sb, link->rrl_rule); | rctl_rule_to_sbuf(sb, link->rrl_rule); | ||||
sbuf_printf(sb, ","); | sbuf_printf(sb, ","); | ||||
} | } | ||||
} | } | ||||
int | int | ||||
sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) | sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap) | ||||
{ | { | ||||
VPS_ITERATOR_DECL(vps_iter); | |||||
struct sbuf *sb; | struct sbuf *sb; | ||||
struct rctl_rule *filter; | struct rctl_rule *filter; | ||||
struct rctl_rule_link *link; | struct rctl_rule_link *link; | ||||
struct proc *p; | struct proc *p; | ||||
char *inputstr, *buf; | char *inputstr, *buf; | ||||
size_t bufsize; | size_t bufsize; | ||||
int error; | int error; | ||||
if (!racct_enable) | if (!racct_enable) | ||||
return (ENOSYS); | return (ENOSYS); | ||||
error = priv_check(td, PRIV_RCTL_GET_RULES); | error = priv_check(td, PRIV_RCTL_GET_RULES); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sx_slock(&allproc_lock); | sx_slock(&V_allproc_lock); | ||||
error = rctl_string_to_rule(inputstr, &filter); | error = rctl_string_to_rule(inputstr, &filter); | ||||
free(inputstr, M_RCTL); | free(inputstr, M_RCTL); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
bufsize = uap->outbuflen; | bufsize = uap->outbuflen; | ||||
if (bufsize > rctl_maxbufsize) { | if (bufsize > rctl_maxbufsize) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (E2BIG); | return (E2BIG); | ||||
} | } | ||||
buf = malloc(bufsize, M_RCTL, M_WAITOK); | buf = malloc(bufsize, M_RCTL, M_WAITOK); | ||||
sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); | sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); | ||||
KASSERT(sb != NULL, ("sbuf_new failed")); | KASSERT(sb != NULL, ("sbuf_new failed")); | ||||
VPS_LIST_RLOCK(); | |||||
VPS_FOREACH(vps_iter) { | |||||
CURVPS_SET(vps_iter); | |||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_slock(&V_allproc_lock); | |||||
#endif | |||||
FOREACH_PROC_IN_SYSTEM(p) { | FOREACH_PROC_IN_SYSTEM(p) { | ||||
RACCT_LOCK(); | RACCT_LOCK(); | ||||
LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) { | LIST_FOREACH(link, &p->p_racct->r_rule_links, | ||||
rrl_next) { | |||||
/* | /* | ||||
* Non-process rules will be added to the buffer later. | * Non-process rules will be added to the | ||||
* Adding them here would result in duplicated output. | * buffer later. Adding them here would result | ||||
* in duplicated output. | |||||
*/ | */ | ||||
if (link->rrl_rule->rr_subject_type != | if (link->rrl_rule->rr_subject_type != | ||||
RCTL_SUBJECT_TYPE_PROCESS) | RCTL_SUBJECT_TYPE_PROCESS) | ||||
continue; | continue; | ||||
if (!rctl_rule_matches(link->rrl_rule, filter)) | if (!rctl_rule_matches(link->rrl_rule, filter)) | ||||
continue; | continue; | ||||
rctl_rule_to_sbuf(sb, link->rrl_rule); | rctl_rule_to_sbuf(sb, link->rrl_rule); | ||||
sbuf_printf(sb, ","); | sbuf_printf(sb, ","); | ||||
} | } | ||||
RACCT_UNLOCK(); | RACCT_UNLOCK(); | ||||
} | } | ||||
#ifdef VIMAGE | |||||
if (saved_vps != vps_iter) | |||||
sx_sunlock(&V_allproc_lock); | |||||
#endif | |||||
CURVPS_RESTORE(); | |||||
} | |||||
VPS_LIST_RUNLOCK(); | |||||
loginclass_racct_foreach(rctl_get_rules_callback, | loginclass_racct_foreach(rctl_get_rules_callback, | ||||
rctl_rule_pre_callback, rctl_rule_post_callback, | rctl_rule_pre_callback, rctl_rule_post_callback, | ||||
filter, sb); | filter, sb); | ||||
ui_racct_foreach(rctl_get_rules_callback, | ui_racct_foreach(rctl_get_rules_callback, | ||||
rctl_rule_pre_callback, rctl_rule_post_callback, | rctl_rule_pre_callback, rctl_rule_post_callback, | ||||
filter, sb); | filter, sb); | ||||
prison_racct_foreach(rctl_get_rules_callback, | prison_racct_foreach(rctl_get_rules_callback, | ||||
rctl_rule_pre_callback, rctl_rule_post_callback, | rctl_rule_pre_callback, rctl_rule_post_callback, | ||||
filter, sb); | filter, sb); | ||||
if (sbuf_error(sb) == ENOMEM) { | if (sbuf_error(sb) == ENOMEM) { | ||||
error = ERANGE; | error = ERANGE; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* Remove trailing ",". | * Remove trailing ",". | ||||
*/ | */ | ||||
if (sbuf_len(sb) > 0) | if (sbuf_len(sb) > 0) | ||||
sbuf_setpos(sb, sbuf_len(sb) - 1); | sbuf_setpos(sb, sbuf_len(sb) - 1); | ||||
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); | error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); | ||||
out: | out: | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
free(buf, M_RCTL); | free(buf, M_RCTL); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) | sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) | ||||
{ | { | ||||
struct sbuf *sb; | struct sbuf *sb; | ||||
Show All 9 Lines | sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) | ||||
error = priv_check(td, PRIV_RCTL_GET_LIMITS); | error = priv_check(td, PRIV_RCTL_GET_LIMITS); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sx_slock(&allproc_lock); | sx_slock(&V_allproc_lock); | ||||
error = rctl_string_to_rule(inputstr, &filter); | error = rctl_string_to_rule(inputstr, &filter); | ||||
free(inputstr, M_RCTL); | free(inputstr, M_RCTL); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_UNDEFINED) { | if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_UNDEFINED) { | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_PROCESS) { | if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_PROCESS) { | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (EOPNOTSUPP); | return (EOPNOTSUPP); | ||||
} | } | ||||
if (filter->rr_subject.rs_proc == NULL) { | if (filter->rr_subject.rs_proc == NULL) { | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
bufsize = uap->outbuflen; | bufsize = uap->outbuflen; | ||||
if (bufsize > rctl_maxbufsize) { | if (bufsize > rctl_maxbufsize) { | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (E2BIG); | return (E2BIG); | ||||
} | } | ||||
buf = malloc(bufsize, M_RCTL, M_WAITOK); | buf = malloc(bufsize, M_RCTL, M_WAITOK); | ||||
sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); | sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN); | ||||
KASSERT(sb != NULL, ("sbuf_new failed")); | KASSERT(sb != NULL, ("sbuf_new failed")); | ||||
RACCT_LOCK(); | RACCT_LOCK(); | ||||
Show All 13 Lines | sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap) | ||||
* Remove trailing ",". | * Remove trailing ",". | ||||
*/ | */ | ||||
if (sbuf_len(sb) > 0) | if (sbuf_len(sb) > 0) | ||||
sbuf_setpos(sb, sbuf_len(sb) - 1); | sbuf_setpos(sb, sbuf_len(sb) - 1); | ||||
error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); | error = rctl_write_outbuf(sb, uap->outbufp, uap->outbuflen); | ||||
out: | out: | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
free(buf, M_RCTL); | free(buf, M_RCTL); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
sys_rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) | sys_rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap) | ||||
{ | { | ||||
struct rctl_rule *rule; | struct rctl_rule *rule; | ||||
char *inputstr; | char *inputstr; | ||||
int error; | int error; | ||||
if (!racct_enable) | if (!racct_enable) | ||||
return (ENOSYS); | return (ENOSYS); | ||||
error = priv_check(td, PRIV_RCTL_ADD_RULE); | error = priv_check(td, PRIV_RCTL_ADD_RULE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sx_slock(&allproc_lock); | sx_slock(&V_allproc_lock); | ||||
error = rctl_string_to_rule(inputstr, &rule); | error = rctl_string_to_rule(inputstr, &rule); | ||||
free(inputstr, M_RCTL); | free(inputstr, M_RCTL); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* The 'per' part of a rule is optional. | * The 'per' part of a rule is optional. | ||||
*/ | */ | ||||
if (rule->rr_per == RCTL_SUBJECT_TYPE_UNDEFINED && | if (rule->rr_per == RCTL_SUBJECT_TYPE_UNDEFINED && | ||||
rule->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) | rule->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) | ||||
rule->rr_per = rule->rr_subject_type; | rule->rr_per = rule->rr_subject_type; | ||||
if (!rctl_rule_fully_specified(rule)) { | if (!rctl_rule_fully_specified(rule)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
error = rctl_rule_add(rule); | error = rctl_rule_add(rule); | ||||
out: | out: | ||||
rctl_rule_release(rule); | rctl_rule_release(rule); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
sys_rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap) | sys_rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap) | ||||
{ | { | ||||
struct rctl_rule *filter; | struct rctl_rule *filter; | ||||
char *inputstr; | char *inputstr; | ||||
int error; | int error; | ||||
if (!racct_enable) | if (!racct_enable) | ||||
return (ENOSYS); | return (ENOSYS); | ||||
error = priv_check(td, PRIV_RCTL_REMOVE_RULE); | error = priv_check(td, PRIV_RCTL_REMOVE_RULE); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | error = rctl_read_inbuf(&inputstr, uap->inbufp, uap->inbuflen); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
sx_slock(&allproc_lock); | sx_slock(&V_allproc_lock); | ||||
error = rctl_string_to_rule(inputstr, &filter); | error = rctl_string_to_rule(inputstr, &filter); | ||||
free(inputstr, M_RCTL); | free(inputstr, M_RCTL); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
error = rctl_rule_remove(filter); | error = rctl_rule_remove(filter); | ||||
rctl_rule_release(filter); | rctl_rule_release(filter); | ||||
sx_sunlock(&allproc_lock); | sx_sunlock(&V_allproc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Update RCTL rule list after credential change. | * Update RCTL rule list after credential change. | ||||
*/ | */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 289 Lines • Show Last 20 Lines |