/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/times.h>
#include <sys/malloc.h>
+#include <bsm/audit_kernel.h>
+
#include <sys/mount.h>
#include <mach/message.h>
#include <mach/host_security.h>
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);
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);
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));
}
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);
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);
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);
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);
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;
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.
*/
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_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;
+ 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));
+}