return ENOTSUP;
}
+/*
+ * setsid_internal
+ *
+ * Description: Core implementation of setsid().
+ */
+int
+setsid_internal(proc_t p)
+{
+ struct pgrp * pg = PGRP_NULL;
+
+ if (p->p_pgrpid == p->p_pid || (pg = pgfind(p->p_pid)) || p->p_lflag & P_LINVFORK) {
+ if (pg != PGRP_NULL) {
+ pg_rele(pg);
+ }
+ return EPERM;
+ } else {
+ /* enter pgrp works with its own pgrp refcount */
+ (void)enterpgrp(p, p->p_pid, 1);
+ return 0;
+ }
+}
/*
* setsid
int
setsid(proc_t p, __unused struct setsid_args *uap, int32_t *retval)
{
- struct pgrp * pg = PGRP_NULL;
-
- if (p->p_pgrpid == p->p_pid || (pg = pgfind(p->p_pid)) || p->p_lflag & P_LINVFORK) {
- if (pg != PGRP_NULL) {
- pg_rele(pg);
- }
- return EPERM;
- } else {
- /* enter pgrp works with its own pgrp refcount */
- (void)enterpgrp(p, p->p_pid, 1);
+ int rc = setsid_internal(p);
+ if (rc == 0) {
*retval = p->p_pid;
- return 0;
}
+ return rc;
}
* flag the process as having set privilege since the last exec.
*/
static int
-setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval)
+setgroups1(proc_t p, u_int ngrp, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval)
{
- u_int ngrp;
gid_t newgroups[NGROUPS] = { 0 };
int error;
- kauth_cred_t my_cred, my_new_cred;
- struct uthread *uthread = get_bsdthread_info(current_thread());
- DEBUG_CRED_ENTER("setgroups1 (%d/%d): %d 0x%016x %d\n", p->p_pid, (p->p_pptr ? p->p_pptr->p_pid : 0), gidsetsize, gidset, gmuid);
+ DEBUG_CRED_ENTER("setgroups1 (%d/%d): %d 0x%016x %d\n", p->p_pid,
+ (p->p_pptr ? p->p_pptr->p_pid : 0), ngrp, gidset, gmuid);
- ngrp = gidsetsize;
if (ngrp > NGROUPS) {
return EINVAL;
}
- if (ngrp < 1) {
- ngrp = 1;
- } else {
+ if (ngrp >= 1) {
error = copyin(gidset,
(caddr_t)newgroups, ngrp * sizeof(gid_t));
if (error) {
return error;
}
}
+ return setgroups_internal(p, ngrp, newgroups, gmuid);
+}
+
+int
+setgroups_internal(proc_t p, u_int ngrp, gid_t *newgroups, uid_t gmuid)
+{
+ struct uthread *uthread = get_bsdthread_info(current_thread());
+ kauth_cred_t my_cred, my_new_cred;
+ int error;
my_cred = kauth_cred_proc_ref(p);
if ((error = suser(my_cred, &p->p_acflag))) {
return error;
}
+ if (ngrp < 1) {
+ ngrp = 1;
+ newgroups[0] = 0;
+ }
+
if ((uthread->uu_flag & UT_SETUID) != 0) {
#if DEBUG_CRED
int my_cred_flags = uthread->uu_ucred->cr_flags;
return copyout((caddr_t)buffer, uap->namebuf, uap->namelen);
}
+void
+setlogin_internal(proc_t p, const char login[static MAXLOGNAME])
+{
+ struct session *sessp = proc_session(p);
+
+ if (sessp != SESSION_NULL) {
+ session_lock(sessp);
+ bcopy(login, sessp->s_login, MAXLOGNAME);
+ session_unlock(sessp);
+ session_rele(sessp);
+ }
+}
/*
* setlogin
int error;
size_t dummy = 0;
char buffer[MAXLOGNAME + 1];
- struct session * sessp;
if ((error = proc_suser(p))) {
return error;
(caddr_t) &buffer[0],
MAXLOGNAME - 1, (size_t *)&dummy);
- sessp = proc_session(p);
-
- if (sessp != SESSION_NULL) {
- session_lock(sessp);
- bcopy(buffer, sessp->s_login, MAXLOGNAME);
- session_unlock(sessp);
- session_rele(sessp);
- }
-
+ setlogin_internal(p, buffer);
if (!error) {
AUDIT_ARG(text, buffer);
return set_security_token_task_internal(p, p->task);
}
+static void
+proc_calc_audit_token(proc_t p, kauth_cred_t my_cred, audit_token_t *audit_token)
+{
+ posix_cred_t my_pcred = posix_cred_get(my_cred);
+
+ /*
+ * The current layout of the Mach audit token explicitly
+ * adds these fields. But nobody should rely on such
+ * a literal representation. Instead, the BSM library
+ * provides a function to convert an audit token into
+ * a BSM subject. Use of that mechanism will isolate
+ * the user of the trailer from future representation
+ * changes.
+ */
+ audit_token->val[0] = my_cred->cr_audit.as_aia_p->ai_auid;
+ audit_token->val[1] = my_pcred->cr_uid;
+ audit_token->val[2] = my_pcred->cr_gid;
+ audit_token->val[3] = my_pcred->cr_ruid;
+ audit_token->val[4] = my_pcred->cr_rgid;
+ audit_token->val[5] = p->p_pid;
+ audit_token->val[6] = my_cred->cr_audit.as_aia_p->ai_asid;
+ audit_token->val[7] = p->p_idversion;
+}
+
/*
* Set the secrity token of the task with current euid and eguid
* The function takes a proc and a task, where proc->task might point to a
int
set_security_token_task_internal(proc_t p, void *t)
{
+ kauth_cred_t my_cred;
security_token_t sec_token;
audit_token_t audit_token;
- kauth_cred_t my_cred;
- posix_cred_t my_pcred;
host_priv_t host_priv;
task_t task = t;
}
my_cred = kauth_cred_proc_ref(p);
- my_pcred = posix_cred_get(my_cred);
+
+ proc_calc_audit_token(p, my_cred, &audit_token);
/* XXX mach_init doesn't have a p_ucred when it calls this function */
if (IS_VALID_CRED(my_cred)) {
sec_token.val[1] = 0;
}
- /*
- * The current layout of the Mach audit token explicitly
- * adds these fields. But nobody should rely on such
- * a literal representation. Instead, the BSM library
- * provides a function to convert an audit token into
- * a BSM subject. Use of that mechanism will isolate
- * the user of the trailer from future representation
- * changes.
- */
- audit_token.val[0] = my_cred->cr_audit.as_aia_p->ai_auid;
- audit_token.val[1] = my_pcred->cr_uid;
- audit_token.val[2] = my_pcred->cr_gid;
- audit_token.val[3] = my_pcred->cr_ruid;
- audit_token.val[4] = my_pcred->cr_rgid;
- audit_token.val[5] = p->p_pid;
- audit_token.val[6] = my_cred->cr_audit.as_aia_p->ai_asid;
- audit_token.val[7] = p->p_idversion;
-
host_priv = (sec_token.val[0]) ? HOST_PRIV_NULL : host_priv_self();
#if CONFIG_MACF
if (host_priv != HOST_PRIV_NULL && mac_system_check_host_priv(my_cred)) {
host_priv) != KERN_SUCCESS;
}
+void
+proc_parent_audit_token(proc_t p, audit_token_t *token_out)
+{
+ proc_t parent;
+ kauth_cred_t my_cred;
+
+ proc_list_lock();
+
+ parent = p->p_pptr;
+ my_cred = kauth_cred_proc_ref(parent);
+ proc_calc_audit_token(parent, my_cred, token_out);
+ kauth_cred_unref(&my_cred);
+
+ proc_list_unlock();
+}
+
int get_audit_token_pid(audit_token_t *audit_token);