10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53369Stz204579 * Common Development and Distribution License (the "License").
63369Stz204579 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
2212273SCasper.Dik@Sun.COM * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <sys/systm.h>
260Sstevel@tonic-gate #include <sys/errno.h>
270Sstevel@tonic-gate #include <sys/policy.h>
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <c2/audit.h>
3011861SMarek.Pospisil@Sun.COM #include <c2/audit_kernel.h>
3111861SMarek.Pospisil@Sun.COM #include <c2/audit_record.h>
3211861SMarek.Pospisil@Sun.COM
3311861SMarek.Pospisil@Sun.COM #define CLEAR_VAL -1
3411861SMarek.Pospisil@Sun.COM
3511861SMarek.Pospisil@Sun.COM extern kmutex_t pidlock;
3611861SMarek.Pospisil@Sun.COM
3711871SMarek.Pospisil@Sun.COM uint32_t audit_policy; /* global audit policies in force */
3811861SMarek.Pospisil@Sun.COM
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*ARGSUSED1*/
410Sstevel@tonic-gate int
auditsys(struct auditcalls * uap,rval_t * rvp)420Sstevel@tonic-gate auditsys(struct auditcalls *uap, rval_t *rvp)
430Sstevel@tonic-gate {
440Sstevel@tonic-gate int err;
4511861SMarek.Pospisil@Sun.COM int result = 0;
460Sstevel@tonic-gate
4711861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_DISABLED)
483369Stz204579 return (ENOTSUP);
493369Stz204579
500Sstevel@tonic-gate switch (uap->code) {
510Sstevel@tonic-gate case BSM_GETAUID:
5211861SMarek.Pospisil@Sun.COM result = getauid((caddr_t)uap->a1);
5311861SMarek.Pospisil@Sun.COM break;
540Sstevel@tonic-gate case BSM_SETAUID:
5511861SMarek.Pospisil@Sun.COM result = setauid((caddr_t)uap->a1);
5611861SMarek.Pospisil@Sun.COM break;
570Sstevel@tonic-gate case BSM_GETAUDIT:
5811861SMarek.Pospisil@Sun.COM result = getaudit((caddr_t)uap->a1);
5911861SMarek.Pospisil@Sun.COM break;
6011861SMarek.Pospisil@Sun.COM case BSM_GETAUDIT_ADDR:
6111861SMarek.Pospisil@Sun.COM result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
6211861SMarek.Pospisil@Sun.COM break;
630Sstevel@tonic-gate case BSM_SETAUDIT:
6411861SMarek.Pospisil@Sun.COM result = setaudit((caddr_t)uap->a1);
6511861SMarek.Pospisil@Sun.COM break;
6611861SMarek.Pospisil@Sun.COM case BSM_SETAUDIT_ADDR:
6711861SMarek.Pospisil@Sun.COM result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
6811861SMarek.Pospisil@Sun.COM break;
690Sstevel@tonic-gate case BSM_AUDITCTL:
7011861SMarek.Pospisil@Sun.COM result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
7111861SMarek.Pospisil@Sun.COM break;
7211861SMarek.Pospisil@Sun.COM case BSM_AUDIT:
7311861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_UNLOADED)
7411861SMarek.Pospisil@Sun.COM return (0);
7511861SMarek.Pospisil@Sun.COM result = audit((caddr_t)uap->a1, (int)uap->a2);
7611861SMarek.Pospisil@Sun.COM break;
7711861SMarek.Pospisil@Sun.COM case BSM_AUDITDOOR:
7811861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_LOADED) {
7911861SMarek.Pospisil@Sun.COM result = auditdoor((int)uap->a1);
8011861SMarek.Pospisil@Sun.COM break;
8111861SMarek.Pospisil@Sun.COM }
820Sstevel@tonic-gate default:
8311861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_LOADED) {
8411861SMarek.Pospisil@Sun.COM result = EINVAL;
8511861SMarek.Pospisil@Sun.COM break;
8611861SMarek.Pospisil@Sun.COM }
870Sstevel@tonic-gate /* Return a different error when not privileged */
880Sstevel@tonic-gate err = secpolicy_audit_config(CRED());
890Sstevel@tonic-gate if (err == 0)
900Sstevel@tonic-gate return (EINVAL);
910Sstevel@tonic-gate else
920Sstevel@tonic-gate return (err);
930Sstevel@tonic-gate }
9411861SMarek.Pospisil@Sun.COM rvp->r_vals = result;
9511861SMarek.Pospisil@Sun.COM return (result);
960Sstevel@tonic-gate }
9711861SMarek.Pospisil@Sun.COM
9811861SMarek.Pospisil@Sun.COM /*
9911861SMarek.Pospisil@Sun.COM * Return the audit user ID for the current process. Currently only
10011861SMarek.Pospisil@Sun.COM * the privileged processes may see the audit id. That may change.
10111861SMarek.Pospisil@Sun.COM * If copyout is unsucessful return EFAULT.
10211861SMarek.Pospisil@Sun.COM */
10311861SMarek.Pospisil@Sun.COM int
getauid(caddr_t auid_p)10411861SMarek.Pospisil@Sun.COM getauid(caddr_t auid_p)
10511861SMarek.Pospisil@Sun.COM {
10611861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
10711861SMarek.Pospisil@Sun.COM
10812273SCasper.Dik@Sun.COM if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
10911861SMarek.Pospisil@Sun.COM return (EPERM);
11011861SMarek.Pospisil@Sun.COM
11111861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(CRED());
11211861SMarek.Pospisil@Sun.COM if (ainfo == NULL)
11311861SMarek.Pospisil@Sun.COM return (EINVAL);
11411861SMarek.Pospisil@Sun.COM
11511861SMarek.Pospisil@Sun.COM if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
11611861SMarek.Pospisil@Sun.COM return (EFAULT);
11711861SMarek.Pospisil@Sun.COM
11811861SMarek.Pospisil@Sun.COM return (0);
11911861SMarek.Pospisil@Sun.COM }
12011861SMarek.Pospisil@Sun.COM
12111861SMarek.Pospisil@Sun.COM /*
12211861SMarek.Pospisil@Sun.COM * Set the audit userid, for a process. This can only be changed by
12311861SMarek.Pospisil@Sun.COM * privileged processes. The audit userid is inherited across forks & execs.
12411861SMarek.Pospisil@Sun.COM * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
12511861SMarek.Pospisil@Sun.COM */
12611861SMarek.Pospisil@Sun.COM int
setauid(caddr_t auid_p)12711861SMarek.Pospisil@Sun.COM setauid(caddr_t auid_p)
12811861SMarek.Pospisil@Sun.COM {
12911861SMarek.Pospisil@Sun.COM proc_t *p;
13011861SMarek.Pospisil@Sun.COM au_id_t auid;
13111861SMarek.Pospisil@Sun.COM cred_t *newcred;
13211861SMarek.Pospisil@Sun.COM auditinfo_addr_t *auinfo;
13311861SMarek.Pospisil@Sun.COM
13411861SMarek.Pospisil@Sun.COM if (secpolicy_audit_config(CRED()) != 0)
13511861SMarek.Pospisil@Sun.COM return (EPERM);
13611861SMarek.Pospisil@Sun.COM
13711861SMarek.Pospisil@Sun.COM if (copyin(auid_p, &auid, sizeof (au_id_t))) {
13811861SMarek.Pospisil@Sun.COM return (EFAULT);
13911861SMarek.Pospisil@Sun.COM }
14011861SMarek.Pospisil@Sun.COM
14111861SMarek.Pospisil@Sun.COM newcred = cralloc();
14211861SMarek.Pospisil@Sun.COM if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
14311861SMarek.Pospisil@Sun.COM crfree(newcred);
14411861SMarek.Pospisil@Sun.COM return (EINVAL);
14511861SMarek.Pospisil@Sun.COM }
14611861SMarek.Pospisil@Sun.COM
14711861SMarek.Pospisil@Sun.COM /* grab p_crlock and switch to new cred */
14811861SMarek.Pospisil@Sun.COM p = curproc;
14911861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
15011861SMarek.Pospisil@Sun.COM crcopy_to(p->p_cred, newcred);
15111861SMarek.Pospisil@Sun.COM p->p_cred = newcred;
15211861SMarek.Pospisil@Sun.COM
15311861SMarek.Pospisil@Sun.COM auinfo->ai_auid = auid; /* update the auid */
15411861SMarek.Pospisil@Sun.COM
15511861SMarek.Pospisil@Sun.COM /* unlock and broadcast the cred changes */
15611861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
15711861SMarek.Pospisil@Sun.COM crset(p, newcred);
15811861SMarek.Pospisil@Sun.COM
15911861SMarek.Pospisil@Sun.COM return (0);
16011861SMarek.Pospisil@Sun.COM }
16111861SMarek.Pospisil@Sun.COM
16211861SMarek.Pospisil@Sun.COM /*
16311861SMarek.Pospisil@Sun.COM * Get the audit state information from the current process.
16411861SMarek.Pospisil@Sun.COM * Return EFAULT if copyout fails.
16511861SMarek.Pospisil@Sun.COM */
16611861SMarek.Pospisil@Sun.COM int
getaudit(caddr_t info_p)16711861SMarek.Pospisil@Sun.COM getaudit(caddr_t info_p)
16811861SMarek.Pospisil@Sun.COM {
16911861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo, info);
17011861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
17111861SMarek.Pospisil@Sun.COM model_t model;
17211861SMarek.Pospisil@Sun.COM
17312273SCasper.Dik@Sun.COM if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
17411861SMarek.Pospisil@Sun.COM return (EPERM);
17511861SMarek.Pospisil@Sun.COM
17611861SMarek.Pospisil@Sun.COM model = get_udatamodel();
17711861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
17811861SMarek.Pospisil@Sun.COM
17911861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(CRED());
18011861SMarek.Pospisil@Sun.COM if (ainfo == NULL)
18111861SMarek.Pospisil@Sun.COM return (EINVAL);
18211861SMarek.Pospisil@Sun.COM
18311861SMarek.Pospisil@Sun.COM /* trying to read a process with an IPv6 address? */
18411861SMarek.Pospisil@Sun.COM if (ainfo->ai_termid.at_type == AU_IPv6)
18511861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
18611861SMarek.Pospisil@Sun.COM
18711861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
18811861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
18911861SMarek.Pospisil@Sun.COM #ifdef _LP64
19011861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32) {
19111861SMarek.Pospisil@Sun.COM dev32_t dev;
19211861SMarek.Pospisil@Sun.COM /* convert internal 64 bit form to 32 bit version */
19311861SMarek.Pospisil@Sun.COM if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
19411861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
19511861SMarek.Pospisil@Sun.COM }
19611861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.port, dev);
19711861SMarek.Pospisil@Sun.COM } else
19811861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
19911861SMarek.Pospisil@Sun.COM #else
20011861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
20111861SMarek.Pospisil@Sun.COM #endif
20211861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
20311861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
20411861SMarek.Pospisil@Sun.COM
20511861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
20611861SMarek.Pospisil@Sun.COM return (EFAULT);
20711861SMarek.Pospisil@Sun.COM
20811861SMarek.Pospisil@Sun.COM return (0);
20911861SMarek.Pospisil@Sun.COM }
21011861SMarek.Pospisil@Sun.COM
21111861SMarek.Pospisil@Sun.COM /*
21211861SMarek.Pospisil@Sun.COM * Get the audit state information from the current process.
21311861SMarek.Pospisil@Sun.COM * Return EFAULT if copyout fails.
21411861SMarek.Pospisil@Sun.COM */
21511861SMarek.Pospisil@Sun.COM int
getaudit_addr(caddr_t info_p,int len)21611861SMarek.Pospisil@Sun.COM getaudit_addr(caddr_t info_p, int len)
21711861SMarek.Pospisil@Sun.COM {
21811861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo_addr, info);
21911861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
22011861SMarek.Pospisil@Sun.COM model_t model;
22111861SMarek.Pospisil@Sun.COM
22212273SCasper.Dik@Sun.COM if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
22311861SMarek.Pospisil@Sun.COM return (EPERM);
22411861SMarek.Pospisil@Sun.COM
22511861SMarek.Pospisil@Sun.COM model = get_udatamodel();
22611861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
22711861SMarek.Pospisil@Sun.COM
22811861SMarek.Pospisil@Sun.COM if (len < STRUCT_SIZE(info))
22911861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
23011861SMarek.Pospisil@Sun.COM
23111861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(CRED());
23211861SMarek.Pospisil@Sun.COM
23311861SMarek.Pospisil@Sun.COM if (ainfo == NULL)
23411861SMarek.Pospisil@Sun.COM return (EINVAL);
23511861SMarek.Pospisil@Sun.COM
23611861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
23711861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
23811861SMarek.Pospisil@Sun.COM #ifdef _LP64
23911861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32) {
24011861SMarek.Pospisil@Sun.COM dev32_t dev;
24111861SMarek.Pospisil@Sun.COM /* convert internal 64 bit form to 32 bit version */
24211861SMarek.Pospisil@Sun.COM if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
24311861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
24411861SMarek.Pospisil@Sun.COM }
24511861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port, dev);
24611861SMarek.Pospisil@Sun.COM } else
24711861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
24811861SMarek.Pospisil@Sun.COM #else
24911861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
25011861SMarek.Pospisil@Sun.COM #endif
25111861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
25211861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
25311861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
25411861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
25511861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
25611861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
25711861SMarek.Pospisil@Sun.COM
25811861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
25911861SMarek.Pospisil@Sun.COM return (EFAULT);
26011861SMarek.Pospisil@Sun.COM
26111861SMarek.Pospisil@Sun.COM return (0);
26211861SMarek.Pospisil@Sun.COM }
26311861SMarek.Pospisil@Sun.COM
26411861SMarek.Pospisil@Sun.COM /*
26511861SMarek.Pospisil@Sun.COM * Set the audit state information for the current process.
26611861SMarek.Pospisil@Sun.COM * Return EFAULT if copyout fails.
26711861SMarek.Pospisil@Sun.COM */
26811861SMarek.Pospisil@Sun.COM int
setaudit(caddr_t info_p)26911861SMarek.Pospisil@Sun.COM setaudit(caddr_t info_p)
27011861SMarek.Pospisil@Sun.COM {
27111861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo, info);
27211861SMarek.Pospisil@Sun.COM proc_t *p;
27311861SMarek.Pospisil@Sun.COM cred_t *newcred;
27411861SMarek.Pospisil@Sun.COM model_t model;
27511861SMarek.Pospisil@Sun.COM auditinfo_addr_t *ainfo;
27611861SMarek.Pospisil@Sun.COM
27711861SMarek.Pospisil@Sun.COM if (secpolicy_audit_config(CRED()) != 0)
27811861SMarek.Pospisil@Sun.COM return (EPERM);
27911861SMarek.Pospisil@Sun.COM
28011861SMarek.Pospisil@Sun.COM model = get_udatamodel();
28111861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
28211861SMarek.Pospisil@Sun.COM
28311861SMarek.Pospisil@Sun.COM if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
28411861SMarek.Pospisil@Sun.COM return (EFAULT);
28511861SMarek.Pospisil@Sun.COM
28611861SMarek.Pospisil@Sun.COM newcred = cralloc();
28711861SMarek.Pospisil@Sun.COM if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
28811861SMarek.Pospisil@Sun.COM crfree(newcred);
28911861SMarek.Pospisil@Sun.COM return (EINVAL);
29011861SMarek.Pospisil@Sun.COM }
29111861SMarek.Pospisil@Sun.COM
29211861SMarek.Pospisil@Sun.COM /* grab p_crlock and switch to new cred */
29311861SMarek.Pospisil@Sun.COM p = curproc;
29411861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
29511861SMarek.Pospisil@Sun.COM crcopy_to(p->p_cred, newcred);
29611861SMarek.Pospisil@Sun.COM p->p_cred = newcred;
29711861SMarek.Pospisil@Sun.COM
29811861SMarek.Pospisil@Sun.COM /* Set audit mask, id, termid and session id as specified */
29911861SMarek.Pospisil@Sun.COM ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
30011861SMarek.Pospisil@Sun.COM #ifdef _LP64
30111861SMarek.Pospisil@Sun.COM /* only convert to 64 bit if coming from a 32 bit binary */
30211861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32)
30311861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port =
30411861SMarek.Pospisil@Sun.COM DEVEXPL(STRUCT_FGET(info, ai_termid.port));
30511861SMarek.Pospisil@Sun.COM else
30611861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
30711861SMarek.Pospisil@Sun.COM #else
30811861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
30911861SMarek.Pospisil@Sun.COM #endif
31011861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_type = AU_IPv4;
31111861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
31211861SMarek.Pospisil@Sun.COM ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
31311861SMarek.Pospisil@Sun.COM ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
31411861SMarek.Pospisil@Sun.COM
31511861SMarek.Pospisil@Sun.COM /* unlock and broadcast the cred changes */
31611861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
31711861SMarek.Pospisil@Sun.COM crset(p, newcred);
31811861SMarek.Pospisil@Sun.COM
31911861SMarek.Pospisil@Sun.COM return (0);
32011861SMarek.Pospisil@Sun.COM }
32111861SMarek.Pospisil@Sun.COM
32211861SMarek.Pospisil@Sun.COM /*
32311861SMarek.Pospisil@Sun.COM * Set the audit state information for the current process.
32411861SMarek.Pospisil@Sun.COM * Return EFAULT if copyin fails.
32511861SMarek.Pospisil@Sun.COM */
32611861SMarek.Pospisil@Sun.COM int
setaudit_addr(caddr_t info_p,int len)32711861SMarek.Pospisil@Sun.COM setaudit_addr(caddr_t info_p, int len)
32811861SMarek.Pospisil@Sun.COM {
32911861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo_addr, info);
33011861SMarek.Pospisil@Sun.COM proc_t *p;
33111861SMarek.Pospisil@Sun.COM cred_t *newcred;
33211861SMarek.Pospisil@Sun.COM model_t model;
33311861SMarek.Pospisil@Sun.COM int i;
33411861SMarek.Pospisil@Sun.COM int type;
33511861SMarek.Pospisil@Sun.COM auditinfo_addr_t *ainfo;
33611861SMarek.Pospisil@Sun.COM
33711861SMarek.Pospisil@Sun.COM if (secpolicy_audit_config(CRED()) != 0)
33811861SMarek.Pospisil@Sun.COM return (EPERM);
33911861SMarek.Pospisil@Sun.COM
34011861SMarek.Pospisil@Sun.COM model = get_udatamodel();
34111861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
34211861SMarek.Pospisil@Sun.COM
34311861SMarek.Pospisil@Sun.COM if (len < STRUCT_SIZE(info))
34411861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
34511861SMarek.Pospisil@Sun.COM
34611861SMarek.Pospisil@Sun.COM if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
34711861SMarek.Pospisil@Sun.COM return (EFAULT);
34811861SMarek.Pospisil@Sun.COM
34911861SMarek.Pospisil@Sun.COM type = STRUCT_FGET(info, ai_termid.at_type);
35011861SMarek.Pospisil@Sun.COM if ((type != AU_IPv4) && (type != AU_IPv6))
35111861SMarek.Pospisil@Sun.COM return (EINVAL);
35211861SMarek.Pospisil@Sun.COM
35311861SMarek.Pospisil@Sun.COM newcred = cralloc();
35411861SMarek.Pospisil@Sun.COM if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
35511861SMarek.Pospisil@Sun.COM crfree(newcred);
35611861SMarek.Pospisil@Sun.COM return (EINVAL);
35711861SMarek.Pospisil@Sun.COM }
35811861SMarek.Pospisil@Sun.COM
35911861SMarek.Pospisil@Sun.COM /* grab p_crlock and switch to new cred */
36011861SMarek.Pospisil@Sun.COM p = curproc;
36111861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
36211861SMarek.Pospisil@Sun.COM crcopy_to(p->p_cred, newcred);
36311861SMarek.Pospisil@Sun.COM p->p_cred = newcred;
36411861SMarek.Pospisil@Sun.COM
36511861SMarek.Pospisil@Sun.COM /* Set audit mask, id, termid and session id as specified */
36611861SMarek.Pospisil@Sun.COM ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
36711861SMarek.Pospisil@Sun.COM ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
36811861SMarek.Pospisil@Sun.COM #ifdef _LP64
36911861SMarek.Pospisil@Sun.COM /* only convert to 64 bit if coming from a 32 bit binary */
37011861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32)
37111861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port =
37211861SMarek.Pospisil@Sun.COM DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
37311861SMarek.Pospisil@Sun.COM else
37411861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
37511861SMarek.Pospisil@Sun.COM #else
37611861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
37711861SMarek.Pospisil@Sun.COM #endif
37811861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_type = type;
37911861SMarek.Pospisil@Sun.COM bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
38011861SMarek.Pospisil@Sun.COM for (i = 0; i < (type/sizeof (int)); i++)
38111861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[i] =
38211861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_addr[i]);
38311861SMarek.Pospisil@Sun.COM
38411861SMarek.Pospisil@Sun.COM if (ainfo->ai_termid.at_type == AU_IPv6 &&
38511861SMarek.Pospisil@Sun.COM IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
38611861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_type = AU_IPv4;
38711861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
38811861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[1] = 0;
38911861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[2] = 0;
39011861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_addr[3] = 0;
39111861SMarek.Pospisil@Sun.COM }
39211861SMarek.Pospisil@Sun.COM
39311861SMarek.Pospisil@Sun.COM ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
39411861SMarek.Pospisil@Sun.COM
39511861SMarek.Pospisil@Sun.COM /* unlock and broadcast the cred changes */
39611861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
39711861SMarek.Pospisil@Sun.COM crset(p, newcred);
39811861SMarek.Pospisil@Sun.COM
39911861SMarek.Pospisil@Sun.COM return (0);
40011861SMarek.Pospisil@Sun.COM }
40111861SMarek.Pospisil@Sun.COM
40211861SMarek.Pospisil@Sun.COM /*
40311861SMarek.Pospisil@Sun.COM * Get the global policy flag
40411861SMarek.Pospisil@Sun.COM */
40511861SMarek.Pospisil@Sun.COM static int
getpolicy(caddr_t data)40611861SMarek.Pospisil@Sun.COM getpolicy(caddr_t data)
40711861SMarek.Pospisil@Sun.COM {
40811871SMarek.Pospisil@Sun.COM uint32_t policy;
40911861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
41011861SMarek.Pospisil@Sun.COM
41111861SMarek.Pospisil@Sun.COM policy = audit_policy | kctx->auk_policy;
41211861SMarek.Pospisil@Sun.COM
41311871SMarek.Pospisil@Sun.COM if (copyout(&policy, data, sizeof (policy)))
41411861SMarek.Pospisil@Sun.COM return (EFAULT);
41511861SMarek.Pospisil@Sun.COM return (0);
41611861SMarek.Pospisil@Sun.COM }
41711861SMarek.Pospisil@Sun.COM
41811861SMarek.Pospisil@Sun.COM /*
41911861SMarek.Pospisil@Sun.COM * Set the global and local policy flags
42011861SMarek.Pospisil@Sun.COM *
42111861SMarek.Pospisil@Sun.COM * The global flags only make sense from the global zone;
42211861SMarek.Pospisil@Sun.COM * the local flags depend on the AUDIT_PERZONE policy:
42311861SMarek.Pospisil@Sun.COM * if the perzone policy is set, then policy is set separately
42411861SMarek.Pospisil@Sun.COM * per zone, else held only in the global zone.
42511861SMarek.Pospisil@Sun.COM *
42611861SMarek.Pospisil@Sun.COM * The initial value of a local zone's policy flag is determined
42711861SMarek.Pospisil@Sun.COM * by the value of the global zone's flags at the time the
42811861SMarek.Pospisil@Sun.COM * local zone is created.
42911861SMarek.Pospisil@Sun.COM *
43011861SMarek.Pospisil@Sun.COM * While auditconfig(1M) allows setting and unsetting policies one bit
43111861SMarek.Pospisil@Sun.COM * at a time, the mask passed in from auditconfig() is created by a
43211861SMarek.Pospisil@Sun.COM * syscall to getpolicy and then modified based on the auditconfig()
43311861SMarek.Pospisil@Sun.COM * cmd line, so the input policy value is used to replace the existing
43411861SMarek.Pospisil@Sun.COM * policy.
43511861SMarek.Pospisil@Sun.COM */
43611861SMarek.Pospisil@Sun.COM static int
setpolicy(caddr_t data)43711861SMarek.Pospisil@Sun.COM setpolicy(caddr_t data)
43811861SMarek.Pospisil@Sun.COM {
43911871SMarek.Pospisil@Sun.COM uint32_t policy;
44011861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
44111861SMarek.Pospisil@Sun.COM
44211871SMarek.Pospisil@Sun.COM if (copyin(data, &policy, sizeof (policy)))
44311861SMarek.Pospisil@Sun.COM return (EFAULT);
44411861SMarek.Pospisil@Sun.COM
44511861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
44611861SMarek.Pospisil@Sun.COM
44711861SMarek.Pospisil@Sun.COM if (INGLOBALZONE(curproc)) {
44811861SMarek.Pospisil@Sun.COM if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
44911861SMarek.Pospisil@Sun.COM return (EINVAL);
45011861SMarek.Pospisil@Sun.COM
45111861SMarek.Pospisil@Sun.COM audit_policy = policy & AUDIT_GLOBAL;
45211861SMarek.Pospisil@Sun.COM } else {
45311861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE))
45411861SMarek.Pospisil@Sun.COM return (EINVAL);
45511861SMarek.Pospisil@Sun.COM
45611861SMarek.Pospisil@Sun.COM if (policy & ~AUDIT_LOCAL) /* global bits are a no-no */
45711861SMarek.Pospisil@Sun.COM return (EINVAL);
45811861SMarek.Pospisil@Sun.COM }
45911861SMarek.Pospisil@Sun.COM kctx->auk_policy = policy & AUDIT_LOCAL;
46011861SMarek.Pospisil@Sun.COM
46111861SMarek.Pospisil@Sun.COM /*
46211861SMarek.Pospisil@Sun.COM * auk_current_vp is NULL before auditd starts (or during early
46311861SMarek.Pospisil@Sun.COM * auditd starup) or if auditd is halted; in either case,
46411861SMarek.Pospisil@Sun.COM * notification of a policy change is not needed, since auditd
46511861SMarek.Pospisil@Sun.COM * reads policy as it comes up. The error return from au_doormsg()
46611861SMarek.Pospisil@Sun.COM * is ignored to avoid a race condition -- for example if auditd
46711861SMarek.Pospisil@Sun.COM * segv's, the audit state may be "auditing" but the door may
46811861SMarek.Pospisil@Sun.COM * be closed. Returning an error if the door is open makes it
46911861SMarek.Pospisil@Sun.COM * impossible for Greenline to restart auditd.
47011861SMarek.Pospisil@Sun.COM */
47111861SMarek.Pospisil@Sun.COM if (kctx->auk_current_vp != NULL)
47211861SMarek.Pospisil@Sun.COM (void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
47311861SMarek.Pospisil@Sun.COM
47411861SMarek.Pospisil@Sun.COM /*
47511861SMarek.Pospisil@Sun.COM * Wake up anyone who might have blocked on full audit
47611861SMarek.Pospisil@Sun.COM * partitions. audit daemons need to set AUDIT_FULL when no
47711861SMarek.Pospisil@Sun.COM * space so we can tell if we should start dropping records.
47811861SMarek.Pospisil@Sun.COM */
47911861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
48011861SMarek.Pospisil@Sun.COM
48111861SMarek.Pospisil@Sun.COM if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
48211861SMarek.Pospisil@Sun.COM (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
48311861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.write_cv));
48411861SMarek.Pospisil@Sun.COM
48511861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
48611861SMarek.Pospisil@Sun.COM
48711861SMarek.Pospisil@Sun.COM return (0);
48811861SMarek.Pospisil@Sun.COM }
48911861SMarek.Pospisil@Sun.COM
49011861SMarek.Pospisil@Sun.COM static int
getamask(caddr_t data)491*12918SJan.Friedel@Sun.COM getamask(caddr_t data)
492*12918SJan.Friedel@Sun.COM {
493*12918SJan.Friedel@Sun.COM au_kcontext_t *kctx;
494*12918SJan.Friedel@Sun.COM
495*12918SJan.Friedel@Sun.COM kctx = GET_KCTX_PZ;
496*12918SJan.Friedel@Sun.COM
497*12918SJan.Friedel@Sun.COM if (copyout(&kctx->auk_info.ai_amask, data, sizeof (au_mask_t)))
498*12918SJan.Friedel@Sun.COM return (EFAULT);
499*12918SJan.Friedel@Sun.COM
500*12918SJan.Friedel@Sun.COM return (0);
501*12918SJan.Friedel@Sun.COM }
502*12918SJan.Friedel@Sun.COM
503*12918SJan.Friedel@Sun.COM static int
setamask(caddr_t data)504*12918SJan.Friedel@Sun.COM setamask(caddr_t data)
505*12918SJan.Friedel@Sun.COM {
506*12918SJan.Friedel@Sun.COM au_mask_t mask;
507*12918SJan.Friedel@Sun.COM au_kcontext_t *kctx;
508*12918SJan.Friedel@Sun.COM
509*12918SJan.Friedel@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
510*12918SJan.Friedel@Sun.COM return (EINVAL);
511*12918SJan.Friedel@Sun.COM
512*12918SJan.Friedel@Sun.COM kctx = GET_KCTX_NGZ;
513*12918SJan.Friedel@Sun.COM
514*12918SJan.Friedel@Sun.COM if (copyin(data, &mask, sizeof (au_mask_t)))
515*12918SJan.Friedel@Sun.COM return (EFAULT);
516*12918SJan.Friedel@Sun.COM
517*12918SJan.Friedel@Sun.COM kctx->auk_info.ai_amask = mask;
518*12918SJan.Friedel@Sun.COM return (0);
519*12918SJan.Friedel@Sun.COM }
520*12918SJan.Friedel@Sun.COM
521*12918SJan.Friedel@Sun.COM static int
getkmask(caddr_t data)52211861SMarek.Pospisil@Sun.COM getkmask(caddr_t data)
52311861SMarek.Pospisil@Sun.COM {
52411861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
52511861SMarek.Pospisil@Sun.COM
52611861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_PZ;
52711861SMarek.Pospisil@Sun.COM
528*12918SJan.Friedel@Sun.COM if (copyout(&kctx->auk_info.ai_namask, data, sizeof (au_mask_t)))
52911861SMarek.Pospisil@Sun.COM return (EFAULT);
53011861SMarek.Pospisil@Sun.COM return (0);
53111861SMarek.Pospisil@Sun.COM }
53211861SMarek.Pospisil@Sun.COM
53311861SMarek.Pospisil@Sun.COM static int
setkmask(caddr_t data)53411861SMarek.Pospisil@Sun.COM setkmask(caddr_t data)
53511861SMarek.Pospisil@Sun.COM {
53611861SMarek.Pospisil@Sun.COM au_mask_t mask;
53711861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
53811861SMarek.Pospisil@Sun.COM
53911861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
54011861SMarek.Pospisil@Sun.COM return (EINVAL);
54111861SMarek.Pospisil@Sun.COM
54211861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
54311861SMarek.Pospisil@Sun.COM
54411861SMarek.Pospisil@Sun.COM if (copyin(data, &mask, sizeof (au_mask_t)))
54511861SMarek.Pospisil@Sun.COM return (EFAULT);
54611861SMarek.Pospisil@Sun.COM
547*12918SJan.Friedel@Sun.COM kctx->auk_info.ai_namask = mask;
54811861SMarek.Pospisil@Sun.COM return (0);
54911861SMarek.Pospisil@Sun.COM }
55011861SMarek.Pospisil@Sun.COM
55111861SMarek.Pospisil@Sun.COM static int
getkaudit(caddr_t info_p,int len)55211861SMarek.Pospisil@Sun.COM getkaudit(caddr_t info_p, int len)
55311861SMarek.Pospisil@Sun.COM {
55411861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo_addr, info);
55511861SMarek.Pospisil@Sun.COM model_t model;
55611861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
55711861SMarek.Pospisil@Sun.COM
55811861SMarek.Pospisil@Sun.COM model = get_udatamodel();
55911861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
56011861SMarek.Pospisil@Sun.COM
56111861SMarek.Pospisil@Sun.COM if (len < STRUCT_SIZE(info))
56211861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
56311861SMarek.Pospisil@Sun.COM
56411861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
565*12918SJan.Friedel@Sun.COM STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_namask);
56611861SMarek.Pospisil@Sun.COM #ifdef _LP64
56711861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32) {
56811861SMarek.Pospisil@Sun.COM dev32_t dev;
56911861SMarek.Pospisil@Sun.COM /* convert internal 64 bit form to 32 bit version */
57011861SMarek.Pospisil@Sun.COM if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
57111861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
57211861SMarek.Pospisil@Sun.COM }
57311861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port, dev);
57411861SMarek.Pospisil@Sun.COM } else {
57511861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port,
57611861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_port);
57711861SMarek.Pospisil@Sun.COM }
57811861SMarek.Pospisil@Sun.COM #else
57911861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_port,
58011861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_port);
58111861SMarek.Pospisil@Sun.COM #endif
58211861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_type,
58311861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_type);
58411861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[0],
58511861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[0]);
58611861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[1],
58711861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[1]);
58811861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[2],
58911861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[2]);
59011861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_termid.at_addr[3],
59111861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[3]);
59211861SMarek.Pospisil@Sun.COM STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
59311861SMarek.Pospisil@Sun.COM
59411861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
59511861SMarek.Pospisil@Sun.COM return (EFAULT);
59611861SMarek.Pospisil@Sun.COM
59711861SMarek.Pospisil@Sun.COM return (0);
59811861SMarek.Pospisil@Sun.COM }
59911861SMarek.Pospisil@Sun.COM
60011861SMarek.Pospisil@Sun.COM /*
60111861SMarek.Pospisil@Sun.COM * the host address for AUDIT_PERZONE == 0 is that of the global
60211861SMarek.Pospisil@Sun.COM * zone and for local zones it is of the current zone.
60311861SMarek.Pospisil@Sun.COM */
60411861SMarek.Pospisil@Sun.COM static int
setkaudit(caddr_t info_p,int len)60511861SMarek.Pospisil@Sun.COM setkaudit(caddr_t info_p, int len)
60611861SMarek.Pospisil@Sun.COM {
60711861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo_addr, info);
60811861SMarek.Pospisil@Sun.COM model_t model;
60911861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
61011861SMarek.Pospisil@Sun.COM
61111861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
61211861SMarek.Pospisil@Sun.COM return (EINVAL);
61311861SMarek.Pospisil@Sun.COM
61411861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
61511861SMarek.Pospisil@Sun.COM
61611861SMarek.Pospisil@Sun.COM model = get_udatamodel();
61711861SMarek.Pospisil@Sun.COM STRUCT_INIT(info, model);
61811861SMarek.Pospisil@Sun.COM
61911861SMarek.Pospisil@Sun.COM if (len < STRUCT_SIZE(info))
62011861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
62111861SMarek.Pospisil@Sun.COM
62211861SMarek.Pospisil@Sun.COM if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
62311861SMarek.Pospisil@Sun.COM return (EFAULT);
62411861SMarek.Pospisil@Sun.COM
62511861SMarek.Pospisil@Sun.COM if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
62611861SMarek.Pospisil@Sun.COM (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
62711861SMarek.Pospisil@Sun.COM return (EINVAL);
62811861SMarek.Pospisil@Sun.COM
62911861SMarek.Pospisil@Sun.COM /* Set audit mask, termid and session id as specified */
63011861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
631*12918SJan.Friedel@Sun.COM kctx->auk_info.ai_namask = STRUCT_FGET(info, ai_mask);
63211861SMarek.Pospisil@Sun.COM #ifdef _LP64
63311861SMarek.Pospisil@Sun.COM /* only convert to 64 bit if coming from a 32 bit binary */
63411861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32)
63511861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_port =
63611861SMarek.Pospisil@Sun.COM DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
63711861SMarek.Pospisil@Sun.COM else
63811861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_port =
63911861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_port);
64011861SMarek.Pospisil@Sun.COM #else
64111861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
64211861SMarek.Pospisil@Sun.COM #endif
64311861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
64411861SMarek.Pospisil@Sun.COM bzero(&kctx->auk_info.ai_termid.at_addr[0],
64511861SMarek.Pospisil@Sun.COM sizeof (kctx->auk_info.ai_termid.at_addr));
64611861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[0] =
64711861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_addr[0]);
64811861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[1] =
64911861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_addr[1]);
65011861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[2] =
65111861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_addr[2]);
65211861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[3] =
65311861SMarek.Pospisil@Sun.COM STRUCT_FGET(info, ai_termid.at_addr[3]);
65411861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
65511861SMarek.Pospisil@Sun.COM
65611861SMarek.Pospisil@Sun.COM if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
65711861SMarek.Pospisil@Sun.COM IN6_IS_ADDR_V4MAPPED(
65811861SMarek.Pospisil@Sun.COM ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
65911861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_type = AU_IPv4;
66011861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[0] =
66111861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[3];
66211861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[1] = 0;
66311861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[2] = 0;
66411861SMarek.Pospisil@Sun.COM kctx->auk_info.ai_termid.at_addr[3] = 0;
66511861SMarek.Pospisil@Sun.COM }
66611861SMarek.Pospisil@Sun.COM if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
66711861SMarek.Pospisil@Sun.COM kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
66811861SMarek.Pospisil@Sun.COM (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
66911861SMarek.Pospisil@Sun.COM else
67011861SMarek.Pospisil@Sun.COM kctx->auk_hostaddr_valid =
67111861SMarek.Pospisil@Sun.COM (kctx->auk_info.ai_termid.at_addr[0] ==
67211861SMarek.Pospisil@Sun.COM htonl(INADDR_ANY)) ? 0 : 1;
67311861SMarek.Pospisil@Sun.COM
67411861SMarek.Pospisil@Sun.COM return (0);
67511861SMarek.Pospisil@Sun.COM }
67611861SMarek.Pospisil@Sun.COM
67711861SMarek.Pospisil@Sun.COM static int
getqctrl(caddr_t data)67811861SMarek.Pospisil@Sun.COM getqctrl(caddr_t data)
67911861SMarek.Pospisil@Sun.COM {
68011861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
68111861SMarek.Pospisil@Sun.COM STRUCT_DECL(au_qctrl, qctrl);
68211861SMarek.Pospisil@Sun.COM STRUCT_INIT(qctrl, get_udatamodel());
68311861SMarek.Pospisil@Sun.COM
68411861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
68511861SMarek.Pospisil@Sun.COM STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
68611861SMarek.Pospisil@Sun.COM STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
68711861SMarek.Pospisil@Sun.COM STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
68811861SMarek.Pospisil@Sun.COM STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
68911861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
69011861SMarek.Pospisil@Sun.COM
69111861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
69211861SMarek.Pospisil@Sun.COM return (EFAULT);
69311861SMarek.Pospisil@Sun.COM
69411861SMarek.Pospisil@Sun.COM return (0);
69511861SMarek.Pospisil@Sun.COM }
69611861SMarek.Pospisil@Sun.COM
69711861SMarek.Pospisil@Sun.COM static int
setqctrl(caddr_t data)69811861SMarek.Pospisil@Sun.COM setqctrl(caddr_t data)
69911861SMarek.Pospisil@Sun.COM {
70011861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
70111861SMarek.Pospisil@Sun.COM struct au_qctrl qctrl_tmp;
70211861SMarek.Pospisil@Sun.COM STRUCT_DECL(au_qctrl, qctrl);
70311861SMarek.Pospisil@Sun.COM STRUCT_INIT(qctrl, get_udatamodel());
70411861SMarek.Pospisil@Sun.COM
70511861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
70611861SMarek.Pospisil@Sun.COM return (EINVAL);
70711861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
70811861SMarek.Pospisil@Sun.COM
70911861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
71011861SMarek.Pospisil@Sun.COM return (EFAULT);
71111861SMarek.Pospisil@Sun.COM
71211861SMarek.Pospisil@Sun.COM qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
71311861SMarek.Pospisil@Sun.COM qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
71411861SMarek.Pospisil@Sun.COM qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
71511861SMarek.Pospisil@Sun.COM qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
71611861SMarek.Pospisil@Sun.COM
71711861SMarek.Pospisil@Sun.COM /* enforce sane values */
71811861SMarek.Pospisil@Sun.COM
71911861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
72011861SMarek.Pospisil@Sun.COM return (EINVAL);
72111861SMarek.Pospisil@Sun.COM
72211861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
72311861SMarek.Pospisil@Sun.COM return (EINVAL);
72411861SMarek.Pospisil@Sun.COM
72511861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
72611861SMarek.Pospisil@Sun.COM return (EINVAL);
72711861SMarek.Pospisil@Sun.COM
72811861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
72911861SMarek.Pospisil@Sun.COM return (EINVAL);
73011861SMarek.Pospisil@Sun.COM
73111861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
73211861SMarek.Pospisil@Sun.COM return (EINVAL);
73311861SMarek.Pospisil@Sun.COM
73411861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_delay == 0)
73511861SMarek.Pospisil@Sun.COM return (EINVAL);
73611861SMarek.Pospisil@Sun.COM
73711861SMarek.Pospisil@Sun.COM if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
73811861SMarek.Pospisil@Sun.COM return (EINVAL);
73911861SMarek.Pospisil@Sun.COM
74011861SMarek.Pospisil@Sun.COM /* update everything at once so things are consistant */
74111861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
74211861SMarek.Pospisil@Sun.COM kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
74311861SMarek.Pospisil@Sun.COM kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
74411861SMarek.Pospisil@Sun.COM kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
74511861SMarek.Pospisil@Sun.COM kctx->auk_queue.delay = qctrl_tmp.aq_delay;
74611861SMarek.Pospisil@Sun.COM
74711861SMarek.Pospisil@Sun.COM if (kctx->auk_queue.rd_block &&
74811861SMarek.Pospisil@Sun.COM kctx->auk_queue.cnt > kctx->auk_queue.lowater)
74911861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.read_cv));
75011861SMarek.Pospisil@Sun.COM
75111861SMarek.Pospisil@Sun.COM if (kctx->auk_queue.wt_block &&
75211861SMarek.Pospisil@Sun.COM kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
75311861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.write_cv));
75411861SMarek.Pospisil@Sun.COM
75511861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
75611861SMarek.Pospisil@Sun.COM
75711861SMarek.Pospisil@Sun.COM return (0);
75811861SMarek.Pospisil@Sun.COM }
75911861SMarek.Pospisil@Sun.COM
76011861SMarek.Pospisil@Sun.COM static int
getcwd(caddr_t data,int length)76111861SMarek.Pospisil@Sun.COM getcwd(caddr_t data, int length)
76211861SMarek.Pospisil@Sun.COM {
76311861SMarek.Pospisil@Sun.COM struct p_audit_data *pad;
76411861SMarek.Pospisil@Sun.COM struct audit_path *app;
76511861SMarek.Pospisil@Sun.COM int pathlen;
76611861SMarek.Pospisil@Sun.COM
76711861SMarek.Pospisil@Sun.COM pad = P2A(curproc);
76811861SMarek.Pospisil@Sun.COM ASSERT(pad != NULL);
76911861SMarek.Pospisil@Sun.COM
77011861SMarek.Pospisil@Sun.COM mutex_enter(&(pad->pad_lock));
77111861SMarek.Pospisil@Sun.COM app = pad->pad_cwd;
77211861SMarek.Pospisil@Sun.COM au_pathhold(app);
77311861SMarek.Pospisil@Sun.COM mutex_exit(&(pad->pad_lock));
77411861SMarek.Pospisil@Sun.COM
77511861SMarek.Pospisil@Sun.COM pathlen = app->audp_sect[1] - app->audp_sect[0];
77611861SMarek.Pospisil@Sun.COM if (pathlen > length) {
77711861SMarek.Pospisil@Sun.COM au_pathrele(app);
77811861SMarek.Pospisil@Sun.COM return (E2BIG);
77911861SMarek.Pospisil@Sun.COM }
78011861SMarek.Pospisil@Sun.COM
78111861SMarek.Pospisil@Sun.COM if (copyout(app->audp_sect[0], data, pathlen)) {
78211861SMarek.Pospisil@Sun.COM au_pathrele(app);
78311861SMarek.Pospisil@Sun.COM return (EFAULT);
78411861SMarek.Pospisil@Sun.COM }
78511861SMarek.Pospisil@Sun.COM
78611861SMarek.Pospisil@Sun.COM au_pathrele(app);
78711861SMarek.Pospisil@Sun.COM return (0);
78811861SMarek.Pospisil@Sun.COM }
78911861SMarek.Pospisil@Sun.COM
79011861SMarek.Pospisil@Sun.COM static int
getcar(caddr_t data,int length)79111861SMarek.Pospisil@Sun.COM getcar(caddr_t data, int length)
79211861SMarek.Pospisil@Sun.COM {
79311861SMarek.Pospisil@Sun.COM struct p_audit_data *pad;
79411861SMarek.Pospisil@Sun.COM struct audit_path *app;
79511861SMarek.Pospisil@Sun.COM int pathlen;
79611861SMarek.Pospisil@Sun.COM
79711861SMarek.Pospisil@Sun.COM pad = P2A(curproc);
79811861SMarek.Pospisil@Sun.COM ASSERT(pad != NULL);
79911861SMarek.Pospisil@Sun.COM
80011861SMarek.Pospisil@Sun.COM mutex_enter(&(pad->pad_lock));
80111861SMarek.Pospisil@Sun.COM app = pad->pad_root;
80211861SMarek.Pospisil@Sun.COM au_pathhold(app);
80311861SMarek.Pospisil@Sun.COM mutex_exit(&(pad->pad_lock));
80411861SMarek.Pospisil@Sun.COM
80511861SMarek.Pospisil@Sun.COM pathlen = app->audp_sect[1] - app->audp_sect[0];
80611861SMarek.Pospisil@Sun.COM if (pathlen > length) {
80711861SMarek.Pospisil@Sun.COM au_pathrele(app);
80811861SMarek.Pospisil@Sun.COM return (E2BIG);
80911861SMarek.Pospisil@Sun.COM }
81011861SMarek.Pospisil@Sun.COM
81111861SMarek.Pospisil@Sun.COM if (copyout(app->audp_sect[0], data, pathlen)) {
81211861SMarek.Pospisil@Sun.COM au_pathrele(app);
81311861SMarek.Pospisil@Sun.COM return (EFAULT);
81411861SMarek.Pospisil@Sun.COM }
81511861SMarek.Pospisil@Sun.COM
81611861SMarek.Pospisil@Sun.COM au_pathrele(app);
81711861SMarek.Pospisil@Sun.COM return (0);
81811861SMarek.Pospisil@Sun.COM }
81911861SMarek.Pospisil@Sun.COM
82011861SMarek.Pospisil@Sun.COM static int
getstat(caddr_t data)82111861SMarek.Pospisil@Sun.COM getstat(caddr_t data)
82211861SMarek.Pospisil@Sun.COM {
82311861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
82411861SMarek.Pospisil@Sun.COM
82511861SMarek.Pospisil@Sun.COM membar_consumer();
82611861SMarek.Pospisil@Sun.COM
82711861SMarek.Pospisil@Sun.COM if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
82811861SMarek.Pospisil@Sun.COM return (EFAULT);
82911861SMarek.Pospisil@Sun.COM return (0);
83011861SMarek.Pospisil@Sun.COM }
83111861SMarek.Pospisil@Sun.COM
83211861SMarek.Pospisil@Sun.COM static int
setstat(caddr_t data)83311861SMarek.Pospisil@Sun.COM setstat(caddr_t data)
83411861SMarek.Pospisil@Sun.COM {
83511861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
83611861SMarek.Pospisil@Sun.COM au_stat_t au_stat;
83711861SMarek.Pospisil@Sun.COM
83811861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
83911861SMarek.Pospisil@Sun.COM return (EINVAL);
84011861SMarek.Pospisil@Sun.COM
84111861SMarek.Pospisil@Sun.COM if (copyin(data, &au_stat, sizeof (au_stat_t)))
84211861SMarek.Pospisil@Sun.COM return (EFAULT);
84311861SMarek.Pospisil@Sun.COM
84411861SMarek.Pospisil@Sun.COM if (au_stat.as_generated == CLEAR_VAL)
84511861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_generated = 0;
84611861SMarek.Pospisil@Sun.COM if (au_stat.as_nonattrib == CLEAR_VAL)
84711861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_nonattrib = 0;
84811861SMarek.Pospisil@Sun.COM if (au_stat.as_kernel == CLEAR_VAL)
84911861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_kernel = 0;
85011861SMarek.Pospisil@Sun.COM if (au_stat.as_audit == CLEAR_VAL)
85111861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_audit = 0;
85211861SMarek.Pospisil@Sun.COM if (au_stat.as_auditctl == CLEAR_VAL)
85311861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_auditctl = 0;
85411861SMarek.Pospisil@Sun.COM if (au_stat.as_enqueue == CLEAR_VAL)
85511861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_enqueue = 0;
85611861SMarek.Pospisil@Sun.COM if (au_stat.as_written == CLEAR_VAL)
85711861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_written = 0;
85811861SMarek.Pospisil@Sun.COM if (au_stat.as_wblocked == CLEAR_VAL)
85911861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_wblocked = 0;
86011861SMarek.Pospisil@Sun.COM if (au_stat.as_rblocked == CLEAR_VAL)
86111861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_rblocked = 0;
86211861SMarek.Pospisil@Sun.COM if (au_stat.as_dropped == CLEAR_VAL)
86311861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_dropped = 0;
86411861SMarek.Pospisil@Sun.COM if (au_stat.as_totalsize == CLEAR_VAL)
86511861SMarek.Pospisil@Sun.COM kctx->auk_statistics.as_totalsize = 0;
86611861SMarek.Pospisil@Sun.COM
86711861SMarek.Pospisil@Sun.COM membar_producer();
86811861SMarek.Pospisil@Sun.COM
86911861SMarek.Pospisil@Sun.COM return (0);
87011861SMarek.Pospisil@Sun.COM
87111861SMarek.Pospisil@Sun.COM }
87211861SMarek.Pospisil@Sun.COM
87311861SMarek.Pospisil@Sun.COM static int
setumask(caddr_t data)87411861SMarek.Pospisil@Sun.COM setumask(caddr_t data)
87511861SMarek.Pospisil@Sun.COM {
87611861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo, user_info);
87711861SMarek.Pospisil@Sun.COM struct proc *p;
87811861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
87911861SMarek.Pospisil@Sun.COM model_t model;
88011861SMarek.Pospisil@Sun.COM
88111861SMarek.Pospisil@Sun.COM /* setumask not applicable in non-global zones without perzone policy */
88211861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
88311861SMarek.Pospisil@Sun.COM return (EINVAL);
88411861SMarek.Pospisil@Sun.COM
88511861SMarek.Pospisil@Sun.COM model = get_udatamodel();
88611861SMarek.Pospisil@Sun.COM STRUCT_INIT(user_info, model);
88711861SMarek.Pospisil@Sun.COM
88811861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
88911861SMarek.Pospisil@Sun.COM return (EFAULT);
89011861SMarek.Pospisil@Sun.COM
89111861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock); /* lock the process queue against updates */
89211861SMarek.Pospisil@Sun.COM for (p = practive; p != NULL; p = p->p_next) {
89311861SMarek.Pospisil@Sun.COM cred_t *cr;
89411861SMarek.Pospisil@Sun.COM
89511861SMarek.Pospisil@Sun.COM /* if in non-global zone only modify processes in same zone */
89611861SMarek.Pospisil@Sun.COM if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
89711861SMarek.Pospisil@Sun.COM continue;
89811861SMarek.Pospisil@Sun.COM
89911861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_lock); /* so process doesn't go away */
90011861SMarek.Pospisil@Sun.COM
90111861SMarek.Pospisil@Sun.COM /* skip system processes and ones being created or going away */
90211861SMarek.Pospisil@Sun.COM if (p->p_stat == SIDL || p->p_stat == SZOMB ||
90311861SMarek.Pospisil@Sun.COM (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
90411861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
90511861SMarek.Pospisil@Sun.COM continue;
90611861SMarek.Pospisil@Sun.COM }
90711861SMarek.Pospisil@Sun.COM
90811861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
90911861SMarek.Pospisil@Sun.COM crhold(cr = p->p_cred);
91011861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
91111861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(cr);
91211861SMarek.Pospisil@Sun.COM if (ainfo == NULL) {
91311861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
91411861SMarek.Pospisil@Sun.COM crfree(cr);
91511861SMarek.Pospisil@Sun.COM continue;
91611861SMarek.Pospisil@Sun.COM }
91711861SMarek.Pospisil@Sun.COM
91811861SMarek.Pospisil@Sun.COM if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
91911861SMarek.Pospisil@Sun.COM au_mask_t mask;
92011861SMarek.Pospisil@Sun.COM int err;
92111861SMarek.Pospisil@Sun.COM
92211861SMarek.Pospisil@Sun.COM /*
92311861SMarek.Pospisil@Sun.COM * Here's a process which matches the specified auid.
92411861SMarek.Pospisil@Sun.COM * If its mask doesn't already match the new mask,
92511861SMarek.Pospisil@Sun.COM * save the new mask in the pad, to be picked up
92611861SMarek.Pospisil@Sun.COM * next syscall.
92711861SMarek.Pospisil@Sun.COM */
92811861SMarek.Pospisil@Sun.COM mask = STRUCT_FGET(user_info, ai_mask);
92911861SMarek.Pospisil@Sun.COM err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
93011861SMarek.Pospisil@Sun.COM crfree(cr);
93111861SMarek.Pospisil@Sun.COM if (err != 0) {
93211861SMarek.Pospisil@Sun.COM struct p_audit_data *pad = P2A(p);
93311861SMarek.Pospisil@Sun.COM ASSERT(pad != NULL);
93411861SMarek.Pospisil@Sun.COM
93511861SMarek.Pospisil@Sun.COM mutex_enter(&(pad->pad_lock));
93611861SMarek.Pospisil@Sun.COM pad->pad_flags |= PAD_SETMASK;
93711861SMarek.Pospisil@Sun.COM pad->pad_newmask = mask;
93811861SMarek.Pospisil@Sun.COM mutex_exit(&(pad->pad_lock));
93911861SMarek.Pospisil@Sun.COM
94011861SMarek.Pospisil@Sun.COM /*
94111861SMarek.Pospisil@Sun.COM * No need to call set_proc_pre_sys(), since
94211861SMarek.Pospisil@Sun.COM * t_pre_sys is ALWAYS on when audit is
94311861SMarek.Pospisil@Sun.COM * enabled...due to syscall auditing.
94411861SMarek.Pospisil@Sun.COM */
94511861SMarek.Pospisil@Sun.COM }
94611861SMarek.Pospisil@Sun.COM } else {
94711861SMarek.Pospisil@Sun.COM crfree(cr);
94811861SMarek.Pospisil@Sun.COM }
94911861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
95011861SMarek.Pospisil@Sun.COM }
95111861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
95211861SMarek.Pospisil@Sun.COM
95311861SMarek.Pospisil@Sun.COM return (0);
95411861SMarek.Pospisil@Sun.COM }
95511861SMarek.Pospisil@Sun.COM
95611861SMarek.Pospisil@Sun.COM static int
setsmask(caddr_t data)95711861SMarek.Pospisil@Sun.COM setsmask(caddr_t data)
95811861SMarek.Pospisil@Sun.COM {
95911861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditinfo, user_info);
96011861SMarek.Pospisil@Sun.COM struct proc *p;
96111861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
96211861SMarek.Pospisil@Sun.COM model_t model;
96311861SMarek.Pospisil@Sun.COM
96411861SMarek.Pospisil@Sun.COM /* setsmask not applicable in non-global zones without perzone policy */
96511861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
96611861SMarek.Pospisil@Sun.COM return (EINVAL);
96711861SMarek.Pospisil@Sun.COM
96811861SMarek.Pospisil@Sun.COM model = get_udatamodel();
96911861SMarek.Pospisil@Sun.COM STRUCT_INIT(user_info, model);
97011861SMarek.Pospisil@Sun.COM
97111861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
97211861SMarek.Pospisil@Sun.COM return (EFAULT);
97311861SMarek.Pospisil@Sun.COM
97411861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock); /* lock the process queue against updates */
97511861SMarek.Pospisil@Sun.COM for (p = practive; p != NULL; p = p->p_next) {
97611861SMarek.Pospisil@Sun.COM cred_t *cr;
97711861SMarek.Pospisil@Sun.COM
97811861SMarek.Pospisil@Sun.COM /* if in non-global zone only modify processes in same zone */
97911861SMarek.Pospisil@Sun.COM if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
98011861SMarek.Pospisil@Sun.COM continue;
98111861SMarek.Pospisil@Sun.COM
98211861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_lock); /* so process doesn't go away */
98311861SMarek.Pospisil@Sun.COM
98411861SMarek.Pospisil@Sun.COM /* skip system processes and ones being created or going away */
98511861SMarek.Pospisil@Sun.COM if (p->p_stat == SIDL || p->p_stat == SZOMB ||
98611861SMarek.Pospisil@Sun.COM (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
98711861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
98811861SMarek.Pospisil@Sun.COM continue;
98911861SMarek.Pospisil@Sun.COM }
99011861SMarek.Pospisil@Sun.COM
99111861SMarek.Pospisil@Sun.COM mutex_enter(&p->p_crlock);
99211861SMarek.Pospisil@Sun.COM crhold(cr = p->p_cred);
99311861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_crlock);
99411861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(cr);
99511861SMarek.Pospisil@Sun.COM if (ainfo == NULL) {
99611861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
99711861SMarek.Pospisil@Sun.COM crfree(cr);
99811861SMarek.Pospisil@Sun.COM continue;
99911861SMarek.Pospisil@Sun.COM }
100011861SMarek.Pospisil@Sun.COM
100111861SMarek.Pospisil@Sun.COM if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
100211861SMarek.Pospisil@Sun.COM au_mask_t mask;
100311861SMarek.Pospisil@Sun.COM int err;
100411861SMarek.Pospisil@Sun.COM
100511861SMarek.Pospisil@Sun.COM /*
100611861SMarek.Pospisil@Sun.COM * Here's a process which matches the specified asid.
100711861SMarek.Pospisil@Sun.COM * If its mask doesn't already match the new mask,
100811861SMarek.Pospisil@Sun.COM * save the new mask in the pad, to be picked up
100911861SMarek.Pospisil@Sun.COM * next syscall.
101011861SMarek.Pospisil@Sun.COM */
101111861SMarek.Pospisil@Sun.COM mask = STRUCT_FGET(user_info, ai_mask);
101211861SMarek.Pospisil@Sun.COM err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
101311861SMarek.Pospisil@Sun.COM crfree(cr);
101411861SMarek.Pospisil@Sun.COM if (err != 0) {
101511861SMarek.Pospisil@Sun.COM struct p_audit_data *pad = P2A(p);
101611861SMarek.Pospisil@Sun.COM ASSERT(pad != NULL);
101711861SMarek.Pospisil@Sun.COM
101811861SMarek.Pospisil@Sun.COM mutex_enter(&(pad->pad_lock));
101911861SMarek.Pospisil@Sun.COM pad->pad_flags |= PAD_SETMASK;
102011861SMarek.Pospisil@Sun.COM pad->pad_newmask = mask;
102111861SMarek.Pospisil@Sun.COM mutex_exit(&(pad->pad_lock));
102211861SMarek.Pospisil@Sun.COM
102311861SMarek.Pospisil@Sun.COM /*
102411861SMarek.Pospisil@Sun.COM * No need to call set_proc_pre_sys(), since
102511861SMarek.Pospisil@Sun.COM * t_pre_sys is ALWAYS on when audit is
102611861SMarek.Pospisil@Sun.COM * enabled...due to syscall auditing.
102711861SMarek.Pospisil@Sun.COM */
102811861SMarek.Pospisil@Sun.COM }
102911861SMarek.Pospisil@Sun.COM } else {
103011861SMarek.Pospisil@Sun.COM crfree(cr);
103111861SMarek.Pospisil@Sun.COM }
103211861SMarek.Pospisil@Sun.COM mutex_exit(&p->p_lock);
103311861SMarek.Pospisil@Sun.COM }
103411861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
103511861SMarek.Pospisil@Sun.COM
103611861SMarek.Pospisil@Sun.COM return (0);
103711861SMarek.Pospisil@Sun.COM }
103811861SMarek.Pospisil@Sun.COM
103911861SMarek.Pospisil@Sun.COM /*
104011861SMarek.Pospisil@Sun.COM * Get the current audit state of the system
104111861SMarek.Pospisil@Sun.COM */
104211861SMarek.Pospisil@Sun.COM static int
getcond(caddr_t data)104311861SMarek.Pospisil@Sun.COM getcond(caddr_t data)
104411861SMarek.Pospisil@Sun.COM {
104511861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
104611861SMarek.Pospisil@Sun.COM
104711861SMarek.Pospisil@Sun.COM if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
104811861SMarek.Pospisil@Sun.COM return (EFAULT);
104911861SMarek.Pospisil@Sun.COM
105011861SMarek.Pospisil@Sun.COM return (0);
105111861SMarek.Pospisil@Sun.COM }
105211861SMarek.Pospisil@Sun.COM
105311861SMarek.Pospisil@Sun.COM /*
105411861SMarek.Pospisil@Sun.COM * Set the current audit state of the system to on (AUC_AUDITING) or
105511861SMarek.Pospisil@Sun.COM * off (AUC_NOAUDIT).
105611861SMarek.Pospisil@Sun.COM */
105711861SMarek.Pospisil@Sun.COM /* ARGSUSED */
105811861SMarek.Pospisil@Sun.COM static int
setcond(caddr_t data)105911861SMarek.Pospisil@Sun.COM setcond(caddr_t data)
106011861SMarek.Pospisil@Sun.COM {
106111861SMarek.Pospisil@Sun.COM int auditstate;
106211861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
106311861SMarek.Pospisil@Sun.COM
106411861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
106511861SMarek.Pospisil@Sun.COM return (EINVAL);
106611861SMarek.Pospisil@Sun.COM
106711861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
106811861SMarek.Pospisil@Sun.COM
106911861SMarek.Pospisil@Sun.COM if (copyin(data, &auditstate, sizeof (int)))
107011861SMarek.Pospisil@Sun.COM return (EFAULT);
107111861SMarek.Pospisil@Sun.COM
107211861SMarek.Pospisil@Sun.COM switch (auditstate) {
107311861SMarek.Pospisil@Sun.COM case AUC_AUDITING: /* Turn auditing on */
107411861SMarek.Pospisil@Sun.COM if (audit_active == C2AUDIT_UNLOADED)
107511861SMarek.Pospisil@Sun.COM audit_init_module();
107611861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_AUDITING;
107711861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc))
107811861SMarek.Pospisil@Sun.COM set_all_zone_usr_proc_sys(ALL_ZONES);
107911861SMarek.Pospisil@Sun.COM else
108011861SMarek.Pospisil@Sun.COM set_all_zone_usr_proc_sys(curproc->p_zone->zone_id);
108111861SMarek.Pospisil@Sun.COM break;
108211861SMarek.Pospisil@Sun.COM
108311861SMarek.Pospisil@Sun.COM case AUC_NOAUDIT: /* Turn auditing off */
108411861SMarek.Pospisil@Sun.COM if (kctx->auk_auditstate == AUC_NOAUDIT)
108511861SMarek.Pospisil@Sun.COM break;
108611861SMarek.Pospisil@Sun.COM kctx->auk_auditstate = AUC_NOAUDIT;
108711861SMarek.Pospisil@Sun.COM
108811861SMarek.Pospisil@Sun.COM /* clear out the audit queue */
108911861SMarek.Pospisil@Sun.COM
109011861SMarek.Pospisil@Sun.COM mutex_enter(&(kctx->auk_queue.lock));
109111861SMarek.Pospisil@Sun.COM if (kctx->auk_queue.wt_block)
109211861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.write_cv));
109311861SMarek.Pospisil@Sun.COM
109411861SMarek.Pospisil@Sun.COM /* unblock au_output_thread */
109511861SMarek.Pospisil@Sun.COM cv_broadcast(&(kctx->auk_queue.read_cv));
109611861SMarek.Pospisil@Sun.COM
109711861SMarek.Pospisil@Sun.COM mutex_exit(&(kctx->auk_queue.lock));
109811861SMarek.Pospisil@Sun.COM break;
109911861SMarek.Pospisil@Sun.COM
110011861SMarek.Pospisil@Sun.COM default:
110111861SMarek.Pospisil@Sun.COM return (EINVAL);
110211861SMarek.Pospisil@Sun.COM }
110311861SMarek.Pospisil@Sun.COM
110411861SMarek.Pospisil@Sun.COM return (0);
110511861SMarek.Pospisil@Sun.COM }
110611861SMarek.Pospisil@Sun.COM
110711861SMarek.Pospisil@Sun.COM static int
getclass(caddr_t data)110811861SMarek.Pospisil@Sun.COM getclass(caddr_t data)
110911861SMarek.Pospisil@Sun.COM {
111011861SMarek.Pospisil@Sun.COM au_evclass_map_t event;
111111861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx = GET_KCTX_PZ;
111211861SMarek.Pospisil@Sun.COM
111311861SMarek.Pospisil@Sun.COM if (copyin(data, &event, sizeof (au_evclass_map_t)))
111411861SMarek.Pospisil@Sun.COM return (EFAULT);
111511861SMarek.Pospisil@Sun.COM
111611861SMarek.Pospisil@Sun.COM if (event.ec_number > MAX_KEVENTS)
111711861SMarek.Pospisil@Sun.COM return (EINVAL);
111811861SMarek.Pospisil@Sun.COM
111911861SMarek.Pospisil@Sun.COM event.ec_class = kctx->auk_ets[event.ec_number];
112011861SMarek.Pospisil@Sun.COM
112111861SMarek.Pospisil@Sun.COM if (copyout(&event, data, sizeof (au_evclass_map_t)))
112211861SMarek.Pospisil@Sun.COM return (EFAULT);
112311861SMarek.Pospisil@Sun.COM
112411861SMarek.Pospisil@Sun.COM return (0);
112511861SMarek.Pospisil@Sun.COM }
112611861SMarek.Pospisil@Sun.COM
112711861SMarek.Pospisil@Sun.COM static int
setclass(caddr_t data)112811861SMarek.Pospisil@Sun.COM setclass(caddr_t data)
112911861SMarek.Pospisil@Sun.COM {
113011861SMarek.Pospisil@Sun.COM au_evclass_map_t event;
113111861SMarek.Pospisil@Sun.COM au_kcontext_t *kctx;
113211861SMarek.Pospisil@Sun.COM
113311861SMarek.Pospisil@Sun.COM if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
113411861SMarek.Pospisil@Sun.COM return (EINVAL);
113511861SMarek.Pospisil@Sun.COM
113611861SMarek.Pospisil@Sun.COM kctx = GET_KCTX_NGZ;
113711861SMarek.Pospisil@Sun.COM
113811861SMarek.Pospisil@Sun.COM if (copyin(data, &event, sizeof (au_evclass_map_t)))
113911861SMarek.Pospisil@Sun.COM return (EFAULT);
114011861SMarek.Pospisil@Sun.COM
114111861SMarek.Pospisil@Sun.COM if (event.ec_number > MAX_KEVENTS)
114211861SMarek.Pospisil@Sun.COM return (EINVAL);
114311861SMarek.Pospisil@Sun.COM
114411861SMarek.Pospisil@Sun.COM kctx->auk_ets[event.ec_number] = event.ec_class;
114511861SMarek.Pospisil@Sun.COM
114611861SMarek.Pospisil@Sun.COM return (0);
114711861SMarek.Pospisil@Sun.COM }
114811861SMarek.Pospisil@Sun.COM
114911861SMarek.Pospisil@Sun.COM static int
getpinfo(caddr_t data)115011861SMarek.Pospisil@Sun.COM getpinfo(caddr_t data)
115111861SMarek.Pospisil@Sun.COM {
115211861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditpinfo, apinfo);
115311861SMarek.Pospisil@Sun.COM proc_t *proc;
115411861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
115511861SMarek.Pospisil@Sun.COM model_t model;
115611861SMarek.Pospisil@Sun.COM cred_t *cr, *newcred;
115711861SMarek.Pospisil@Sun.COM
115811861SMarek.Pospisil@Sun.COM model = get_udatamodel();
115911861SMarek.Pospisil@Sun.COM STRUCT_INIT(apinfo, model);
116011861SMarek.Pospisil@Sun.COM
116111861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
116211861SMarek.Pospisil@Sun.COM return (EFAULT);
116311861SMarek.Pospisil@Sun.COM
116411861SMarek.Pospisil@Sun.COM newcred = cralloc();
116511861SMarek.Pospisil@Sun.COM
116611861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock);
116711861SMarek.Pospisil@Sun.COM if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
116811861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
116911861SMarek.Pospisil@Sun.COM crfree(newcred);
117011861SMarek.Pospisil@Sun.COM return (ESRCH); /* no such process */
117111861SMarek.Pospisil@Sun.COM }
117211861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_lock); /* so process doesn't go away */
117311861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
117411861SMarek.Pospisil@Sun.COM
117511861SMarek.Pospisil@Sun.COM audit_update_context(proc, newcred); /* make sure it's up-to-date */
117611861SMarek.Pospisil@Sun.COM
117711861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_crlock);
117811861SMarek.Pospisil@Sun.COM crhold(cr = proc->p_cred);
117911861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_crlock);
118011861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_lock);
118111861SMarek.Pospisil@Sun.COM
118211861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(cr);
118311861SMarek.Pospisil@Sun.COM if (ainfo == NULL) {
118411861SMarek.Pospisil@Sun.COM crfree(cr);
118511861SMarek.Pospisil@Sun.COM return (EINVAL);
118611861SMarek.Pospisil@Sun.COM }
118711861SMarek.Pospisil@Sun.COM
118811861SMarek.Pospisil@Sun.COM /* designated process has an ipv6 address? */
118911861SMarek.Pospisil@Sun.COM if (ainfo->ai_termid.at_type == AU_IPv6) {
119011861SMarek.Pospisil@Sun.COM crfree(cr);
119111861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
119211861SMarek.Pospisil@Sun.COM }
119311861SMarek.Pospisil@Sun.COM
119411861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
119511861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
119611861SMarek.Pospisil@Sun.COM #ifdef _LP64
119711861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32) {
119811861SMarek.Pospisil@Sun.COM dev32_t dev;
119911861SMarek.Pospisil@Sun.COM /* convert internal 64 bit form to 32 bit version */
120011861SMarek.Pospisil@Sun.COM if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
120111861SMarek.Pospisil@Sun.COM crfree(cr);
120211861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
120311861SMarek.Pospisil@Sun.COM }
120411861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.port, dev);
120511861SMarek.Pospisil@Sun.COM } else
120611861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
120711861SMarek.Pospisil@Sun.COM #else
120811861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
120911861SMarek.Pospisil@Sun.COM #endif
121011861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
121111861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
121211861SMarek.Pospisil@Sun.COM
121311861SMarek.Pospisil@Sun.COM crfree(cr);
121411861SMarek.Pospisil@Sun.COM
121511861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
121611861SMarek.Pospisil@Sun.COM return (EFAULT);
121711861SMarek.Pospisil@Sun.COM
121811861SMarek.Pospisil@Sun.COM return (0);
121911861SMarek.Pospisil@Sun.COM }
122011861SMarek.Pospisil@Sun.COM
122111861SMarek.Pospisil@Sun.COM static int
getpinfo_addr(caddr_t data,int len)122211861SMarek.Pospisil@Sun.COM getpinfo_addr(caddr_t data, int len)
122311861SMarek.Pospisil@Sun.COM {
122411861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditpinfo_addr, apinfo);
122511861SMarek.Pospisil@Sun.COM proc_t *proc;
122611861SMarek.Pospisil@Sun.COM const auditinfo_addr_t *ainfo;
122711861SMarek.Pospisil@Sun.COM model_t model;
122811861SMarek.Pospisil@Sun.COM cred_t *cr, *newcred;
122911861SMarek.Pospisil@Sun.COM
123011861SMarek.Pospisil@Sun.COM model = get_udatamodel();
123111861SMarek.Pospisil@Sun.COM STRUCT_INIT(apinfo, model);
123211861SMarek.Pospisil@Sun.COM
123311861SMarek.Pospisil@Sun.COM if (len < STRUCT_SIZE(apinfo))
123411861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
123511861SMarek.Pospisil@Sun.COM
123611861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
123711861SMarek.Pospisil@Sun.COM return (EFAULT);
123811861SMarek.Pospisil@Sun.COM
123911861SMarek.Pospisil@Sun.COM newcred = cralloc();
124011861SMarek.Pospisil@Sun.COM
124111861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock);
124211861SMarek.Pospisil@Sun.COM if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
124311861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
124411861SMarek.Pospisil@Sun.COM crfree(newcred);
124511861SMarek.Pospisil@Sun.COM return (ESRCH);
124611861SMarek.Pospisil@Sun.COM }
124711861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_lock); /* so process doesn't go away */
124811861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
124911861SMarek.Pospisil@Sun.COM
125011861SMarek.Pospisil@Sun.COM audit_update_context(proc, newcred); /* make sure it's up-to-date */
125111861SMarek.Pospisil@Sun.COM
125211861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_crlock);
125311861SMarek.Pospisil@Sun.COM crhold(cr = proc->p_cred);
125411861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_crlock);
125511861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_lock);
125611861SMarek.Pospisil@Sun.COM
125711861SMarek.Pospisil@Sun.COM ainfo = crgetauinfo(cr);
125811861SMarek.Pospisil@Sun.COM if (ainfo == NULL) {
125911861SMarek.Pospisil@Sun.COM crfree(cr);
126011861SMarek.Pospisil@Sun.COM return (EINVAL);
126111861SMarek.Pospisil@Sun.COM }
126211861SMarek.Pospisil@Sun.COM
126311861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
126411861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
126511861SMarek.Pospisil@Sun.COM #ifdef _LP64
126611861SMarek.Pospisil@Sun.COM if (model == DATAMODEL_ILP32) {
126711861SMarek.Pospisil@Sun.COM dev32_t dev;
126811861SMarek.Pospisil@Sun.COM /* convert internal 64 bit form to 32 bit version */
126911861SMarek.Pospisil@Sun.COM if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
127011861SMarek.Pospisil@Sun.COM crfree(cr);
127111861SMarek.Pospisil@Sun.COM return (EOVERFLOW);
127211861SMarek.Pospisil@Sun.COM }
127311861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_port, dev);
127411861SMarek.Pospisil@Sun.COM } else
127511861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_port,
127611861SMarek.Pospisil@Sun.COM ainfo->ai_termid.at_port);
127711861SMarek.Pospisil@Sun.COM #else
127811861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
127911861SMarek.Pospisil@Sun.COM #endif
128011861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
128111861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
128211861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
128311861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
128411861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
128511861SMarek.Pospisil@Sun.COM STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
128611861SMarek.Pospisil@Sun.COM
128711861SMarek.Pospisil@Sun.COM crfree(cr);
128811861SMarek.Pospisil@Sun.COM
128911861SMarek.Pospisil@Sun.COM if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
129011861SMarek.Pospisil@Sun.COM return (EFAULT);
129111861SMarek.Pospisil@Sun.COM
129211861SMarek.Pospisil@Sun.COM return (0);
129311861SMarek.Pospisil@Sun.COM }
129411861SMarek.Pospisil@Sun.COM
129511861SMarek.Pospisil@Sun.COM static int
setpmask(caddr_t data)129611861SMarek.Pospisil@Sun.COM setpmask(caddr_t data)
129711861SMarek.Pospisil@Sun.COM {
129811861SMarek.Pospisil@Sun.COM STRUCT_DECL(auditpinfo, apinfo);
129911861SMarek.Pospisil@Sun.COM proc_t *proc;
130011861SMarek.Pospisil@Sun.COM cred_t *newcred;
130111861SMarek.Pospisil@Sun.COM auditinfo_addr_t *ainfo;
130211861SMarek.Pospisil@Sun.COM struct p_audit_data *pad;
130311861SMarek.Pospisil@Sun.COM
130411861SMarek.Pospisil@Sun.COM model_t model;
130511861SMarek.Pospisil@Sun.COM
130611861SMarek.Pospisil@Sun.COM model = get_udatamodel();
130711861SMarek.Pospisil@Sun.COM STRUCT_INIT(apinfo, model);
130811861SMarek.Pospisil@Sun.COM
130911861SMarek.Pospisil@Sun.COM if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
131011861SMarek.Pospisil@Sun.COM return (EFAULT);
131111861SMarek.Pospisil@Sun.COM
131211861SMarek.Pospisil@Sun.COM mutex_enter(&pidlock);
131311861SMarek.Pospisil@Sun.COM if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
131411861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
131511861SMarek.Pospisil@Sun.COM return (ESRCH);
131611861SMarek.Pospisil@Sun.COM }
131711861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_lock); /* so process doesn't go away */
131811861SMarek.Pospisil@Sun.COM mutex_exit(&pidlock);
131911861SMarek.Pospisil@Sun.COM
132011861SMarek.Pospisil@Sun.COM newcred = cralloc();
132111861SMarek.Pospisil@Sun.COM if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
132211861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_lock);
132311861SMarek.Pospisil@Sun.COM crfree(newcred);
132411861SMarek.Pospisil@Sun.COM return (EINVAL);
132511861SMarek.Pospisil@Sun.COM }
132611861SMarek.Pospisil@Sun.COM
132711861SMarek.Pospisil@Sun.COM mutex_enter(&proc->p_crlock);
132811861SMarek.Pospisil@Sun.COM crcopy_to(proc->p_cred, newcred);
132911861SMarek.Pospisil@Sun.COM proc->p_cred = newcred;
133011861SMarek.Pospisil@Sun.COM
133111861SMarek.Pospisil@Sun.COM ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
133211861SMarek.Pospisil@Sun.COM
133311861SMarek.Pospisil@Sun.COM /*
133411861SMarek.Pospisil@Sun.COM * Unlock. No need to broadcast changes via set_proc_pre_sys(),
133511861SMarek.Pospisil@Sun.COM * since t_pre_sys is ALWAYS on when audit is enabled... due to
133611861SMarek.Pospisil@Sun.COM * syscall auditing.
133711861SMarek.Pospisil@Sun.COM */
133811861SMarek.Pospisil@Sun.COM crfree(newcred);
133911861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_crlock);
134011861SMarek.Pospisil@Sun.COM
134111861SMarek.Pospisil@Sun.COM /* Reset flag for any previous pending mask change; this supercedes */
134211861SMarek.Pospisil@Sun.COM pad = P2A(proc);
134311861SMarek.Pospisil@Sun.COM ASSERT(pad != NULL);
134411861SMarek.Pospisil@Sun.COM mutex_enter(&(pad->pad_lock));
134511861SMarek.Pospisil@Sun.COM pad->pad_flags &= ~PAD_SETMASK;
134611861SMarek.Pospisil@Sun.COM mutex_exit(&(pad->pad_lock));
134711861SMarek.Pospisil@Sun.COM
134811861SMarek.Pospisil@Sun.COM mutex_exit(&proc->p_lock);
134911861SMarek.Pospisil@Sun.COM
135011861SMarek.Pospisil@Sun.COM return (0);
135111861SMarek.Pospisil@Sun.COM }
135211861SMarek.Pospisil@Sun.COM
135311861SMarek.Pospisil@Sun.COM /*
135411861SMarek.Pospisil@Sun.COM * The out of control system call
135511861SMarek.Pospisil@Sun.COM * This is audit kitchen sink aka auditadm, aka auditon
135611861SMarek.Pospisil@Sun.COM */
135711861SMarek.Pospisil@Sun.COM int
auditctl(int cmd,caddr_t data,int length)135811861SMarek.Pospisil@Sun.COM auditctl(
135911861SMarek.Pospisil@Sun.COM int cmd,
136011861SMarek.Pospisil@Sun.COM caddr_t data,
136111861SMarek.Pospisil@Sun.COM int length)
136211861SMarek.Pospisil@Sun.COM {
136311861SMarek.Pospisil@Sun.COM int result;
136411861SMarek.Pospisil@Sun.COM
136511861SMarek.Pospisil@Sun.COM switch (cmd) {
1366*12918SJan.Friedel@Sun.COM case A_GETAMASK:
136711861SMarek.Pospisil@Sun.COM case A_GETCOND:
136811861SMarek.Pospisil@Sun.COM case A_GETCAR:
136911861SMarek.Pospisil@Sun.COM case A_GETCLASS:
137011861SMarek.Pospisil@Sun.COM case A_GETCWD:
137111861SMarek.Pospisil@Sun.COM case A_GETKAUDIT:
137211861SMarek.Pospisil@Sun.COM case A_GETKMASK:
137311861SMarek.Pospisil@Sun.COM case A_GETPINFO:
137411861SMarek.Pospisil@Sun.COM case A_GETPINFO_ADDR:
137511861SMarek.Pospisil@Sun.COM case A_GETPOLICY:
137611861SMarek.Pospisil@Sun.COM case A_GETQCTRL:
137711861SMarek.Pospisil@Sun.COM case A_GETSTAT:
137812273SCasper.Dik@Sun.COM if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
137911861SMarek.Pospisil@Sun.COM return (EPERM);
138011861SMarek.Pospisil@Sun.COM break;
138111861SMarek.Pospisil@Sun.COM default:
138211861SMarek.Pospisil@Sun.COM if (secpolicy_audit_config(CRED()) != 0)
138311861SMarek.Pospisil@Sun.COM return (EPERM);
138411861SMarek.Pospisil@Sun.COM break;
138511861SMarek.Pospisil@Sun.COM }
138611861SMarek.Pospisil@Sun.COM
138711861SMarek.Pospisil@Sun.COM switch (cmd) {
138811861SMarek.Pospisil@Sun.COM case A_GETPOLICY:
138911861SMarek.Pospisil@Sun.COM result = getpolicy(data);
139011861SMarek.Pospisil@Sun.COM break;
139111861SMarek.Pospisil@Sun.COM case A_SETPOLICY:
139211861SMarek.Pospisil@Sun.COM result = setpolicy(data);
139311861SMarek.Pospisil@Sun.COM break;
1394*12918SJan.Friedel@Sun.COM case A_GETAMASK:
1395*12918SJan.Friedel@Sun.COM result = getamask(data);
1396*12918SJan.Friedel@Sun.COM break;
1397*12918SJan.Friedel@Sun.COM case A_SETAMASK:
1398*12918SJan.Friedel@Sun.COM result = setamask(data);
1399*12918SJan.Friedel@Sun.COM break;
140011861SMarek.Pospisil@Sun.COM case A_GETKMASK:
140111861SMarek.Pospisil@Sun.COM result = getkmask(data);
140211861SMarek.Pospisil@Sun.COM break;
140311861SMarek.Pospisil@Sun.COM case A_SETKMASK:
140411861SMarek.Pospisil@Sun.COM result = setkmask(data);
140511861SMarek.Pospisil@Sun.COM break;
140611861SMarek.Pospisil@Sun.COM case A_GETKAUDIT:
140711861SMarek.Pospisil@Sun.COM result = getkaudit(data, length);
140811861SMarek.Pospisil@Sun.COM break;
140911861SMarek.Pospisil@Sun.COM case A_SETKAUDIT:
141011861SMarek.Pospisil@Sun.COM result = setkaudit(data, length);
141111861SMarek.Pospisil@Sun.COM break;
141211861SMarek.Pospisil@Sun.COM case A_GETQCTRL:
141311861SMarek.Pospisil@Sun.COM result = getqctrl(data);
141411861SMarek.Pospisil@Sun.COM break;
141511861SMarek.Pospisil@Sun.COM case A_SETQCTRL:
141611861SMarek.Pospisil@Sun.COM result = setqctrl(data);
141711861SMarek.Pospisil@Sun.COM break;
141811861SMarek.Pospisil@Sun.COM case A_GETCWD:
141911861SMarek.Pospisil@Sun.COM result = getcwd(data, length);
142011861SMarek.Pospisil@Sun.COM break;
142111861SMarek.Pospisil@Sun.COM case A_GETCAR:
142211861SMarek.Pospisil@Sun.COM result = getcar(data, length);
142311861SMarek.Pospisil@Sun.COM break;
142411861SMarek.Pospisil@Sun.COM case A_GETSTAT:
142511861SMarek.Pospisil@Sun.COM result = getstat(data);
142611861SMarek.Pospisil@Sun.COM break;
142711861SMarek.Pospisil@Sun.COM case A_SETSTAT:
142811861SMarek.Pospisil@Sun.COM result = setstat(data);
142911861SMarek.Pospisil@Sun.COM break;
143011861SMarek.Pospisil@Sun.COM case A_SETUMASK:
143111861SMarek.Pospisil@Sun.COM result = setumask(data);
143211861SMarek.Pospisil@Sun.COM break;
143311861SMarek.Pospisil@Sun.COM case A_SETSMASK:
143411861SMarek.Pospisil@Sun.COM result = setsmask(data);
143511861SMarek.Pospisil@Sun.COM break;
143611861SMarek.Pospisil@Sun.COM case A_GETCOND:
143711861SMarek.Pospisil@Sun.COM result = getcond(data);
143811861SMarek.Pospisil@Sun.COM break;
143911861SMarek.Pospisil@Sun.COM case A_SETCOND:
144011861SMarek.Pospisil@Sun.COM result = setcond(data);
144111861SMarek.Pospisil@Sun.COM break;
144211861SMarek.Pospisil@Sun.COM case A_GETCLASS:
144311861SMarek.Pospisil@Sun.COM result = getclass(data);
144411861SMarek.Pospisil@Sun.COM break;
144511861SMarek.Pospisil@Sun.COM case A_SETCLASS:
144611861SMarek.Pospisil@Sun.COM result = setclass(data);
144711861SMarek.Pospisil@Sun.COM break;
144811861SMarek.Pospisil@Sun.COM case A_GETPINFO:
144911861SMarek.Pospisil@Sun.COM result = getpinfo(data);
145011861SMarek.Pospisil@Sun.COM break;
145111861SMarek.Pospisil@Sun.COM case A_GETPINFO_ADDR:
145211861SMarek.Pospisil@Sun.COM result = getpinfo_addr(data, length);
145311861SMarek.Pospisil@Sun.COM break;
145411861SMarek.Pospisil@Sun.COM case A_SETPMASK:
145511861SMarek.Pospisil@Sun.COM result = setpmask(data);
145611861SMarek.Pospisil@Sun.COM break;
145711861SMarek.Pospisil@Sun.COM default:
145811861SMarek.Pospisil@Sun.COM result = EINVAL;
145911861SMarek.Pospisil@Sun.COM break;
146011861SMarek.Pospisil@Sun.COM }
146111861SMarek.Pospisil@Sun.COM return (result);
146211861SMarek.Pospisil@Sun.COM }
1463