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