/* * Set the audit userid, for a process. This can only be changed by * privileged processes. The audit userid is inherited across forks & execs. * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT. */ int setauid(caddr_t auid_p) { proc_t *p; au_id_t auid; cred_t *newcred; auditinfo_addr_t *auinfo; if (secpolicy_audit_config(CRED()) != 0) return (EPERM); if (copyin(auid_p, &auid, sizeof (au_id_t))) { return (EFAULT); } newcred = cralloc(); if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) { crfree(newcred); return (EINVAL); } /* grab p_crlock and switch to new cred */ p = curproc; mutex_enter(&p->p_crlock); crcopy_to(p->p_cred, newcred); p->p_cred = newcred; auinfo->ai_auid = auid; /* update the auid */ /* unlock and broadcast the cred changes */ mutex_exit(&p->p_crlock); crset(p, newcred); return (0); }
/*ARGSUSED1*/ int auditsys(struct auditcalls *uap, rval_t *rvp) { int err; /* * this ugly hack is because auditsys returns * 0 for all cases except audit_active == 0 * and uap->code == BSM_AUDITCTL || default) */ if (!audit_active) return (ENOTSUP); switch (uap->code) { case BSM_GETAUID: case BSM_SETAUID: case BSM_GETAUDIT: case BSM_SETAUDIT: case BSM_AUDIT: return (0); case BSM_AUDITCTL: if ((int)uap->a1 == A_GETCOND) err = secpolicy_audit_getattr(CRED()); else /* FALLTHROUGH */ default: /* Return a different error when not privileged */ err = secpolicy_audit_config(CRED()); if (err == 0) return (EINVAL); else return (err); } }
/*ARGSUSED1*/ int auditsys(struct auditcalls *uap, rval_t *rvp) { int err; int result = 0; if (audit_active == C2AUDIT_DISABLED) return (ENOTSUP); switch (uap->code) { case BSM_GETAUID: result = getauid((caddr_t)uap->a1); break; case BSM_SETAUID: result = setauid((caddr_t)uap->a1); break; case BSM_GETAUDIT: result = getaudit((caddr_t)uap->a1); break; case BSM_GETAUDIT_ADDR: result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2); break; case BSM_SETAUDIT: result = setaudit((caddr_t)uap->a1); break; case BSM_SETAUDIT_ADDR: result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2); break; case BSM_AUDITCTL: result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3); break; case BSM_AUDIT: if (audit_active == C2AUDIT_UNLOADED) return (0); result = audit((caddr_t)uap->a1, (int)uap->a2); break; case BSM_AUDITDOOR: if (audit_active == C2AUDIT_LOADED) { result = auditdoor((int)uap->a1); break; } default: if (audit_active == C2AUDIT_LOADED) { result = EINVAL; break; } /* Return a different error when not privileged */ err = secpolicy_audit_config(CRED()); if (err == 0) return (EINVAL); else return (err); } rvp->r_vals = result; return (result); }
/* * Set the audit state information for the current process. * Return EFAULT if copyout fails. */ int setaudit(caddr_t info_p) { STRUCT_DECL(auditinfo, info); proc_t *p; cred_t *newcred; model_t model; auditinfo_addr_t *ainfo; if (secpolicy_audit_config(CRED()) != 0) return (EPERM); model = get_udatamodel(); STRUCT_INIT(info, model); if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) return (EFAULT); newcred = cralloc(); if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { crfree(newcred); return (EINVAL); } /* grab p_crlock and switch to new cred */ p = curproc; mutex_enter(&p->p_crlock); crcopy_to(p->p_cred, newcred); p->p_cred = newcred; /* Set audit mask, id, termid and session id as specified */ ainfo->ai_auid = STRUCT_FGET(info, ai_auid); #ifdef _LP64 /* only convert to 64 bit if coming from a 32 bit binary */ if (model == DATAMODEL_ILP32) ainfo->ai_termid.at_port = DEVEXPL(STRUCT_FGET(info, ai_termid.port)); else ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port); #else ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port); #endif ainfo->ai_termid.at_type = AU_IPv4; ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine); ainfo->ai_asid = STRUCT_FGET(info, ai_asid); ainfo->ai_mask = STRUCT_FGET(info, ai_mask); /* unlock and broadcast the cred changes */ mutex_exit(&p->p_crlock); crset(p, newcred); return (0); }
/* * Set the audit state information for the current process. * Return EFAULT if copyin fails. */ int setaudit_addr(caddr_t info_p, int len) { STRUCT_DECL(auditinfo_addr, info); proc_t *p; cred_t *newcred; model_t model; int i; int type; auditinfo_addr_t *ainfo; if (secpolicy_audit_config(CRED()) != 0) return (EPERM); model = get_udatamodel(); STRUCT_INIT(info, model); if (len < STRUCT_SIZE(info)) return (EOVERFLOW); if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) return (EFAULT); type = STRUCT_FGET(info, ai_termid.at_type); if ((type != AU_IPv4) && (type != AU_IPv6)) return (EINVAL); newcred = cralloc(); if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { crfree(newcred); return (EINVAL); } /* grab p_crlock and switch to new cred */ p = curproc; mutex_enter(&p->p_crlock); crcopy_to(p->p_cred, newcred); p->p_cred = newcred; /* Set audit mask, id, termid and session id as specified */ ainfo->ai_auid = STRUCT_FGET(info, ai_auid); ainfo->ai_mask = STRUCT_FGET(info, ai_mask); #ifdef _LP64 /* only convert to 64 bit if coming from a 32 bit binary */ if (model == DATAMODEL_ILP32) ainfo->ai_termid.at_port = DEVEXPL(STRUCT_FGET(info, ai_termid.at_port)); else ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); #else ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); #endif ainfo->ai_termid.at_type = type; bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr)); for (i = 0; i < (type/sizeof (int)); i++) ainfo->ai_termid.at_addr[i] = STRUCT_FGET(info, ai_termid.at_addr[i]); if (ainfo->ai_termid.at_type == AU_IPv6 && IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) { ainfo->ai_termid.at_type = AU_IPv4; ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3]; ainfo->ai_termid.at_addr[1] = 0; ainfo->ai_termid.at_addr[2] = 0; ainfo->ai_termid.at_addr[3] = 0; } ainfo->ai_asid = STRUCT_FGET(info, ai_asid); /* unlock and broadcast the cred changes */ mutex_exit(&p->p_crlock); crset(p, newcred); return (0); }
/* * The out of control system call * This is audit kitchen sink aka auditadm, aka auditon */ int auditctl( int cmd, caddr_t data, int length) { int result; switch (cmd) { case A_GETAMASK: case A_GETCOND: case A_GETCAR: case A_GETCLASS: case A_GETCWD: case A_GETKAUDIT: case A_GETKMASK: case A_GETPINFO: case A_GETPINFO_ADDR: case A_GETPOLICY: case A_GETQCTRL: case A_GETSTAT: if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0) return (EPERM); break; default: if (secpolicy_audit_config(CRED()) != 0) return (EPERM); break; } switch (cmd) { case A_GETPOLICY: result = getpolicy(data); break; case A_SETPOLICY: result = setpolicy(data); break; case A_GETAMASK: result = getamask(data); break; case A_SETAMASK: result = setamask(data); break; case A_GETKMASK: result = getkmask(data); break; case A_SETKMASK: result = setkmask(data); break; case A_GETKAUDIT: result = getkaudit(data, length); break; case A_SETKAUDIT: result = setkaudit(data, length); break; case A_GETQCTRL: result = getqctrl(data); break; case A_SETQCTRL: result = setqctrl(data); break; case A_GETCWD: result = getcwd(data, length); break; case A_GETCAR: result = getcar(data, length); break; case A_GETSTAT: result = getstat(data); break; case A_SETSTAT: result = setstat(data); break; case A_SETUMASK: result = setumask(data); break; case A_SETSMASK: result = setsmask(data); break; case A_GETCOND: result = getcond(data); break; case A_SETCOND: result = setcond(data); break; case A_GETCLASS: result = getclass(data); break; case A_SETCLASS: result = setclass(data); break; case A_GETPINFO: result = getpinfo(data); break; case A_GETPINFO_ADDR: result = getpinfo_addr(data, length); break; case A_SETPMASK: result = setpmask(data); break; default: result = EINVAL; break; } return (result); }