17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5405e5d68Stz204579 * Common Development and Distribution License (the "License").
6405e5d68Stz204579 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22134a1f4eSCasper H.S. Dik * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
23d7c4a96fSAlex Wilson * Copyright 2020 The University of Queensland
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <sys/systm.h>
277c478bd9Sstevel@tonic-gate #include <sys/errno.h>
287c478bd9Sstevel@tonic-gate #include <sys/policy.h>
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <c2/audit.h>
31005d3febSMarek Pospisil #include <c2/audit_kernel.h>
32005d3febSMarek Pospisil #include <c2/audit_record.h>
33005d3febSMarek Pospisil
34005d3febSMarek Pospisil #define CLEAR_VAL -1
35005d3febSMarek Pospisil
36005d3febSMarek Pospisil extern kmutex_t pidlock;
37005d3febSMarek Pospisil
3896093503SMarek Pospisil uint32_t audit_policy; /* global audit policies in force */
39005d3febSMarek Pospisil
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /*ARGSUSED1*/
427c478bd9Sstevel@tonic-gate int
auditsys(struct auditcalls * uap,rval_t * rvp)437c478bd9Sstevel@tonic-gate auditsys(struct auditcalls *uap, rval_t *rvp)
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate int err;
46005d3febSMarek Pospisil int result = 0;
477c478bd9Sstevel@tonic-gate
48005d3febSMarek Pospisil if (audit_active == C2AUDIT_DISABLED)
49405e5d68Stz204579 return (ENOTSUP);
50405e5d68Stz204579
517c478bd9Sstevel@tonic-gate switch (uap->code) {
527c478bd9Sstevel@tonic-gate case BSM_GETAUID:
53005d3febSMarek Pospisil result = getauid((caddr_t)uap->a1);
54005d3febSMarek Pospisil break;
557c478bd9Sstevel@tonic-gate case BSM_SETAUID:
56005d3febSMarek Pospisil result = setauid((caddr_t)uap->a1);
57005d3febSMarek Pospisil break;
587c478bd9Sstevel@tonic-gate case BSM_GETAUDIT:
59005d3febSMarek Pospisil result = getaudit((caddr_t)uap->a1);
60005d3febSMarek Pospisil break;
61005d3febSMarek Pospisil case BSM_GETAUDIT_ADDR:
62005d3febSMarek Pospisil result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
63005d3febSMarek Pospisil break;
647c478bd9Sstevel@tonic-gate case BSM_SETAUDIT:
65005d3febSMarek Pospisil result = setaudit((caddr_t)uap->a1);
66005d3febSMarek Pospisil break;
67005d3febSMarek Pospisil case BSM_SETAUDIT_ADDR:
68005d3febSMarek Pospisil result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
69005d3febSMarek Pospisil break;
707c478bd9Sstevel@tonic-gate case BSM_AUDITCTL:
71005d3febSMarek Pospisil result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
72005d3febSMarek Pospisil break;
73005d3febSMarek Pospisil case BSM_AUDIT:
74005d3febSMarek Pospisil if (audit_active == C2AUDIT_UNLOADED)
75005d3febSMarek Pospisil return (0);
76005d3febSMarek Pospisil result = audit((caddr_t)uap->a1, (int)uap->a2);
77005d3febSMarek Pospisil break;
78005d3febSMarek Pospisil case BSM_AUDITDOOR:
79005d3febSMarek Pospisil if (audit_active == C2AUDIT_LOADED) {
80005d3febSMarek Pospisil result = auditdoor((int)uap->a1);
81005d3febSMarek Pospisil break;
82005d3febSMarek Pospisil }
83a9f62b1aSToomas Soome /* FALLTHROUGH */
847c478bd9Sstevel@tonic-gate default:
85005d3febSMarek Pospisil if (audit_active == C2AUDIT_LOADED) {
86005d3febSMarek Pospisil result = EINVAL;
87005d3febSMarek Pospisil break;
88005d3febSMarek Pospisil }
897c478bd9Sstevel@tonic-gate /* Return a different error when not privileged */
907c478bd9Sstevel@tonic-gate err = secpolicy_audit_config(CRED());
917c478bd9Sstevel@tonic-gate if (err == 0)
927c478bd9Sstevel@tonic-gate return (EINVAL);
937c478bd9Sstevel@tonic-gate else
947c478bd9Sstevel@tonic-gate return (err);
957c478bd9Sstevel@tonic-gate }
96005d3febSMarek Pospisil rvp->r_vals = result;
97005d3febSMarek Pospisil return (result);
98005d3febSMarek Pospisil }
99005d3febSMarek Pospisil
100005d3febSMarek Pospisil /*
101005d3febSMarek Pospisil * Return the audit user ID for the current process. Currently only
102005d3febSMarek Pospisil * the privileged processes may see the audit id. That may change.
103005d3febSMarek Pospisil * If copyout is unsucessful return EFAULT.
104005d3febSMarek Pospisil */
105005d3febSMarek Pospisil int
getauid(caddr_t auid_p)106005d3febSMarek Pospisil getauid(caddr_t auid_p)
107005d3febSMarek Pospisil {
108005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
109005d3febSMarek Pospisil
110134a1f4eSCasper H.S. Dik if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
111005d3febSMarek Pospisil return (EPERM);
112005d3febSMarek Pospisil
113005d3febSMarek Pospisil ainfo = crgetauinfo(CRED());
114005d3febSMarek Pospisil if (ainfo == NULL)
115005d3febSMarek Pospisil return (EINVAL);
116005d3febSMarek Pospisil
117005d3febSMarek Pospisil if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
118005d3febSMarek Pospisil return (EFAULT);
119005d3febSMarek Pospisil
120005d3febSMarek Pospisil return (0);
121005d3febSMarek Pospisil }
122005d3febSMarek Pospisil
123005d3febSMarek Pospisil /*
124005d3febSMarek Pospisil * Set the audit userid, for a process. This can only be changed by
125005d3febSMarek Pospisil * privileged processes. The audit userid is inherited across forks & execs.
126005d3febSMarek Pospisil * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
127005d3febSMarek Pospisil */
128005d3febSMarek Pospisil int
setauid(caddr_t auid_p)129005d3febSMarek Pospisil setauid(caddr_t auid_p)
130005d3febSMarek Pospisil {
131005d3febSMarek Pospisil proc_t *p;
132005d3febSMarek Pospisil au_id_t auid;
133005d3febSMarek Pospisil cred_t *newcred;
134005d3febSMarek Pospisil auditinfo_addr_t *auinfo;
135005d3febSMarek Pospisil
136005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0)
137005d3febSMarek Pospisil return (EPERM);
138005d3febSMarek Pospisil
139005d3febSMarek Pospisil if (copyin(auid_p, &auid, sizeof (au_id_t))) {
140005d3febSMarek Pospisil return (EFAULT);
141005d3febSMarek Pospisil }
142005d3febSMarek Pospisil
143005d3febSMarek Pospisil newcred = cralloc();
144005d3febSMarek Pospisil if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
145005d3febSMarek Pospisil crfree(newcred);
146005d3febSMarek Pospisil return (EINVAL);
147005d3febSMarek Pospisil }
148005d3febSMarek Pospisil
149005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */
150005d3febSMarek Pospisil p = curproc;
151005d3febSMarek Pospisil mutex_enter(&p->p_crlock);
152005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred);
153005d3febSMarek Pospisil p->p_cred = newcred;
154005d3febSMarek Pospisil
155005d3febSMarek Pospisil auinfo->ai_auid = auid; /* update the auid */
156005d3febSMarek Pospisil
157005d3febSMarek Pospisil /* unlock and broadcast the cred changes */
158005d3febSMarek Pospisil mutex_exit(&p->p_crlock);
159005d3febSMarek Pospisil crset(p, newcred);
160005d3febSMarek Pospisil
161005d3febSMarek Pospisil return (0);
162005d3febSMarek Pospisil }
163005d3febSMarek Pospisil
164005d3febSMarek Pospisil /*
165005d3febSMarek Pospisil * Get the audit state information from the current process.
166005d3febSMarek Pospisil * Return EFAULT if copyout fails.
167005d3febSMarek Pospisil */
168005d3febSMarek Pospisil int
getaudit(caddr_t info_p)169005d3febSMarek Pospisil getaudit(caddr_t info_p)
170005d3febSMarek Pospisil {
171005d3febSMarek Pospisil STRUCT_DECL(auditinfo, info);
172005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
173005d3febSMarek Pospisil model_t model;
174005d3febSMarek Pospisil
175134a1f4eSCasper H.S. Dik if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
176005d3febSMarek Pospisil return (EPERM);
177005d3febSMarek Pospisil
178005d3febSMarek Pospisil model = get_udatamodel();
179005d3febSMarek Pospisil STRUCT_INIT(info, model);
180005d3febSMarek Pospisil
181005d3febSMarek Pospisil ainfo = crgetauinfo(CRED());
182005d3febSMarek Pospisil if (ainfo == NULL)
183005d3febSMarek Pospisil return (EINVAL);
184005d3febSMarek Pospisil
185005d3febSMarek Pospisil /* trying to read a process with an IPv6 address? */
186005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6)
187005d3febSMarek Pospisil return (EOVERFLOW);
188005d3febSMarek Pospisil
189005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
190005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
191005d3febSMarek Pospisil #ifdef _LP64
192005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) {
193005d3febSMarek Pospisil dev32_t dev;
194005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */
195005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
196005d3febSMarek Pospisil return (EOVERFLOW);
197005d3febSMarek Pospisil }
198005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, dev);
199005d3febSMarek Pospisil } else
200005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
201005d3febSMarek Pospisil #else
202005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
203005d3febSMarek Pospisil #endif
204005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
205005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
206005d3febSMarek Pospisil
207005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
208005d3febSMarek Pospisil return (EFAULT);
209005d3febSMarek Pospisil
210005d3febSMarek Pospisil return (0);
211005d3febSMarek Pospisil }
212005d3febSMarek Pospisil
213005d3febSMarek Pospisil /*
214005d3febSMarek Pospisil * Get the audit state information from the current process.
215005d3febSMarek Pospisil * Return EFAULT if copyout fails.
216005d3febSMarek Pospisil */
217005d3febSMarek Pospisil int
getaudit_addr(caddr_t info_p,int len)218005d3febSMarek Pospisil getaudit_addr(caddr_t info_p, int len)
219005d3febSMarek Pospisil {
220005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info);
221005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
222005d3febSMarek Pospisil model_t model;
223005d3febSMarek Pospisil
224134a1f4eSCasper H.S. Dik if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
225005d3febSMarek Pospisil return (EPERM);
226005d3febSMarek Pospisil
227005d3febSMarek Pospisil model = get_udatamodel();
228005d3febSMarek Pospisil STRUCT_INIT(info, model);
229005d3febSMarek Pospisil
230005d3febSMarek Pospisil if (len < STRUCT_SIZE(info))
231005d3febSMarek Pospisil return (EOVERFLOW);
232005d3febSMarek Pospisil
233005d3febSMarek Pospisil ainfo = crgetauinfo(CRED());
234005d3febSMarek Pospisil
235005d3febSMarek Pospisil if (ainfo == NULL)
236005d3febSMarek Pospisil return (EINVAL);
237005d3febSMarek Pospisil
238005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
239005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
240005d3febSMarek Pospisil #ifdef _LP64
241005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) {
242005d3febSMarek Pospisil dev32_t dev;
243005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */
244005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
245005d3febSMarek Pospisil return (EOVERFLOW);
246005d3febSMarek Pospisil }
247005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, dev);
248005d3febSMarek Pospisil } else
249005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
250005d3febSMarek Pospisil #else
251005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
252005d3febSMarek Pospisil #endif
253005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
254005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
255005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
256005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
257005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
258005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
259005d3febSMarek Pospisil
260005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
261005d3febSMarek Pospisil return (EFAULT);
262005d3febSMarek Pospisil
263005d3febSMarek Pospisil return (0);
264005d3febSMarek Pospisil }
265005d3febSMarek Pospisil
266005d3febSMarek Pospisil /*
267005d3febSMarek Pospisil * Set the audit state information for the current process.
268005d3febSMarek Pospisil * Return EFAULT if copyout fails.
269005d3febSMarek Pospisil */
270005d3febSMarek Pospisil int
setaudit(caddr_t info_p)271005d3febSMarek Pospisil setaudit(caddr_t info_p)
272005d3febSMarek Pospisil {
273005d3febSMarek Pospisil STRUCT_DECL(auditinfo, info);
274005d3febSMarek Pospisil proc_t *p;
275005d3febSMarek Pospisil cred_t *newcred;
276005d3febSMarek Pospisil model_t model;
277005d3febSMarek Pospisil auditinfo_addr_t *ainfo;
278005d3febSMarek Pospisil
279005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0)
280005d3febSMarek Pospisil return (EPERM);
281005d3febSMarek Pospisil
282005d3febSMarek Pospisil model = get_udatamodel();
283005d3febSMarek Pospisil STRUCT_INIT(info, model);
284005d3febSMarek Pospisil
285005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
286005d3febSMarek Pospisil return (EFAULT);
287005d3febSMarek Pospisil
288005d3febSMarek Pospisil newcred = cralloc();
289005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
290005d3febSMarek Pospisil crfree(newcred);
291005d3febSMarek Pospisil return (EINVAL);
292005d3febSMarek Pospisil }
293005d3febSMarek Pospisil
294005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */
295005d3febSMarek Pospisil p = curproc;
296005d3febSMarek Pospisil mutex_enter(&p->p_crlock);
297005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred);
298005d3febSMarek Pospisil p->p_cred = newcred;
299005d3febSMarek Pospisil
300005d3febSMarek Pospisil /* Set audit mask, id, termid and session id as specified */
301005d3febSMarek Pospisil ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
302005d3febSMarek Pospisil #ifdef _LP64
303005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */
304005d3febSMarek Pospisil if (model == DATAMODEL_ILP32)
305005d3febSMarek Pospisil ainfo->ai_termid.at_port =
306005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.port));
307005d3febSMarek Pospisil else
308005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
309005d3febSMarek Pospisil #else
310005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
311005d3febSMarek Pospisil #endif
312005d3febSMarek Pospisil ainfo->ai_termid.at_type = AU_IPv4;
313005d3febSMarek Pospisil ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
314005d3febSMarek Pospisil ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
315005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
316005d3febSMarek Pospisil
317005d3febSMarek Pospisil /* unlock and broadcast the cred changes */
318005d3febSMarek Pospisil mutex_exit(&p->p_crlock);
319005d3febSMarek Pospisil crset(p, newcred);
320005d3febSMarek Pospisil
321005d3febSMarek Pospisil return (0);
322005d3febSMarek Pospisil }
323005d3febSMarek Pospisil
324005d3febSMarek Pospisil /*
325005d3febSMarek Pospisil * Set the audit state information for the current process.
326005d3febSMarek Pospisil * Return EFAULT if copyin fails.
327005d3febSMarek Pospisil */
328005d3febSMarek Pospisil int
setaudit_addr(caddr_t info_p,int len)329005d3febSMarek Pospisil setaudit_addr(caddr_t info_p, int len)
330005d3febSMarek Pospisil {
331005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info);
332005d3febSMarek Pospisil proc_t *p;
333005d3febSMarek Pospisil cred_t *newcred;
334005d3febSMarek Pospisil model_t model;
335005d3febSMarek Pospisil int i;
336005d3febSMarek Pospisil int type;
337005d3febSMarek Pospisil auditinfo_addr_t *ainfo;
338005d3febSMarek Pospisil
339005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0)
340005d3febSMarek Pospisil return (EPERM);
341005d3febSMarek Pospisil
342005d3febSMarek Pospisil model = get_udatamodel();
343005d3febSMarek Pospisil STRUCT_INIT(info, model);
344005d3febSMarek Pospisil
345005d3febSMarek Pospisil if (len < STRUCT_SIZE(info))
346005d3febSMarek Pospisil return (EOVERFLOW);
347005d3febSMarek Pospisil
348005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
349005d3febSMarek Pospisil return (EFAULT);
350005d3febSMarek Pospisil
351005d3febSMarek Pospisil type = STRUCT_FGET(info, ai_termid.at_type);
352005d3febSMarek Pospisil if ((type != AU_IPv4) && (type != AU_IPv6))
353005d3febSMarek Pospisil return (EINVAL);
354005d3febSMarek Pospisil
355005d3febSMarek Pospisil newcred = cralloc();
356005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
357005d3febSMarek Pospisil crfree(newcred);
358005d3febSMarek Pospisil return (EINVAL);
359005d3febSMarek Pospisil }
360005d3febSMarek Pospisil
361005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */
362005d3febSMarek Pospisil p = curproc;
363005d3febSMarek Pospisil mutex_enter(&p->p_crlock);
364005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred);
365005d3febSMarek Pospisil p->p_cred = newcred;
366005d3febSMarek Pospisil
367005d3febSMarek Pospisil /* Set audit mask, id, termid and session id as specified */
368005d3febSMarek Pospisil ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
369005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
370005d3febSMarek Pospisil #ifdef _LP64
371005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */
372005d3febSMarek Pospisil if (model == DATAMODEL_ILP32)
373005d3febSMarek Pospisil ainfo->ai_termid.at_port =
374005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
375005d3febSMarek Pospisil else
376005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
377005d3febSMarek Pospisil #else
378005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
379005d3febSMarek Pospisil #endif
380005d3febSMarek Pospisil ainfo->ai_termid.at_type = type;
381005d3febSMarek Pospisil bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
382005d3febSMarek Pospisil for (i = 0; i < (type/sizeof (int)); i++)
383005d3febSMarek Pospisil ainfo->ai_termid.at_addr[i] =
384005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[i]);
385005d3febSMarek Pospisil
386005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6 &&
387005d3febSMarek Pospisil IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
388005d3febSMarek Pospisil ainfo->ai_termid.at_type = AU_IPv4;
389005d3febSMarek Pospisil ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
390005d3febSMarek Pospisil ainfo->ai_termid.at_addr[1] = 0;
391005d3febSMarek Pospisil ainfo->ai_termid.at_addr[2] = 0;
392005d3febSMarek Pospisil ainfo->ai_termid.at_addr[3] = 0;
393005d3febSMarek Pospisil }
394005d3febSMarek Pospisil
395005d3febSMarek Pospisil ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
396005d3febSMarek Pospisil
397005d3febSMarek Pospisil /* unlock and broadcast the cred changes */
398005d3febSMarek Pospisil mutex_exit(&p->p_crlock);
399005d3febSMarek Pospisil crset(p, newcred);
400005d3febSMarek Pospisil
401005d3febSMarek Pospisil return (0);
402005d3febSMarek Pospisil }
403005d3febSMarek Pospisil
404005d3febSMarek Pospisil /*
405005d3febSMarek Pospisil * Get the global policy flag
406005d3febSMarek Pospisil */
407005d3febSMarek Pospisil static int
getpolicy(caddr_t data)408005d3febSMarek Pospisil getpolicy(caddr_t data)
409005d3febSMarek Pospisil {
41096093503SMarek Pospisil uint32_t policy;
411005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
412005d3febSMarek Pospisil
413005d3febSMarek Pospisil policy = audit_policy | kctx->auk_policy;
414005d3febSMarek Pospisil
41596093503SMarek Pospisil if (copyout(&policy, data, sizeof (policy)))
416005d3febSMarek Pospisil return (EFAULT);
417005d3febSMarek Pospisil return (0);
418005d3febSMarek Pospisil }
419005d3febSMarek Pospisil
420005d3febSMarek Pospisil /*
421005d3febSMarek Pospisil * Set the global and local policy flags
422005d3febSMarek Pospisil *
423005d3febSMarek Pospisil * The global flags only make sense from the global zone;
424005d3febSMarek Pospisil * the local flags depend on the AUDIT_PERZONE policy:
425005d3febSMarek Pospisil * if the perzone policy is set, then policy is set separately
426005d3febSMarek Pospisil * per zone, else held only in the global zone.
427005d3febSMarek Pospisil *
428005d3febSMarek Pospisil * The initial value of a local zone's policy flag is determined
429005d3febSMarek Pospisil * by the value of the global zone's flags at the time the
430005d3febSMarek Pospisil * local zone is created.
431005d3febSMarek Pospisil *
432*bbf21555SRichard Lowe * While auditconfig(8) allows setting and unsetting policies one bit
433005d3febSMarek Pospisil * at a time, the mask passed in from auditconfig() is created by a
434005d3febSMarek Pospisil * syscall to getpolicy and then modified based on the auditconfig()
435005d3febSMarek Pospisil * cmd line, so the input policy value is used to replace the existing
436005d3febSMarek Pospisil * policy.
437005d3febSMarek Pospisil */
438005d3febSMarek Pospisil static int
setpolicy(caddr_t data)439005d3febSMarek Pospisil setpolicy(caddr_t data)
440005d3febSMarek Pospisil {
44196093503SMarek Pospisil uint32_t policy;
442005d3febSMarek Pospisil au_kcontext_t *kctx;
443005d3febSMarek Pospisil
44496093503SMarek Pospisil if (copyin(data, &policy, sizeof (policy)))
445005d3febSMarek Pospisil return (EFAULT);
446005d3febSMarek Pospisil
447005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
448005d3febSMarek Pospisil
449005d3febSMarek Pospisil if (INGLOBALZONE(curproc)) {
450005d3febSMarek Pospisil if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
451005d3febSMarek Pospisil return (EINVAL);
452005d3febSMarek Pospisil
453005d3febSMarek Pospisil audit_policy = policy & AUDIT_GLOBAL;
454005d3febSMarek Pospisil } else {
455005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE))
456005d3febSMarek Pospisil return (EINVAL);
457005d3febSMarek Pospisil
458005d3febSMarek Pospisil if (policy & ~AUDIT_LOCAL) /* global bits are a no-no */
459005d3febSMarek Pospisil return (EINVAL);
460005d3febSMarek Pospisil }
461005d3febSMarek Pospisil kctx->auk_policy = policy & AUDIT_LOCAL;
462005d3febSMarek Pospisil
463005d3febSMarek Pospisil /*
464005d3febSMarek Pospisil * auk_current_vp is NULL before auditd starts (or during early
465005d3febSMarek Pospisil * auditd starup) or if auditd is halted; in either case,
466005d3febSMarek Pospisil * notification of a policy change is not needed, since auditd
467005d3febSMarek Pospisil * reads policy as it comes up. The error return from au_doormsg()
468005d3febSMarek Pospisil * is ignored to avoid a race condition -- for example if auditd
469005d3febSMarek Pospisil * segv's, the audit state may be "auditing" but the door may
470005d3febSMarek Pospisil * be closed. Returning an error if the door is open makes it
471005d3febSMarek Pospisil * impossible for Greenline to restart auditd.
472d7c4a96fSAlex Wilson *
473d7c4a96fSAlex Wilson * Note that auk_current_vp can change (e.g. to NULL) as long as we
474d7c4a96fSAlex Wilson * aren't holding auk_svc_lock -- so au_door_upcall() will eventually
475d7c4a96fSAlex Wilson * double-check this condition after it takes auk_svc_lock.
476005d3febSMarek Pospisil */
477005d3febSMarek Pospisil if (kctx->auk_current_vp != NULL)
478005d3febSMarek Pospisil (void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
479005d3febSMarek Pospisil
480005d3febSMarek Pospisil /*
481005d3febSMarek Pospisil * Wake up anyone who might have blocked on full audit
482005d3febSMarek Pospisil * partitions. audit daemons need to set AUDIT_FULL when no
483005d3febSMarek Pospisil * space so we can tell if we should start dropping records.
484005d3febSMarek Pospisil */
485005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
486005d3febSMarek Pospisil
487005d3febSMarek Pospisil if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
488005d3febSMarek Pospisil (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
489005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv));
490005d3febSMarek Pospisil
491005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
492005d3febSMarek Pospisil
493005d3febSMarek Pospisil return (0);
494005d3febSMarek Pospisil }
495005d3febSMarek Pospisil
496005d3febSMarek Pospisil static int
getamask(caddr_t data)497f8994074SJan Friedel getamask(caddr_t data)
498f8994074SJan Friedel {
499f8994074SJan Friedel au_kcontext_t *kctx;
500f8994074SJan Friedel
501f8994074SJan Friedel kctx = GET_KCTX_PZ;
502f8994074SJan Friedel
503f8994074SJan Friedel if (copyout(&kctx->auk_info.ai_amask, data, sizeof (au_mask_t)))
504f8994074SJan Friedel return (EFAULT);
505f8994074SJan Friedel
506f8994074SJan Friedel return (0);
507f8994074SJan Friedel }
508f8994074SJan Friedel
509f8994074SJan Friedel static int
setamask(caddr_t data)510f8994074SJan Friedel setamask(caddr_t data)
511f8994074SJan Friedel {
512f8994074SJan Friedel au_mask_t mask;
513f8994074SJan Friedel au_kcontext_t *kctx;
514f8994074SJan Friedel
515f8994074SJan Friedel if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
516f8994074SJan Friedel return (EINVAL);
517f8994074SJan Friedel
518f8994074SJan Friedel kctx = GET_KCTX_NGZ;
519f8994074SJan Friedel
520f8994074SJan Friedel if (copyin(data, &mask, sizeof (au_mask_t)))
521f8994074SJan Friedel return (EFAULT);
522f8994074SJan Friedel
523f8994074SJan Friedel kctx->auk_info.ai_amask = mask;
524f8994074SJan Friedel return (0);
525f8994074SJan Friedel }
526f8994074SJan Friedel
527f8994074SJan Friedel static int
getkmask(caddr_t data)528005d3febSMarek Pospisil getkmask(caddr_t data)
529005d3febSMarek Pospisil {
530005d3febSMarek Pospisil au_kcontext_t *kctx;
531005d3febSMarek Pospisil
532005d3febSMarek Pospisil kctx = GET_KCTX_PZ;
533005d3febSMarek Pospisil
534f8994074SJan Friedel if (copyout(&kctx->auk_info.ai_namask, data, sizeof (au_mask_t)))
535005d3febSMarek Pospisil return (EFAULT);
536005d3febSMarek Pospisil return (0);
537005d3febSMarek Pospisil }
538005d3febSMarek Pospisil
539005d3febSMarek Pospisil static int
setkmask(caddr_t data)540005d3febSMarek Pospisil setkmask(caddr_t data)
541005d3febSMarek Pospisil {
542005d3febSMarek Pospisil au_mask_t mask;
543005d3febSMarek Pospisil au_kcontext_t *kctx;
544005d3febSMarek Pospisil
545005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
546005d3febSMarek Pospisil return (EINVAL);
547005d3febSMarek Pospisil
548005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
549005d3febSMarek Pospisil
550005d3febSMarek Pospisil if (copyin(data, &mask, sizeof (au_mask_t)))
551005d3febSMarek Pospisil return (EFAULT);
552005d3febSMarek Pospisil
553f8994074SJan Friedel kctx->auk_info.ai_namask = mask;
554005d3febSMarek Pospisil return (0);
555005d3febSMarek Pospisil }
556005d3febSMarek Pospisil
557005d3febSMarek Pospisil static int
getkaudit(caddr_t info_p,int len)558005d3febSMarek Pospisil getkaudit(caddr_t info_p, int len)
559005d3febSMarek Pospisil {
560005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info);
561005d3febSMarek Pospisil model_t model;
562005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
563005d3febSMarek Pospisil
564005d3febSMarek Pospisil model = get_udatamodel();
565005d3febSMarek Pospisil STRUCT_INIT(info, model);
566005d3febSMarek Pospisil
567005d3febSMarek Pospisil if (len < STRUCT_SIZE(info))
568005d3febSMarek Pospisil return (EOVERFLOW);
569005d3febSMarek Pospisil
570005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
571f8994074SJan Friedel STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_namask);
572005d3febSMarek Pospisil #ifdef _LP64
573005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) {
574005d3febSMarek Pospisil dev32_t dev;
575005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */
576005d3febSMarek Pospisil if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
577005d3febSMarek Pospisil return (EOVERFLOW);
578005d3febSMarek Pospisil }
579005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, dev);
580005d3febSMarek Pospisil } else {
581005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port,
582005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port);
583005d3febSMarek Pospisil }
584005d3febSMarek Pospisil #else
585005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port,
586005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port);
587005d3febSMarek Pospisil #endif
588005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_type,
589005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type);
590005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[0],
591005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0]);
592005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[1],
593005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1]);
594005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[2],
595005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2]);
596005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[3],
597005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3]);
598005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
599005d3febSMarek Pospisil
600005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
601005d3febSMarek Pospisil return (EFAULT);
602005d3febSMarek Pospisil
603005d3febSMarek Pospisil return (0);
604005d3febSMarek Pospisil }
605005d3febSMarek Pospisil
606005d3febSMarek Pospisil /*
607005d3febSMarek Pospisil * the host address for AUDIT_PERZONE == 0 is that of the global
608005d3febSMarek Pospisil * zone and for local zones it is of the current zone.
609005d3febSMarek Pospisil */
610005d3febSMarek Pospisil static int
setkaudit(caddr_t info_p,int len)611005d3febSMarek Pospisil setkaudit(caddr_t info_p, int len)
612005d3febSMarek Pospisil {
613005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info);
614005d3febSMarek Pospisil model_t model;
615005d3febSMarek Pospisil au_kcontext_t *kctx;
616005d3febSMarek Pospisil
617005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
618005d3febSMarek Pospisil return (EINVAL);
619005d3febSMarek Pospisil
620005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
621005d3febSMarek Pospisil
622005d3febSMarek Pospisil model = get_udatamodel();
623005d3febSMarek Pospisil STRUCT_INIT(info, model);
624005d3febSMarek Pospisil
625005d3febSMarek Pospisil if (len < STRUCT_SIZE(info))
626005d3febSMarek Pospisil return (EOVERFLOW);
627005d3febSMarek Pospisil
628005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
629005d3febSMarek Pospisil return (EFAULT);
630005d3febSMarek Pospisil
631005d3febSMarek Pospisil if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
632005d3febSMarek Pospisil (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
633005d3febSMarek Pospisil return (EINVAL);
634005d3febSMarek Pospisil
635005d3febSMarek Pospisil /* Set audit mask, termid and session id as specified */
636005d3febSMarek Pospisil kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
637f8994074SJan Friedel kctx->auk_info.ai_namask = STRUCT_FGET(info, ai_mask);
638005d3febSMarek Pospisil #ifdef _LP64
639005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */
640005d3febSMarek Pospisil if (model == DATAMODEL_ILP32)
641005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port =
642005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
643005d3febSMarek Pospisil else
644005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port =
645005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_port);
646005d3febSMarek Pospisil #else
647005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
648005d3febSMarek Pospisil #endif
649005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
650005d3febSMarek Pospisil bzero(&kctx->auk_info.ai_termid.at_addr[0],
651005d3febSMarek Pospisil sizeof (kctx->auk_info.ai_termid.at_addr));
652005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] =
653005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[0]);
654005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] =
655005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[1]);
656005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] =
657005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[2]);
658005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] =
659005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[3]);
660005d3febSMarek Pospisil kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
661005d3febSMarek Pospisil
662005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
663005d3febSMarek Pospisil IN6_IS_ADDR_V4MAPPED(
664005d3febSMarek Pospisil ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
665005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = AU_IPv4;
666005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] =
667005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3];
668005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] = 0;
669005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] = 0;
670005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] = 0;
671005d3febSMarek Pospisil }
672005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
673005d3febSMarek Pospisil kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
674005d3febSMarek Pospisil (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
675005d3febSMarek Pospisil else
676005d3febSMarek Pospisil kctx->auk_hostaddr_valid =
677005d3febSMarek Pospisil (kctx->auk_info.ai_termid.at_addr[0] ==
678005d3febSMarek Pospisil htonl(INADDR_ANY)) ? 0 : 1;
679005d3febSMarek Pospisil
680005d3febSMarek Pospisil return (0);
681005d3febSMarek Pospisil }
682005d3febSMarek Pospisil
683005d3febSMarek Pospisil static int
getqctrl(caddr_t data)684005d3febSMarek Pospisil getqctrl(caddr_t data)
685005d3febSMarek Pospisil {
686005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
687005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl);
688005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel());
689005d3febSMarek Pospisil
690005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
691005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
692005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
693005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
694005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
695005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
696005d3febSMarek Pospisil
697005d3febSMarek Pospisil if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
698005d3febSMarek Pospisil return (EFAULT);
699005d3febSMarek Pospisil
700005d3febSMarek Pospisil return (0);
701005d3febSMarek Pospisil }
702005d3febSMarek Pospisil
703005d3febSMarek Pospisil static int
setqctrl(caddr_t data)704005d3febSMarek Pospisil setqctrl(caddr_t data)
705005d3febSMarek Pospisil {
706005d3febSMarek Pospisil au_kcontext_t *kctx;
707005d3febSMarek Pospisil struct au_qctrl qctrl_tmp;
708005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl);
709005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel());
710005d3febSMarek Pospisil
711005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
712005d3febSMarek Pospisil return (EINVAL);
713005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
714005d3febSMarek Pospisil
715005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
716005d3febSMarek Pospisil return (EFAULT);
717005d3febSMarek Pospisil
718005d3febSMarek Pospisil qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
719005d3febSMarek Pospisil qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
720005d3febSMarek Pospisil qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
721005d3febSMarek Pospisil qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
722005d3febSMarek Pospisil
723005d3febSMarek Pospisil /* enforce sane values */
724005d3febSMarek Pospisil
725005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
726005d3febSMarek Pospisil return (EINVAL);
727005d3febSMarek Pospisil
728005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
729005d3febSMarek Pospisil return (EINVAL);
730005d3febSMarek Pospisil
731005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
732005d3febSMarek Pospisil return (EINVAL);
733005d3febSMarek Pospisil
734005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
735005d3febSMarek Pospisil return (EINVAL);
736005d3febSMarek Pospisil
737005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
738005d3febSMarek Pospisil return (EINVAL);
739005d3febSMarek Pospisil
740005d3febSMarek Pospisil if (qctrl_tmp.aq_delay == 0)
741005d3febSMarek Pospisil return (EINVAL);
742005d3febSMarek Pospisil
743005d3febSMarek Pospisil if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
744005d3febSMarek Pospisil return (EINVAL);
745005d3febSMarek Pospisil
746005d3febSMarek Pospisil /* update everything at once so things are consistant */
747005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
748005d3febSMarek Pospisil kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
749005d3febSMarek Pospisil kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
750005d3febSMarek Pospisil kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
751005d3febSMarek Pospisil kctx->auk_queue.delay = qctrl_tmp.aq_delay;
752005d3febSMarek Pospisil
753005d3febSMarek Pospisil if (kctx->auk_queue.rd_block &&
754005d3febSMarek Pospisil kctx->auk_queue.cnt > kctx->auk_queue.lowater)
755005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv));
756005d3febSMarek Pospisil
757005d3febSMarek Pospisil if (kctx->auk_queue.wt_block &&
758005d3febSMarek Pospisil kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
759005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv));
760005d3febSMarek Pospisil
761005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
762005d3febSMarek Pospisil
763005d3febSMarek Pospisil return (0);
764005d3febSMarek Pospisil }
765005d3febSMarek Pospisil
766005d3febSMarek Pospisil static int
getcwd(caddr_t data,int length)767005d3febSMarek Pospisil getcwd(caddr_t data, int length)
768005d3febSMarek Pospisil {
769005d3febSMarek Pospisil struct p_audit_data *pad;
770005d3febSMarek Pospisil struct audit_path *app;
771005d3febSMarek Pospisil int pathlen;
772005d3febSMarek Pospisil
773005d3febSMarek Pospisil pad = P2A(curproc);
774005d3febSMarek Pospisil ASSERT(pad != NULL);
775005d3febSMarek Pospisil
776005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock));
777005d3febSMarek Pospisil app = pad->pad_cwd;
778005d3febSMarek Pospisil au_pathhold(app);
779005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock));
780005d3febSMarek Pospisil
781005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0];
782005d3febSMarek Pospisil if (pathlen > length) {
783005d3febSMarek Pospisil au_pathrele(app);
784005d3febSMarek Pospisil return (E2BIG);
785005d3febSMarek Pospisil }
786005d3febSMarek Pospisil
787005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) {
788005d3febSMarek Pospisil au_pathrele(app);
789005d3febSMarek Pospisil return (EFAULT);
790005d3febSMarek Pospisil }
791005d3febSMarek Pospisil
792005d3febSMarek Pospisil au_pathrele(app);
793005d3febSMarek Pospisil return (0);
794005d3febSMarek Pospisil }
795005d3febSMarek Pospisil
796005d3febSMarek Pospisil static int
getcar(caddr_t data,int length)797005d3febSMarek Pospisil getcar(caddr_t data, int length)
798005d3febSMarek Pospisil {
799005d3febSMarek Pospisil struct p_audit_data *pad;
800005d3febSMarek Pospisil struct audit_path *app;
801005d3febSMarek Pospisil int pathlen;
802005d3febSMarek Pospisil
803005d3febSMarek Pospisil pad = P2A(curproc);
804005d3febSMarek Pospisil ASSERT(pad != NULL);
805005d3febSMarek Pospisil
806005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock));
807005d3febSMarek Pospisil app = pad->pad_root;
808005d3febSMarek Pospisil au_pathhold(app);
809005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock));
810005d3febSMarek Pospisil
811005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0];
812005d3febSMarek Pospisil if (pathlen > length) {
813005d3febSMarek Pospisil au_pathrele(app);
814005d3febSMarek Pospisil return (E2BIG);
815005d3febSMarek Pospisil }
816005d3febSMarek Pospisil
817005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) {
818005d3febSMarek Pospisil au_pathrele(app);
819005d3febSMarek Pospisil return (EFAULT);
820005d3febSMarek Pospisil }
821005d3febSMarek Pospisil
822005d3febSMarek Pospisil au_pathrele(app);
823005d3febSMarek Pospisil return (0);
824005d3febSMarek Pospisil }
825005d3febSMarek Pospisil
826005d3febSMarek Pospisil static int
getstat(caddr_t data)827005d3febSMarek Pospisil getstat(caddr_t data)
828005d3febSMarek Pospisil {
829005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
830005d3febSMarek Pospisil
831005d3febSMarek Pospisil membar_consumer();
832005d3febSMarek Pospisil
833005d3febSMarek Pospisil if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
834005d3febSMarek Pospisil return (EFAULT);
835005d3febSMarek Pospisil return (0);
836005d3febSMarek Pospisil }
837005d3febSMarek Pospisil
838005d3febSMarek Pospisil static int
setstat(caddr_t data)839005d3febSMarek Pospisil setstat(caddr_t data)
840005d3febSMarek Pospisil {
841005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
842005d3febSMarek Pospisil au_stat_t au_stat;
843005d3febSMarek Pospisil
844005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
845005d3febSMarek Pospisil return (EINVAL);
846005d3febSMarek Pospisil
847005d3febSMarek Pospisil if (copyin(data, &au_stat, sizeof (au_stat_t)))
848005d3febSMarek Pospisil return (EFAULT);
849005d3febSMarek Pospisil
850005d3febSMarek Pospisil if (au_stat.as_generated == CLEAR_VAL)
851005d3febSMarek Pospisil kctx->auk_statistics.as_generated = 0;
852005d3febSMarek Pospisil if (au_stat.as_nonattrib == CLEAR_VAL)
853005d3febSMarek Pospisil kctx->auk_statistics.as_nonattrib = 0;
854005d3febSMarek Pospisil if (au_stat.as_kernel == CLEAR_VAL)
855005d3febSMarek Pospisil kctx->auk_statistics.as_kernel = 0;
856005d3febSMarek Pospisil if (au_stat.as_audit == CLEAR_VAL)
857005d3febSMarek Pospisil kctx->auk_statistics.as_audit = 0;
858005d3febSMarek Pospisil if (au_stat.as_auditctl == CLEAR_VAL)
859005d3febSMarek Pospisil kctx->auk_statistics.as_auditctl = 0;
860005d3febSMarek Pospisil if (au_stat.as_enqueue == CLEAR_VAL)
861005d3febSMarek Pospisil kctx->auk_statistics.as_enqueue = 0;
862005d3febSMarek Pospisil if (au_stat.as_written == CLEAR_VAL)
863005d3febSMarek Pospisil kctx->auk_statistics.as_written = 0;
864005d3febSMarek Pospisil if (au_stat.as_wblocked == CLEAR_VAL)
865005d3febSMarek Pospisil kctx->auk_statistics.as_wblocked = 0;
866005d3febSMarek Pospisil if (au_stat.as_rblocked == CLEAR_VAL)
867005d3febSMarek Pospisil kctx->auk_statistics.as_rblocked = 0;
868005d3febSMarek Pospisil if (au_stat.as_dropped == CLEAR_VAL)
869005d3febSMarek Pospisil kctx->auk_statistics.as_dropped = 0;
870005d3febSMarek Pospisil if (au_stat.as_totalsize == CLEAR_VAL)
871005d3febSMarek Pospisil kctx->auk_statistics.as_totalsize = 0;
872005d3febSMarek Pospisil
873005d3febSMarek Pospisil membar_producer();
874005d3febSMarek Pospisil
875005d3febSMarek Pospisil return (0);
876005d3febSMarek Pospisil
877005d3febSMarek Pospisil }
878005d3febSMarek Pospisil
879005d3febSMarek Pospisil static int
setumask(caddr_t data)880005d3febSMarek Pospisil setumask(caddr_t data)
881005d3febSMarek Pospisil {
882005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info);
883005d3febSMarek Pospisil struct proc *p;
884005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
885005d3febSMarek Pospisil model_t model;
886005d3febSMarek Pospisil
887005d3febSMarek Pospisil /* setumask not applicable in non-global zones without perzone policy */
888005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
889005d3febSMarek Pospisil return (EINVAL);
890005d3febSMarek Pospisil
891005d3febSMarek Pospisil model = get_udatamodel();
892005d3febSMarek Pospisil STRUCT_INIT(user_info, model);
893005d3febSMarek Pospisil
894005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
895005d3febSMarek Pospisil return (EFAULT);
896005d3febSMarek Pospisil
897005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */
898005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) {
899005d3febSMarek Pospisil cred_t *cr;
900005d3febSMarek Pospisil
901005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */
902005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
903005d3febSMarek Pospisil continue;
904005d3febSMarek Pospisil
905005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */
906005d3febSMarek Pospisil
907005d3febSMarek Pospisil /* skip system processes and ones being created or going away */
908005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB ||
909005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
910005d3febSMarek Pospisil mutex_exit(&p->p_lock);
911005d3febSMarek Pospisil continue;
912005d3febSMarek Pospisil }
913005d3febSMarek Pospisil
914005d3febSMarek Pospisil mutex_enter(&p->p_crlock);
915005d3febSMarek Pospisil crhold(cr = p->p_cred);
916005d3febSMarek Pospisil mutex_exit(&p->p_crlock);
917005d3febSMarek Pospisil ainfo = crgetauinfo(cr);
918005d3febSMarek Pospisil if (ainfo == NULL) {
919005d3febSMarek Pospisil mutex_exit(&p->p_lock);
920005d3febSMarek Pospisil crfree(cr);
921005d3febSMarek Pospisil continue;
922005d3febSMarek Pospisil }
923005d3febSMarek Pospisil
924005d3febSMarek Pospisil if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
925005d3febSMarek Pospisil au_mask_t mask;
926005d3febSMarek Pospisil int err;
927005d3febSMarek Pospisil
928005d3febSMarek Pospisil /*
929005d3febSMarek Pospisil * Here's a process which matches the specified auid.
930005d3febSMarek Pospisil * If its mask doesn't already match the new mask,
931005d3febSMarek Pospisil * save the new mask in the pad, to be picked up
932005d3febSMarek Pospisil * next syscall.
933005d3febSMarek Pospisil */
934005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask);
935005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
936005d3febSMarek Pospisil crfree(cr);
937005d3febSMarek Pospisil if (err != 0) {
938005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p);
939005d3febSMarek Pospisil ASSERT(pad != NULL);
940005d3febSMarek Pospisil
941005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock));
942005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK;
943005d3febSMarek Pospisil pad->pad_newmask = mask;
944005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock));
945005d3febSMarek Pospisil
946005d3febSMarek Pospisil /*
947005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since
948005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is
949005d3febSMarek Pospisil * enabled...due to syscall auditing.
950005d3febSMarek Pospisil */
951005d3febSMarek Pospisil }
952005d3febSMarek Pospisil } else {
953005d3febSMarek Pospisil crfree(cr);
954005d3febSMarek Pospisil }
955005d3febSMarek Pospisil mutex_exit(&p->p_lock);
956005d3febSMarek Pospisil }
957005d3febSMarek Pospisil mutex_exit(&pidlock);
958005d3febSMarek Pospisil
959005d3febSMarek Pospisil return (0);
960005d3febSMarek Pospisil }
961005d3febSMarek Pospisil
962005d3febSMarek Pospisil static int
setsmask(caddr_t data)963005d3febSMarek Pospisil setsmask(caddr_t data)
964005d3febSMarek Pospisil {
965005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info);
966005d3febSMarek Pospisil struct proc *p;
967005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
968005d3febSMarek Pospisil model_t model;
969005d3febSMarek Pospisil
970005d3febSMarek Pospisil /* setsmask not applicable in non-global zones without perzone policy */
971005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
972005d3febSMarek Pospisil return (EINVAL);
973005d3febSMarek Pospisil
974005d3febSMarek Pospisil model = get_udatamodel();
975005d3febSMarek Pospisil STRUCT_INIT(user_info, model);
976005d3febSMarek Pospisil
977005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
978005d3febSMarek Pospisil return (EFAULT);
979005d3febSMarek Pospisil
980005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */
981005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) {
982005d3febSMarek Pospisil cred_t *cr;
983005d3febSMarek Pospisil
984005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */
985005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
986005d3febSMarek Pospisil continue;
987005d3febSMarek Pospisil
988005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */
989005d3febSMarek Pospisil
990005d3febSMarek Pospisil /* skip system processes and ones being created or going away */
991005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB ||
992005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
993005d3febSMarek Pospisil mutex_exit(&p->p_lock);
994005d3febSMarek Pospisil continue;
995005d3febSMarek Pospisil }
996005d3febSMarek Pospisil
997005d3febSMarek Pospisil mutex_enter(&p->p_crlock);
998005d3febSMarek Pospisil crhold(cr = p->p_cred);
999005d3febSMarek Pospisil mutex_exit(&p->p_crlock);
1000005d3febSMarek Pospisil ainfo = crgetauinfo(cr);
1001005d3febSMarek Pospisil if (ainfo == NULL) {
1002005d3febSMarek Pospisil mutex_exit(&p->p_lock);
1003005d3febSMarek Pospisil crfree(cr);
1004005d3febSMarek Pospisil continue;
1005005d3febSMarek Pospisil }
1006005d3febSMarek Pospisil
1007005d3febSMarek Pospisil if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
1008005d3febSMarek Pospisil au_mask_t mask;
1009005d3febSMarek Pospisil int err;
1010005d3febSMarek Pospisil
1011005d3febSMarek Pospisil /*
1012005d3febSMarek Pospisil * Here's a process which matches the specified asid.
1013005d3febSMarek Pospisil * If its mask doesn't already match the new mask,
1014005d3febSMarek Pospisil * save the new mask in the pad, to be picked up
1015005d3febSMarek Pospisil * next syscall.
1016005d3febSMarek Pospisil */
1017005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask);
1018005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1019005d3febSMarek Pospisil crfree(cr);
1020005d3febSMarek Pospisil if (err != 0) {
1021005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p);
1022005d3febSMarek Pospisil ASSERT(pad != NULL);
1023005d3febSMarek Pospisil
1024005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock));
1025005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK;
1026005d3febSMarek Pospisil pad->pad_newmask = mask;
1027005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock));
1028005d3febSMarek Pospisil
1029005d3febSMarek Pospisil /*
1030005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since
1031005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is
1032005d3febSMarek Pospisil * enabled...due to syscall auditing.
1033005d3febSMarek Pospisil */
1034005d3febSMarek Pospisil }
1035005d3febSMarek Pospisil } else {
1036005d3febSMarek Pospisil crfree(cr);
1037005d3febSMarek Pospisil }
1038005d3febSMarek Pospisil mutex_exit(&p->p_lock);
1039005d3febSMarek Pospisil }
1040005d3febSMarek Pospisil mutex_exit(&pidlock);
1041005d3febSMarek Pospisil
1042005d3febSMarek Pospisil return (0);
1043005d3febSMarek Pospisil }
1044005d3febSMarek Pospisil
1045005d3febSMarek Pospisil /*
1046005d3febSMarek Pospisil * Get the current audit state of the system
1047005d3febSMarek Pospisil */
1048005d3febSMarek Pospisil static int
getcond(caddr_t data)1049005d3febSMarek Pospisil getcond(caddr_t data)
1050005d3febSMarek Pospisil {
1051005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
1052005d3febSMarek Pospisil
1053005d3febSMarek Pospisil if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
1054005d3febSMarek Pospisil return (EFAULT);
1055005d3febSMarek Pospisil
1056005d3febSMarek Pospisil return (0);
1057005d3febSMarek Pospisil }
1058005d3febSMarek Pospisil
1059005d3febSMarek Pospisil /*
1060005d3febSMarek Pospisil * Set the current audit state of the system to on (AUC_AUDITING) or
1061005d3febSMarek Pospisil * off (AUC_NOAUDIT).
1062005d3febSMarek Pospisil */
1063005d3febSMarek Pospisil /* ARGSUSED */
1064005d3febSMarek Pospisil static int
setcond(caddr_t data)1065005d3febSMarek Pospisil setcond(caddr_t data)
1066005d3febSMarek Pospisil {
1067005d3febSMarek Pospisil int auditstate;
1068005d3febSMarek Pospisil au_kcontext_t *kctx;
1069005d3febSMarek Pospisil
1070005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
1071005d3febSMarek Pospisil return (EINVAL);
1072005d3febSMarek Pospisil
1073005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
1074005d3febSMarek Pospisil
1075005d3febSMarek Pospisil if (copyin(data, &auditstate, sizeof (int)))
1076005d3febSMarek Pospisil return (EFAULT);
1077005d3febSMarek Pospisil
1078005d3febSMarek Pospisil switch (auditstate) {
1079005d3febSMarek Pospisil case AUC_AUDITING: /* Turn auditing on */
1080005d3febSMarek Pospisil if (audit_active == C2AUDIT_UNLOADED)
1081005d3febSMarek Pospisil audit_init_module();
1082005d3febSMarek Pospisil kctx->auk_auditstate = AUC_AUDITING;
1083005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc))
1084005d3febSMarek Pospisil set_all_zone_usr_proc_sys(ALL_ZONES);
1085005d3febSMarek Pospisil else
1086005d3febSMarek Pospisil set_all_zone_usr_proc_sys(curproc->p_zone->zone_id);
1087005d3febSMarek Pospisil break;
1088005d3febSMarek Pospisil
1089005d3febSMarek Pospisil case AUC_NOAUDIT: /* Turn auditing off */
1090005d3febSMarek Pospisil if (kctx->auk_auditstate == AUC_NOAUDIT)
1091005d3febSMarek Pospisil break;
1092005d3febSMarek Pospisil kctx->auk_auditstate = AUC_NOAUDIT;
1093005d3febSMarek Pospisil
1094005d3febSMarek Pospisil /* clear out the audit queue */
1095005d3febSMarek Pospisil
1096005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock));
1097005d3febSMarek Pospisil if (kctx->auk_queue.wt_block)
1098005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv));
1099005d3febSMarek Pospisil
1100005d3febSMarek Pospisil /* unblock au_output_thread */
1101005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv));
1102005d3febSMarek Pospisil
1103005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock));
1104005d3febSMarek Pospisil break;
1105005d3febSMarek Pospisil
1106005d3febSMarek Pospisil default:
1107005d3febSMarek Pospisil return (EINVAL);
1108005d3febSMarek Pospisil }
1109005d3febSMarek Pospisil
1110005d3febSMarek Pospisil return (0);
1111005d3febSMarek Pospisil }
1112005d3febSMarek Pospisil
1113005d3febSMarek Pospisil static int
getclass(caddr_t data)1114005d3febSMarek Pospisil getclass(caddr_t data)
1115005d3febSMarek Pospisil {
1116005d3febSMarek Pospisil au_evclass_map_t event;
1117005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ;
1118005d3febSMarek Pospisil
1119005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t)))
1120005d3febSMarek Pospisil return (EFAULT);
1121005d3febSMarek Pospisil
1122005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS)
1123005d3febSMarek Pospisil return (EINVAL);
1124005d3febSMarek Pospisil
1125005d3febSMarek Pospisil event.ec_class = kctx->auk_ets[event.ec_number];
1126005d3febSMarek Pospisil
1127005d3febSMarek Pospisil if (copyout(&event, data, sizeof (au_evclass_map_t)))
1128005d3febSMarek Pospisil return (EFAULT);
1129005d3febSMarek Pospisil
1130005d3febSMarek Pospisil return (0);
1131005d3febSMarek Pospisil }
1132005d3febSMarek Pospisil
1133005d3febSMarek Pospisil static int
setclass(caddr_t data)1134005d3febSMarek Pospisil setclass(caddr_t data)
1135005d3febSMarek Pospisil {
1136005d3febSMarek Pospisil au_evclass_map_t event;
1137005d3febSMarek Pospisil au_kcontext_t *kctx;
1138005d3febSMarek Pospisil
1139005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1140005d3febSMarek Pospisil return (EINVAL);
1141005d3febSMarek Pospisil
1142005d3febSMarek Pospisil kctx = GET_KCTX_NGZ;
1143005d3febSMarek Pospisil
1144005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t)))
1145005d3febSMarek Pospisil return (EFAULT);
1146005d3febSMarek Pospisil
1147005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS)
1148005d3febSMarek Pospisil return (EINVAL);
1149005d3febSMarek Pospisil
1150005d3febSMarek Pospisil kctx->auk_ets[event.ec_number] = event.ec_class;
1151005d3febSMarek Pospisil
1152005d3febSMarek Pospisil return (0);
1153005d3febSMarek Pospisil }
1154005d3febSMarek Pospisil
1155005d3febSMarek Pospisil static int
getpinfo(caddr_t data)1156005d3febSMarek Pospisil getpinfo(caddr_t data)
1157005d3febSMarek Pospisil {
1158005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo);
1159005d3febSMarek Pospisil proc_t *proc;
1160005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
1161005d3febSMarek Pospisil model_t model;
1162005d3febSMarek Pospisil cred_t *cr, *newcred;
1163005d3febSMarek Pospisil
1164005d3febSMarek Pospisil model = get_udatamodel();
1165005d3febSMarek Pospisil STRUCT_INIT(apinfo, model);
1166005d3febSMarek Pospisil
1167005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1168005d3febSMarek Pospisil return (EFAULT);
1169005d3febSMarek Pospisil
1170005d3febSMarek Pospisil newcred = cralloc();
1171005d3febSMarek Pospisil
1172005d3febSMarek Pospisil mutex_enter(&pidlock);
1173005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1174005d3febSMarek Pospisil mutex_exit(&pidlock);
1175005d3febSMarek Pospisil crfree(newcred);
1176005d3febSMarek Pospisil return (ESRCH); /* no such process */
1177005d3febSMarek Pospisil }
1178005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */
1179005d3febSMarek Pospisil mutex_exit(&pidlock);
1180005d3febSMarek Pospisil
1181005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */
1182005d3febSMarek Pospisil
1183005d3febSMarek Pospisil mutex_enter(&proc->p_crlock);
1184005d3febSMarek Pospisil crhold(cr = proc->p_cred);
1185005d3febSMarek Pospisil mutex_exit(&proc->p_crlock);
1186005d3febSMarek Pospisil mutex_exit(&proc->p_lock);
1187005d3febSMarek Pospisil
1188005d3febSMarek Pospisil ainfo = crgetauinfo(cr);
1189005d3febSMarek Pospisil if (ainfo == NULL) {
1190005d3febSMarek Pospisil crfree(cr);
1191005d3febSMarek Pospisil return (EINVAL);
1192005d3febSMarek Pospisil }
1193005d3febSMarek Pospisil
1194005d3febSMarek Pospisil /* designated process has an ipv6 address? */
1195005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6) {
1196005d3febSMarek Pospisil crfree(cr);
1197005d3febSMarek Pospisil return (EOVERFLOW);
1198005d3febSMarek Pospisil }
1199005d3febSMarek Pospisil
1200005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1201005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1202005d3febSMarek Pospisil #ifdef _LP64
1203005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) {
1204005d3febSMarek Pospisil dev32_t dev;
1205005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */
1206005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1207005d3febSMarek Pospisil crfree(cr);
1208005d3febSMarek Pospisil return (EOVERFLOW);
1209005d3febSMarek Pospisil }
1210005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, dev);
1211005d3febSMarek Pospisil } else
1212005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1213005d3febSMarek Pospisil #else
1214005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1215005d3febSMarek Pospisil #endif
1216005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
1217005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1218005d3febSMarek Pospisil
1219005d3febSMarek Pospisil crfree(cr);
1220005d3febSMarek Pospisil
1221005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1222005d3febSMarek Pospisil return (EFAULT);
1223005d3febSMarek Pospisil
1224005d3febSMarek Pospisil return (0);
1225005d3febSMarek Pospisil }
1226005d3febSMarek Pospisil
1227005d3febSMarek Pospisil static int
getpinfo_addr(caddr_t data,int len)1228005d3febSMarek Pospisil getpinfo_addr(caddr_t data, int len)
1229005d3febSMarek Pospisil {
1230005d3febSMarek Pospisil STRUCT_DECL(auditpinfo_addr, apinfo);
1231005d3febSMarek Pospisil proc_t *proc;
1232005d3febSMarek Pospisil const auditinfo_addr_t *ainfo;
1233005d3febSMarek Pospisil model_t model;
1234005d3febSMarek Pospisil cred_t *cr, *newcred;
1235005d3febSMarek Pospisil
1236005d3febSMarek Pospisil model = get_udatamodel();
1237005d3febSMarek Pospisil STRUCT_INIT(apinfo, model);
1238005d3febSMarek Pospisil
1239005d3febSMarek Pospisil if (len < STRUCT_SIZE(apinfo))
1240005d3febSMarek Pospisil return (EOVERFLOW);
1241005d3febSMarek Pospisil
1242005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1243005d3febSMarek Pospisil return (EFAULT);
1244005d3febSMarek Pospisil
1245005d3febSMarek Pospisil newcred = cralloc();
1246005d3febSMarek Pospisil
1247005d3febSMarek Pospisil mutex_enter(&pidlock);
1248005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1249005d3febSMarek Pospisil mutex_exit(&pidlock);
1250005d3febSMarek Pospisil crfree(newcred);
1251005d3febSMarek Pospisil return (ESRCH);
1252005d3febSMarek Pospisil }
1253005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */
1254005d3febSMarek Pospisil mutex_exit(&pidlock);
1255005d3febSMarek Pospisil
1256005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */
1257005d3febSMarek Pospisil
1258005d3febSMarek Pospisil mutex_enter(&proc->p_crlock);
1259005d3febSMarek Pospisil crhold(cr = proc->p_cred);
1260005d3febSMarek Pospisil mutex_exit(&proc->p_crlock);
1261005d3febSMarek Pospisil mutex_exit(&proc->p_lock);
1262005d3febSMarek Pospisil
1263005d3febSMarek Pospisil ainfo = crgetauinfo(cr);
1264005d3febSMarek Pospisil if (ainfo == NULL) {
1265005d3febSMarek Pospisil crfree(cr);
1266005d3febSMarek Pospisil return (EINVAL);
1267005d3febSMarek Pospisil }
1268005d3febSMarek Pospisil
1269005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1270005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1271005d3febSMarek Pospisil #ifdef _LP64
1272005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) {
1273005d3febSMarek Pospisil dev32_t dev;
1274005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */
1275005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1276005d3febSMarek Pospisil crfree(cr);
1277005d3febSMarek Pospisil return (EOVERFLOW);
1278005d3febSMarek Pospisil }
1279005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, dev);
1280005d3febSMarek Pospisil } else
1281005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port,
1282005d3febSMarek Pospisil ainfo->ai_termid.at_port);
1283005d3febSMarek Pospisil #else
1284005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
1285005d3febSMarek Pospisil #endif
1286005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
1287005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
1288005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
1289005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
1290005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
1291005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1292005d3febSMarek Pospisil
1293005d3febSMarek Pospisil crfree(cr);
1294005d3febSMarek Pospisil
1295005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1296005d3febSMarek Pospisil return (EFAULT);
1297005d3febSMarek Pospisil
1298005d3febSMarek Pospisil return (0);
1299005d3febSMarek Pospisil }
1300005d3febSMarek Pospisil
1301005d3febSMarek Pospisil static int
setpmask(caddr_t data)1302005d3febSMarek Pospisil setpmask(caddr_t data)
1303005d3febSMarek Pospisil {
1304005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo);
1305005d3febSMarek Pospisil proc_t *proc;
1306005d3febSMarek Pospisil cred_t *newcred;
1307005d3febSMarek Pospisil auditinfo_addr_t *ainfo;
1308005d3febSMarek Pospisil struct p_audit_data *pad;
1309005d3febSMarek Pospisil
1310005d3febSMarek Pospisil model_t model;
1311005d3febSMarek Pospisil
1312005d3febSMarek Pospisil model = get_udatamodel();
1313005d3febSMarek Pospisil STRUCT_INIT(apinfo, model);
1314005d3febSMarek Pospisil
1315005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1316005d3febSMarek Pospisil return (EFAULT);
1317005d3febSMarek Pospisil
1318005d3febSMarek Pospisil mutex_enter(&pidlock);
1319005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1320005d3febSMarek Pospisil mutex_exit(&pidlock);
1321005d3febSMarek Pospisil return (ESRCH);
1322005d3febSMarek Pospisil }
1323005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */
1324005d3febSMarek Pospisil mutex_exit(&pidlock);
1325005d3febSMarek Pospisil
1326005d3febSMarek Pospisil newcred = cralloc();
1327005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
1328005d3febSMarek Pospisil mutex_exit(&proc->p_lock);
1329005d3febSMarek Pospisil crfree(newcred);
1330005d3febSMarek Pospisil return (EINVAL);
1331005d3febSMarek Pospisil }
1332005d3febSMarek Pospisil
1333005d3febSMarek Pospisil mutex_enter(&proc->p_crlock);
1334005d3febSMarek Pospisil crcopy_to(proc->p_cred, newcred);
1335005d3febSMarek Pospisil proc->p_cred = newcred;
1336005d3febSMarek Pospisil
1337005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
1338005d3febSMarek Pospisil
1339005d3febSMarek Pospisil /*
1340005d3febSMarek Pospisil * Unlock. No need to broadcast changes via set_proc_pre_sys(),
1341005d3febSMarek Pospisil * since t_pre_sys is ALWAYS on when audit is enabled... due to
1342005d3febSMarek Pospisil * syscall auditing.
1343005d3febSMarek Pospisil */
1344005d3febSMarek Pospisil crfree(newcred);
1345005d3febSMarek Pospisil mutex_exit(&proc->p_crlock);
1346005d3febSMarek Pospisil
1347005d3febSMarek Pospisil /* Reset flag for any previous pending mask change; this supercedes */
1348005d3febSMarek Pospisil pad = P2A(proc);
1349005d3febSMarek Pospisil ASSERT(pad != NULL);
1350005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock));
1351005d3febSMarek Pospisil pad->pad_flags &= ~PAD_SETMASK;
1352005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock));
1353005d3febSMarek Pospisil
1354005d3febSMarek Pospisil mutex_exit(&proc->p_lock);
1355005d3febSMarek Pospisil
1356005d3febSMarek Pospisil return (0);
1357005d3febSMarek Pospisil }
1358005d3febSMarek Pospisil
1359005d3febSMarek Pospisil /*
1360005d3febSMarek Pospisil * The out of control system call
1361005d3febSMarek Pospisil * This is audit kitchen sink aka auditadm, aka auditon
1362005d3febSMarek Pospisil */
1363005d3febSMarek Pospisil int
auditctl(int cmd,caddr_t data,int length)1364005d3febSMarek Pospisil auditctl(
1365005d3febSMarek Pospisil int cmd,
1366005d3febSMarek Pospisil caddr_t data,
1367005d3febSMarek Pospisil int length)
1368005d3febSMarek Pospisil {
1369005d3febSMarek Pospisil int result;
1370005d3febSMarek Pospisil
1371005d3febSMarek Pospisil switch (cmd) {
1372f8994074SJan Friedel case A_GETAMASK:
1373005d3febSMarek Pospisil case A_GETCOND:
1374005d3febSMarek Pospisil case A_GETCAR:
1375005d3febSMarek Pospisil case A_GETCLASS:
1376005d3febSMarek Pospisil case A_GETCWD:
1377005d3febSMarek Pospisil case A_GETKAUDIT:
1378005d3febSMarek Pospisil case A_GETKMASK:
1379005d3febSMarek Pospisil case A_GETPINFO:
1380005d3febSMarek Pospisil case A_GETPINFO_ADDR:
1381005d3febSMarek Pospisil case A_GETPOLICY:
1382005d3febSMarek Pospisil case A_GETQCTRL:
1383005d3febSMarek Pospisil case A_GETSTAT:
1384134a1f4eSCasper H.S. Dik if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
1385005d3febSMarek Pospisil return (EPERM);
1386005d3febSMarek Pospisil break;
1387005d3febSMarek Pospisil default:
1388005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0)
1389005d3febSMarek Pospisil return (EPERM);
1390005d3febSMarek Pospisil break;
1391005d3febSMarek Pospisil }
1392005d3febSMarek Pospisil
1393005d3febSMarek Pospisil switch (cmd) {
1394005d3febSMarek Pospisil case A_GETPOLICY:
1395005d3febSMarek Pospisil result = getpolicy(data);
1396005d3febSMarek Pospisil break;
1397005d3febSMarek Pospisil case A_SETPOLICY:
1398005d3febSMarek Pospisil result = setpolicy(data);
1399005d3febSMarek Pospisil break;
1400f8994074SJan Friedel case A_GETAMASK:
1401f8994074SJan Friedel result = getamask(data);
1402f8994074SJan Friedel break;
1403f8994074SJan Friedel case A_SETAMASK:
1404f8994074SJan Friedel result = setamask(data);
1405f8994074SJan Friedel break;
1406005d3febSMarek Pospisil case A_GETKMASK:
1407005d3febSMarek Pospisil result = getkmask(data);
1408005d3febSMarek Pospisil break;
1409005d3febSMarek Pospisil case A_SETKMASK:
1410005d3febSMarek Pospisil result = setkmask(data);
1411005d3febSMarek Pospisil break;
1412005d3febSMarek Pospisil case A_GETKAUDIT:
1413005d3febSMarek Pospisil result = getkaudit(data, length);
1414005d3febSMarek Pospisil break;
1415005d3febSMarek Pospisil case A_SETKAUDIT:
1416005d3febSMarek Pospisil result = setkaudit(data, length);
1417005d3febSMarek Pospisil break;
1418005d3febSMarek Pospisil case A_GETQCTRL:
1419005d3febSMarek Pospisil result = getqctrl(data);
1420005d3febSMarek Pospisil break;
1421005d3febSMarek Pospisil case A_SETQCTRL:
1422005d3febSMarek Pospisil result = setqctrl(data);
1423005d3febSMarek Pospisil break;
1424005d3febSMarek Pospisil case A_GETCWD:
1425005d3febSMarek Pospisil result = getcwd(data, length);
1426005d3febSMarek Pospisil break;
1427005d3febSMarek Pospisil case A_GETCAR:
1428005d3febSMarek Pospisil result = getcar(data, length);
1429005d3febSMarek Pospisil break;
1430005d3febSMarek Pospisil case A_GETSTAT:
1431005d3febSMarek Pospisil result = getstat(data);
1432005d3febSMarek Pospisil break;
1433005d3febSMarek Pospisil case A_SETSTAT:
1434005d3febSMarek Pospisil result = setstat(data);
1435005d3febSMarek Pospisil break;
1436005d3febSMarek Pospisil case A_SETUMASK:
1437005d3febSMarek Pospisil result = setumask(data);
1438005d3febSMarek Pospisil break;
1439005d3febSMarek Pospisil case A_SETSMASK:
1440005d3febSMarek Pospisil result = setsmask(data);
1441005d3febSMarek Pospisil break;
1442005d3febSMarek Pospisil case A_GETCOND:
1443005d3febSMarek Pospisil result = getcond(data);
1444005d3febSMarek Pospisil break;
1445005d3febSMarek Pospisil case A_SETCOND:
1446005d3febSMarek Pospisil result = setcond(data);
1447005d3febSMarek Pospisil break;
1448005d3febSMarek Pospisil case A_GETCLASS:
1449005d3febSMarek Pospisil result = getclass(data);
1450005d3febSMarek Pospisil break;
1451005d3febSMarek Pospisil case A_SETCLASS:
1452005d3febSMarek Pospisil result = setclass(data);
1453005d3febSMarek Pospisil break;
1454005d3febSMarek Pospisil case A_GETPINFO:
1455005d3febSMarek Pospisil result = getpinfo(data);
1456005d3febSMarek Pospisil break;
1457005d3febSMarek Pospisil case A_GETPINFO_ADDR:
1458005d3febSMarek Pospisil result = getpinfo_addr(data, length);
1459005d3febSMarek Pospisil break;
1460005d3febSMarek Pospisil case A_SETPMASK:
1461005d3febSMarek Pospisil result = setpmask(data);
1462005d3febSMarek Pospisil break;
1463005d3febSMarek Pospisil default:
1464005d3febSMarek Pospisil result = EINVAL;
1465005d3febSMarek Pospisil break;
1466005d3febSMarek Pospisil }
1467005d3febSMarek Pospisil return (result);
14687c478bd9Sstevel@tonic-gate }
1469