X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/bsd/kern/kern_prot.c diff --git a/bsd/kern/kern_prot.c b/bsd/kern/kern_prot.c index 5882e93cf..db25475d6 100644 --- a/bsd/kern/kern_prot.c +++ b/bsd/kern/kern_prot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -73,8 +73,12 @@ #include #include +#include + #include #include +#include + #include /* @@ -90,6 +94,7 @@ setprivexec(p, uap, retval) register struct setprivexec_args *uap; register_t *retval; { + AUDIT_ARG(value, uap->flag); *retval = p->p_debugger; p->p_debugger = (uap->flag != 0); return(0); @@ -131,6 +136,56 @@ getpgrp(p, uap, retval) return (0); } +/* Get an arbitary pid's process group id */ +struct getpgid_args { + pid_t pid; +}; + +int +getpgid(p, uap, retval) + struct proc *p; + struct getpgid_args *uap; + register_t *retval; +{ + struct proc *pt; + + pt = p; + if (uap->pid == 0) + goto found; + + if ((pt = pfind(uap->pid)) == 0) + return (ESRCH); +found: + *retval = pt->p_pgrp->pg_id; + return (0); +} + +/* + * Get an arbitary pid's session id. + */ +struct getsid_args { + pid_t pid; +}; + +int +getsid(p, uap, retval) + struct proc *p; + struct getsid_args *uap; + register_t *retval; +{ + struct proc *pt; + + pt = p; + if (uap->pid == 0) + goto found; + + if ((pt = pfind(uap->pid)) == 0) + return (ESRCH); +found: + *retval = pt->p_session->s_sid; + return (0); +} + /* ARGSUSED */ getuid(p, uap, retval) struct proc *p; @@ -224,7 +279,7 @@ setsid(p, uap, retval) register_t *retval; { - if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { + if (p->p_pgid == p->p_pid || pgfind(p->p_pid) || p->p_flag & P_INVFORK) { return (EPERM); } else { (void)enterpgrp(p, p->p_pid, 1); @@ -274,7 +329,7 @@ setpgid(curp, uap, retval) uap->pgid = targp->p_pid; else if (uap->pgid != targp->p_pid) if ((pgrp = pgfind(uap->pgid)) == 0 || - pgrp->pg_session != curp->p_session) + pgrp->pg_session != curp->p_session) return (EPERM); return (enterpgrp(targp, uap->pgid, 0)); } @@ -314,6 +369,7 @@ setuid(p, uap, retval) int error; uid = uap->uid; + AUDIT_ARG(uid, uid, 0, 0, 0); if (uid != pc->p_ruid && (error = suser(pc->pc_ucred, &p->p_acflag))) return (error); @@ -322,6 +378,9 @@ setuid(p, uap, retval) * Transfer proc count to new user. * Copy credentials so other references do not see our changes. */ + + /* prepare app access profile files */ + prepare_profile_database(uap->uid); pcred_writelock(p); (void)chgproccnt(pc->p_ruid, -1); (void)chgproccnt(uid, 1); @@ -349,6 +408,7 @@ seteuid(p, uap, retval) int error; euid = uap->euid; + AUDIT_ARG(uid, 0, euid, 0, 0); if (euid != pc->p_ruid && euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag))) return (error); @@ -379,6 +439,7 @@ setgid(p, uap, retval) int error; gid = uap->gid; + AUDIT_ARG(gid, gid, 0, 0, 0); if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag))) return (error); pcred_writelock(p); @@ -406,6 +467,7 @@ setegid(p, uap, retval) int error; egid = uap->egid; + AUDIT_ARG(gid, 0, egid, 0, 0); if (egid != pc->p_rgid && egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag))) return (error); @@ -437,16 +499,23 @@ setgroups(p, uap, retval) if (error = suser(pc->pc_ucred, &p->p_acflag)) return (error); ngrp = uap->gidsetsize; - if (ngrp < 1 || ngrp > NGROUPS) + if (ngrp > NGROUPS) return (EINVAL); new = crget(); - error = copyin((caddr_t)uap->gidset, - (caddr_t)new->cr_groups, ngrp * sizeof(gid_t)); - if (error) { - crfree(new); - return (error); + + if ( ngrp < 1 ) { + ngrp = 1; + } + else { + error = copyin((caddr_t)uap->gidset, + (caddr_t)new->cr_groups, ngrp * sizeof(gid_t)); + if (error) { + crfree(new); + return (error); + } } new->cr_ngroups = ngrp; + AUDIT_ARG(groupset, new->cr_groups, ngrp); pcred_writelock(p); old = pc->pc_ucred; new->cr_uid = old->cr_uid; @@ -664,6 +733,32 @@ crdup(cr) return (newcr); } +/* + * compare two cred structs + */ +int +crcmp(cr1, cr2) + struct ucred *cr1; + struct ucred *cr2; +{ + int i; + + if (cr1 == cr2) + return 0; + if (cr1 == NOCRED || cr1 == FSCRED || + cr2 == NOCRED || cr2 == FSCRED) + return 1; + if (cr1->cr_uid != cr2->cr_uid) + return 1; + if (cr1->cr_ngroups != cr2->cr_ngroups) + return 1; + // XXX assumes groups will always be listed in some order + for (i=0; i < cr1->cr_ngroups; i++) + if (cr1->cr_groups[i] != cr2->cr_groups[i]) + return 1; + return (0); +} + /* * Get login name, if available. */ @@ -705,24 +800,63 @@ setlogin(p, uap, retval) error = copyinstr((caddr_t) uap->namebuf, (caddr_t) p->p_pgrp->pg_session->s_login, sizeof (p->p_pgrp->pg_session->s_login) - 1, (size_t *)&dummy); - if (error == ENAMETOOLONG) + if(!error) + AUDIT_ARG(text, p->p_pgrp->pg_session->s_login); + else if (error == ENAMETOOLONG) error = EINVAL; return (error); } /* Set the secrity token of the task with current euid and eguid */ -void +kern_return_t set_security_token(struct proc * p) { security_token_t sec_token; + audit_token_t audit_token; sec_token.val[0] = p->p_ucred->cr_uid; - sec_token.val[1] = p->p_ucred->cr_gid; - (void)host_security_set_task_token(host_security_self(), + sec_token.val[1] = p->p_ucred->cr_gid; + + /* + * 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] = p->p_au->ai_auid; + audit_token.val[1] = p->p_ucred->cr_uid; + audit_token.val[2] = p->p_ucred->cr_gid; + audit_token.val[3] = p->p_cred->p_ruid; + audit_token.val[4] = p->p_cred->p_rgid; + audit_token.val[5] = p->p_pid; + audit_token.val[6] = p->p_au->ai_asid; + audit_token.val[7] = p->p_au->ai_termid.port; + + return host_security_set_task_token(host_security_self(), p->task, sec_token, + audit_token, (sec_token.val[0]) ? - HOST_PRIV_NULL : + HOST_PRIV_NULL : host_priv_self()); } + + +/* + * Fill in a struct xucred based on a struct ucred. + */ +__private_extern__ +void +cru2x(struct ucred *cr, struct xucred *xcr) +{ + + bzero(xcr, sizeof(*xcr)); + xcr->cr_version = XUCRED_VERSION; + xcr->cr_uid = cr->cr_uid; + xcr->cr_ngroups = cr->cr_ngroups; + bcopy(cr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups)); +}