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