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 /* 22*134a1f4eSCasper 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 108*134a1f4eSCasper 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 173*134a1f4eSCasper 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 222*134a1f4eSCasper 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 491005d3febSMarek Pospisil getkmask(caddr_t data) 492005d3febSMarek Pospisil { 493005d3febSMarek Pospisil au_kcontext_t *kctx; 494005d3febSMarek Pospisil 495005d3febSMarek Pospisil kctx = GET_KCTX_PZ; 496005d3febSMarek Pospisil 497005d3febSMarek Pospisil if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t))) 498005d3febSMarek Pospisil return (EFAULT); 499005d3febSMarek Pospisil return (0); 500005d3febSMarek Pospisil } 501005d3febSMarek Pospisil 502005d3febSMarek Pospisil static int 503005d3febSMarek Pospisil setkmask(caddr_t data) 504005d3febSMarek Pospisil { 505005d3febSMarek Pospisil au_mask_t mask; 506005d3febSMarek Pospisil au_kcontext_t *kctx; 507005d3febSMarek Pospisil 508005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 509005d3febSMarek Pospisil return (EINVAL); 510005d3febSMarek Pospisil 511005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 512005d3febSMarek Pospisil 513005d3febSMarek Pospisil if (copyin(data, &mask, sizeof (au_mask_t))) 514005d3febSMarek Pospisil return (EFAULT); 515005d3febSMarek Pospisil 516005d3febSMarek Pospisil kctx->auk_info.ai_mask = mask; 517005d3febSMarek Pospisil return (0); 518005d3febSMarek Pospisil } 519005d3febSMarek Pospisil 520005d3febSMarek Pospisil static int 521005d3febSMarek Pospisil getkaudit(caddr_t info_p, int len) 522005d3febSMarek Pospisil { 523005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 524005d3febSMarek Pospisil model_t model; 525005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 526005d3febSMarek Pospisil 527005d3febSMarek Pospisil model = get_udatamodel(); 528005d3febSMarek Pospisil STRUCT_INIT(info, model); 529005d3febSMarek Pospisil 530005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 531005d3febSMarek Pospisil return (EOVERFLOW); 532005d3febSMarek Pospisil 533005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid); 534005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask); 535005d3febSMarek Pospisil #ifdef _LP64 536005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 537005d3febSMarek Pospisil dev32_t dev; 538005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 539005d3febSMarek Pospisil if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) { 540005d3febSMarek Pospisil return (EOVERFLOW); 541005d3febSMarek Pospisil } 542005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, dev); 543005d3febSMarek Pospisil } else { 544005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, 545005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port); 546005d3febSMarek Pospisil } 547005d3febSMarek Pospisil #else 548005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, 549005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port); 550005d3febSMarek Pospisil #endif 551005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_type, 552005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type); 553005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[0], 554005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0]); 555005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[1], 556005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1]); 557005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[2], 558005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2]); 559005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[3], 560005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3]); 561005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid); 562005d3febSMarek Pospisil 563005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info))) 564005d3febSMarek Pospisil return (EFAULT); 565005d3febSMarek Pospisil 566005d3febSMarek Pospisil return (0); 567005d3febSMarek Pospisil } 568005d3febSMarek Pospisil 569005d3febSMarek Pospisil /* 570005d3febSMarek Pospisil * the host address for AUDIT_PERZONE == 0 is that of the global 571005d3febSMarek Pospisil * zone and for local zones it is of the current zone. 572005d3febSMarek Pospisil */ 573005d3febSMarek Pospisil static int 574005d3febSMarek Pospisil setkaudit(caddr_t info_p, int len) 575005d3febSMarek Pospisil { 576005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 577005d3febSMarek Pospisil model_t model; 578005d3febSMarek Pospisil au_kcontext_t *kctx; 579005d3febSMarek Pospisil 580005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 581005d3febSMarek Pospisil return (EINVAL); 582005d3febSMarek Pospisil 583005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 584005d3febSMarek Pospisil 585005d3febSMarek Pospisil model = get_udatamodel(); 586005d3febSMarek Pospisil STRUCT_INIT(info, model); 587005d3febSMarek Pospisil 588005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 589005d3febSMarek Pospisil return (EOVERFLOW); 590005d3febSMarek Pospisil 591005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) 592005d3febSMarek Pospisil return (EFAULT); 593005d3febSMarek Pospisil 594005d3febSMarek Pospisil if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) && 595005d3febSMarek Pospisil (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6)) 596005d3febSMarek Pospisil return (EINVAL); 597005d3febSMarek Pospisil 598005d3febSMarek Pospisil /* Set audit mask, termid and session id as specified */ 599005d3febSMarek Pospisil kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid); 600005d3febSMarek Pospisil kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask); 601005d3febSMarek Pospisil #ifdef _LP64 602005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */ 603005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) 604005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = 605005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.at_port)); 606005d3febSMarek Pospisil else 607005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = 608005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_port); 609005d3febSMarek Pospisil #else 610005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); 611005d3febSMarek Pospisil #endif 612005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type); 613005d3febSMarek Pospisil bzero(&kctx->auk_info.ai_termid.at_addr[0], 614005d3febSMarek Pospisil sizeof (kctx->auk_info.ai_termid.at_addr)); 615005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] = 616005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[0]); 617005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] = 618005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[1]); 619005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] = 620005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[2]); 621005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] = 622005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[3]); 623005d3febSMarek Pospisil kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid); 624005d3febSMarek Pospisil 625005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6 && 626005d3febSMarek Pospisil IN6_IS_ADDR_V4MAPPED( 627005d3febSMarek Pospisil ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) { 628005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = AU_IPv4; 629005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] = 630005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3]; 631005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] = 0; 632005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] = 0; 633005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] = 0; 634005d3febSMarek Pospisil } 635005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6) 636005d3febSMarek Pospisil kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED( 637005d3febSMarek Pospisil (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1; 638005d3febSMarek Pospisil else 639005d3febSMarek Pospisil kctx->auk_hostaddr_valid = 640005d3febSMarek Pospisil (kctx->auk_info.ai_termid.at_addr[0] == 641005d3febSMarek Pospisil htonl(INADDR_ANY)) ? 0 : 1; 642005d3febSMarek Pospisil 643005d3febSMarek Pospisil return (0); 644005d3febSMarek Pospisil } 645005d3febSMarek Pospisil 646005d3febSMarek Pospisil static int 647005d3febSMarek Pospisil getqctrl(caddr_t data) 648005d3febSMarek Pospisil { 649005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 650005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl); 651005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel()); 652005d3febSMarek Pospisil 653005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 654005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater); 655005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater); 656005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz); 657005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay); 658005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 659005d3febSMarek Pospisil 660005d3febSMarek Pospisil if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl))) 661005d3febSMarek Pospisil return (EFAULT); 662005d3febSMarek Pospisil 663005d3febSMarek Pospisil return (0); 664005d3febSMarek Pospisil } 665005d3febSMarek Pospisil 666005d3febSMarek Pospisil static int 667005d3febSMarek Pospisil setqctrl(caddr_t data) 668005d3febSMarek Pospisil { 669005d3febSMarek Pospisil au_kcontext_t *kctx; 670005d3febSMarek Pospisil struct au_qctrl qctrl_tmp; 671005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl); 672005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel()); 673005d3febSMarek Pospisil 674005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 675005d3febSMarek Pospisil return (EINVAL); 676005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 677005d3febSMarek Pospisil 678005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl))) 679005d3febSMarek Pospisil return (EFAULT); 680005d3febSMarek Pospisil 681005d3febSMarek Pospisil qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater); 682005d3febSMarek Pospisil qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater); 683005d3febSMarek Pospisil qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz); 684005d3febSMarek Pospisil qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay); 685005d3febSMarek Pospisil 686005d3febSMarek Pospisil /* enforce sane values */ 687005d3febSMarek Pospisil 688005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater) 689005d3febSMarek Pospisil return (EINVAL); 690005d3febSMarek Pospisil 691005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater < AQ_LOWATER) 692005d3febSMarek Pospisil return (EINVAL); 693005d3febSMarek Pospisil 694005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH) 695005d3febSMarek Pospisil return (EINVAL); 696005d3febSMarek Pospisil 697005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz < AQ_BUFSZ) 698005d3febSMarek Pospisil return (EINVAL); 699005d3febSMarek Pospisil 700005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ) 701005d3febSMarek Pospisil return (EINVAL); 702005d3febSMarek Pospisil 703005d3febSMarek Pospisil if (qctrl_tmp.aq_delay == 0) 704005d3febSMarek Pospisil return (EINVAL); 705005d3febSMarek Pospisil 706005d3febSMarek Pospisil if (qctrl_tmp.aq_delay > AQ_MAXDELAY) 707005d3febSMarek Pospisil return (EINVAL); 708005d3febSMarek Pospisil 709005d3febSMarek Pospisil /* update everything at once so things are consistant */ 710005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 711005d3febSMarek Pospisil kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater; 712005d3febSMarek Pospisil kctx->auk_queue.lowater = qctrl_tmp.aq_lowater; 713005d3febSMarek Pospisil kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz; 714005d3febSMarek Pospisil kctx->auk_queue.delay = qctrl_tmp.aq_delay; 715005d3febSMarek Pospisil 716005d3febSMarek Pospisil if (kctx->auk_queue.rd_block && 717005d3febSMarek Pospisil kctx->auk_queue.cnt > kctx->auk_queue.lowater) 718005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv)); 719005d3febSMarek Pospisil 720005d3febSMarek Pospisil if (kctx->auk_queue.wt_block && 721005d3febSMarek Pospisil kctx->auk_queue.cnt < kctx->auk_queue.hiwater) 722005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv)); 723005d3febSMarek Pospisil 724005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 725005d3febSMarek Pospisil 726005d3febSMarek Pospisil return (0); 727005d3febSMarek Pospisil } 728005d3febSMarek Pospisil 729005d3febSMarek Pospisil static int 730005d3febSMarek Pospisil getcwd(caddr_t data, int length) 731005d3febSMarek Pospisil { 732005d3febSMarek Pospisil struct p_audit_data *pad; 733005d3febSMarek Pospisil struct audit_path *app; 734005d3febSMarek Pospisil int pathlen; 735005d3febSMarek Pospisil 736005d3febSMarek Pospisil pad = P2A(curproc); 737005d3febSMarek Pospisil ASSERT(pad != NULL); 738005d3febSMarek Pospisil 739005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 740005d3febSMarek Pospisil app = pad->pad_cwd; 741005d3febSMarek Pospisil au_pathhold(app); 742005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 743005d3febSMarek Pospisil 744005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0]; 745005d3febSMarek Pospisil if (pathlen > length) { 746005d3febSMarek Pospisil au_pathrele(app); 747005d3febSMarek Pospisil return (E2BIG); 748005d3febSMarek Pospisil } 749005d3febSMarek Pospisil 750005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) { 751005d3febSMarek Pospisil au_pathrele(app); 752005d3febSMarek Pospisil return (EFAULT); 753005d3febSMarek Pospisil } 754005d3febSMarek Pospisil 755005d3febSMarek Pospisil au_pathrele(app); 756005d3febSMarek Pospisil return (0); 757005d3febSMarek Pospisil } 758005d3febSMarek Pospisil 759005d3febSMarek Pospisil static int 760005d3febSMarek Pospisil getcar(caddr_t data, int length) 761005d3febSMarek Pospisil { 762005d3febSMarek Pospisil struct p_audit_data *pad; 763005d3febSMarek Pospisil struct audit_path *app; 764005d3febSMarek Pospisil int pathlen; 765005d3febSMarek Pospisil 766005d3febSMarek Pospisil pad = P2A(curproc); 767005d3febSMarek Pospisil ASSERT(pad != NULL); 768005d3febSMarek Pospisil 769005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 770005d3febSMarek Pospisil app = pad->pad_root; 771005d3febSMarek Pospisil au_pathhold(app); 772005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 773005d3febSMarek Pospisil 774005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0]; 775005d3febSMarek Pospisil if (pathlen > length) { 776005d3febSMarek Pospisil au_pathrele(app); 777005d3febSMarek Pospisil return (E2BIG); 778005d3febSMarek Pospisil } 779005d3febSMarek Pospisil 780005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) { 781005d3febSMarek Pospisil au_pathrele(app); 782005d3febSMarek Pospisil return (EFAULT); 783005d3febSMarek Pospisil } 784005d3febSMarek Pospisil 785005d3febSMarek Pospisil au_pathrele(app); 786005d3febSMarek Pospisil return (0); 787005d3febSMarek Pospisil } 788005d3febSMarek Pospisil 789005d3febSMarek Pospisil static int 790005d3febSMarek Pospisil getstat(caddr_t data) 791005d3febSMarek Pospisil { 792005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 793005d3febSMarek Pospisil 794005d3febSMarek Pospisil membar_consumer(); 795005d3febSMarek Pospisil 796005d3febSMarek Pospisil if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t))) 797005d3febSMarek Pospisil return (EFAULT); 798005d3febSMarek Pospisil return (0); 799005d3febSMarek Pospisil } 800005d3febSMarek Pospisil 801005d3febSMarek Pospisil static int 802005d3febSMarek Pospisil setstat(caddr_t data) 803005d3febSMarek Pospisil { 804005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 805005d3febSMarek Pospisil au_stat_t au_stat; 806005d3febSMarek Pospisil 807005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 808005d3febSMarek Pospisil return (EINVAL); 809005d3febSMarek Pospisil 810005d3febSMarek Pospisil if (copyin(data, &au_stat, sizeof (au_stat_t))) 811005d3febSMarek Pospisil return (EFAULT); 812005d3febSMarek Pospisil 813005d3febSMarek Pospisil if (au_stat.as_generated == CLEAR_VAL) 814005d3febSMarek Pospisil kctx->auk_statistics.as_generated = 0; 815005d3febSMarek Pospisil if (au_stat.as_nonattrib == CLEAR_VAL) 816005d3febSMarek Pospisil kctx->auk_statistics.as_nonattrib = 0; 817005d3febSMarek Pospisil if (au_stat.as_kernel == CLEAR_VAL) 818005d3febSMarek Pospisil kctx->auk_statistics.as_kernel = 0; 819005d3febSMarek Pospisil if (au_stat.as_audit == CLEAR_VAL) 820005d3febSMarek Pospisil kctx->auk_statistics.as_audit = 0; 821005d3febSMarek Pospisil if (au_stat.as_auditctl == CLEAR_VAL) 822005d3febSMarek Pospisil kctx->auk_statistics.as_auditctl = 0; 823005d3febSMarek Pospisil if (au_stat.as_enqueue == CLEAR_VAL) 824005d3febSMarek Pospisil kctx->auk_statistics.as_enqueue = 0; 825005d3febSMarek Pospisil if (au_stat.as_written == CLEAR_VAL) 826005d3febSMarek Pospisil kctx->auk_statistics.as_written = 0; 827005d3febSMarek Pospisil if (au_stat.as_wblocked == CLEAR_VAL) 828005d3febSMarek Pospisil kctx->auk_statistics.as_wblocked = 0; 829005d3febSMarek Pospisil if (au_stat.as_rblocked == CLEAR_VAL) 830005d3febSMarek Pospisil kctx->auk_statistics.as_rblocked = 0; 831005d3febSMarek Pospisil if (au_stat.as_dropped == CLEAR_VAL) 832005d3febSMarek Pospisil kctx->auk_statistics.as_dropped = 0; 833005d3febSMarek Pospisil if (au_stat.as_totalsize == CLEAR_VAL) 834005d3febSMarek Pospisil kctx->auk_statistics.as_totalsize = 0; 835005d3febSMarek Pospisil 836005d3febSMarek Pospisil membar_producer(); 837005d3febSMarek Pospisil 838005d3febSMarek Pospisil return (0); 839005d3febSMarek Pospisil 840005d3febSMarek Pospisil } 841005d3febSMarek Pospisil 842005d3febSMarek Pospisil static int 843005d3febSMarek Pospisil setumask(caddr_t data) 844005d3febSMarek Pospisil { 845005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info); 846005d3febSMarek Pospisil struct proc *p; 847005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 848005d3febSMarek Pospisil model_t model; 849005d3febSMarek Pospisil 850005d3febSMarek Pospisil /* setumask not applicable in non-global zones without perzone policy */ 851005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 852005d3febSMarek Pospisil return (EINVAL); 853005d3febSMarek Pospisil 854005d3febSMarek Pospisil model = get_udatamodel(); 855005d3febSMarek Pospisil STRUCT_INIT(user_info, model); 856005d3febSMarek Pospisil 857005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info))) 858005d3febSMarek Pospisil return (EFAULT); 859005d3febSMarek Pospisil 860005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */ 861005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) { 862005d3febSMarek Pospisil cred_t *cr; 863005d3febSMarek Pospisil 864005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */ 865005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id)) 866005d3febSMarek Pospisil continue; 867005d3febSMarek Pospisil 868005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */ 869005d3febSMarek Pospisil 870005d3febSMarek Pospisil /* skip system processes and ones being created or going away */ 871005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB || 872005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) { 873005d3febSMarek Pospisil mutex_exit(&p->p_lock); 874005d3febSMarek Pospisil continue; 875005d3febSMarek Pospisil } 876005d3febSMarek Pospisil 877005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 878005d3febSMarek Pospisil crhold(cr = p->p_cred); 879005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 880005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 881005d3febSMarek Pospisil if (ainfo == NULL) { 882005d3febSMarek Pospisil mutex_exit(&p->p_lock); 883005d3febSMarek Pospisil crfree(cr); 884005d3febSMarek Pospisil continue; 885005d3febSMarek Pospisil } 886005d3febSMarek Pospisil 887005d3febSMarek Pospisil if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) { 888005d3febSMarek Pospisil au_mask_t mask; 889005d3febSMarek Pospisil int err; 890005d3febSMarek Pospisil 891005d3febSMarek Pospisil /* 892005d3febSMarek Pospisil * Here's a process which matches the specified auid. 893005d3febSMarek Pospisil * If its mask doesn't already match the new mask, 894005d3febSMarek Pospisil * save the new mask in the pad, to be picked up 895005d3febSMarek Pospisil * next syscall. 896005d3febSMarek Pospisil */ 897005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask); 898005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t)); 899005d3febSMarek Pospisil crfree(cr); 900005d3febSMarek Pospisil if (err != 0) { 901005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p); 902005d3febSMarek Pospisil ASSERT(pad != NULL); 903005d3febSMarek Pospisil 904005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 905005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK; 906005d3febSMarek Pospisil pad->pad_newmask = mask; 907005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 908005d3febSMarek Pospisil 909005d3febSMarek Pospisil /* 910005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since 911005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is 912005d3febSMarek Pospisil * enabled...due to syscall auditing. 913005d3febSMarek Pospisil */ 914005d3febSMarek Pospisil } 915005d3febSMarek Pospisil } else { 916005d3febSMarek Pospisil crfree(cr); 917005d3febSMarek Pospisil } 918005d3febSMarek Pospisil mutex_exit(&p->p_lock); 919005d3febSMarek Pospisil } 920005d3febSMarek Pospisil mutex_exit(&pidlock); 921005d3febSMarek Pospisil 922005d3febSMarek Pospisil return (0); 923005d3febSMarek Pospisil } 924005d3febSMarek Pospisil 925005d3febSMarek Pospisil static int 926005d3febSMarek Pospisil setsmask(caddr_t data) 927005d3febSMarek Pospisil { 928005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info); 929005d3febSMarek Pospisil struct proc *p; 930005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 931005d3febSMarek Pospisil model_t model; 932005d3febSMarek Pospisil 933005d3febSMarek Pospisil /* setsmask not applicable in non-global zones without perzone policy */ 934005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 935005d3febSMarek Pospisil return (EINVAL); 936005d3febSMarek Pospisil 937005d3febSMarek Pospisil model = get_udatamodel(); 938005d3febSMarek Pospisil STRUCT_INIT(user_info, model); 939005d3febSMarek Pospisil 940005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info))) 941005d3febSMarek Pospisil return (EFAULT); 942005d3febSMarek Pospisil 943005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */ 944005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) { 945005d3febSMarek Pospisil cred_t *cr; 946005d3febSMarek Pospisil 947005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */ 948005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id)) 949005d3febSMarek Pospisil continue; 950005d3febSMarek Pospisil 951005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */ 952005d3febSMarek Pospisil 953005d3febSMarek Pospisil /* skip system processes and ones being created or going away */ 954005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB || 955005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) { 956005d3febSMarek Pospisil mutex_exit(&p->p_lock); 957005d3febSMarek Pospisil continue; 958005d3febSMarek Pospisil } 959005d3febSMarek Pospisil 960005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 961005d3febSMarek Pospisil crhold(cr = p->p_cred); 962005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 963005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 964005d3febSMarek Pospisil if (ainfo == NULL) { 965005d3febSMarek Pospisil mutex_exit(&p->p_lock); 966005d3febSMarek Pospisil crfree(cr); 967005d3febSMarek Pospisil continue; 968005d3febSMarek Pospisil } 969005d3febSMarek Pospisil 970005d3febSMarek Pospisil if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) { 971005d3febSMarek Pospisil au_mask_t mask; 972005d3febSMarek Pospisil int err; 973005d3febSMarek Pospisil 974005d3febSMarek Pospisil /* 975005d3febSMarek Pospisil * Here's a process which matches the specified asid. 976005d3febSMarek Pospisil * If its mask doesn't already match the new mask, 977005d3febSMarek Pospisil * save the new mask in the pad, to be picked up 978005d3febSMarek Pospisil * next syscall. 979005d3febSMarek Pospisil */ 980005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask); 981005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t)); 982005d3febSMarek Pospisil crfree(cr); 983005d3febSMarek Pospisil if (err != 0) { 984005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p); 985005d3febSMarek Pospisil ASSERT(pad != NULL); 986005d3febSMarek Pospisil 987005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 988005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK; 989005d3febSMarek Pospisil pad->pad_newmask = mask; 990005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 991005d3febSMarek Pospisil 992005d3febSMarek Pospisil /* 993005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since 994005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is 995005d3febSMarek Pospisil * enabled...due to syscall auditing. 996005d3febSMarek Pospisil */ 997005d3febSMarek Pospisil } 998005d3febSMarek Pospisil } else { 999005d3febSMarek Pospisil crfree(cr); 1000005d3febSMarek Pospisil } 1001005d3febSMarek Pospisil mutex_exit(&p->p_lock); 1002005d3febSMarek Pospisil } 1003005d3febSMarek Pospisil mutex_exit(&pidlock); 1004005d3febSMarek Pospisil 1005005d3febSMarek Pospisil return (0); 1006005d3febSMarek Pospisil } 1007005d3febSMarek Pospisil 1008005d3febSMarek Pospisil /* 1009005d3febSMarek Pospisil * Get the current audit state of the system 1010005d3febSMarek Pospisil */ 1011005d3febSMarek Pospisil static int 1012005d3febSMarek Pospisil getcond(caddr_t data) 1013005d3febSMarek Pospisil { 1014005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 1015005d3febSMarek Pospisil 1016005d3febSMarek Pospisil if (copyout(&(kctx->auk_auditstate), data, sizeof (int))) 1017005d3febSMarek Pospisil return (EFAULT); 1018005d3febSMarek Pospisil 1019005d3febSMarek Pospisil return (0); 1020005d3febSMarek Pospisil } 1021005d3febSMarek Pospisil 1022005d3febSMarek Pospisil /* 1023005d3febSMarek Pospisil * Set the current audit state of the system to on (AUC_AUDITING) or 1024005d3febSMarek Pospisil * off (AUC_NOAUDIT). 1025005d3febSMarek Pospisil */ 1026005d3febSMarek Pospisil /* ARGSUSED */ 1027005d3febSMarek Pospisil static int 1028005d3febSMarek Pospisil setcond(caddr_t data) 1029005d3febSMarek Pospisil { 1030005d3febSMarek Pospisil int auditstate; 1031005d3febSMarek Pospisil au_kcontext_t *kctx; 1032005d3febSMarek Pospisil 1033005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 1034005d3febSMarek Pospisil return (EINVAL); 1035005d3febSMarek Pospisil 1036005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 1037005d3febSMarek Pospisil 1038005d3febSMarek Pospisil if (copyin(data, &auditstate, sizeof (int))) 1039005d3febSMarek Pospisil return (EFAULT); 1040005d3febSMarek Pospisil 1041005d3febSMarek Pospisil switch (auditstate) { 1042005d3febSMarek Pospisil case AUC_AUDITING: /* Turn auditing on */ 1043005d3febSMarek Pospisil if (audit_active == C2AUDIT_UNLOADED) 1044005d3febSMarek Pospisil audit_init_module(); 1045005d3febSMarek Pospisil kctx->auk_auditstate = AUC_AUDITING; 1046005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc)) 1047005d3febSMarek Pospisil set_all_zone_usr_proc_sys(ALL_ZONES); 1048005d3febSMarek Pospisil else 1049005d3febSMarek Pospisil set_all_zone_usr_proc_sys(curproc->p_zone->zone_id); 1050005d3febSMarek Pospisil break; 1051005d3febSMarek Pospisil 1052005d3febSMarek Pospisil case AUC_NOAUDIT: /* Turn auditing off */ 1053005d3febSMarek Pospisil if (kctx->auk_auditstate == AUC_NOAUDIT) 1054005d3febSMarek Pospisil break; 1055005d3febSMarek Pospisil kctx->auk_auditstate = AUC_NOAUDIT; 1056005d3febSMarek Pospisil 1057005d3febSMarek Pospisil /* clear out the audit queue */ 1058005d3febSMarek Pospisil 1059005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 1060005d3febSMarek Pospisil if (kctx->auk_queue.wt_block) 1061005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv)); 1062005d3febSMarek Pospisil 1063005d3febSMarek Pospisil /* unblock au_output_thread */ 1064005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv)); 1065005d3febSMarek Pospisil 1066005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 1067005d3febSMarek Pospisil break; 1068005d3febSMarek Pospisil 1069005d3febSMarek Pospisil default: 1070005d3febSMarek Pospisil return (EINVAL); 1071005d3febSMarek Pospisil } 1072005d3febSMarek Pospisil 1073005d3febSMarek Pospisil return (0); 1074005d3febSMarek Pospisil } 1075005d3febSMarek Pospisil 1076005d3febSMarek Pospisil static int 1077005d3febSMarek Pospisil getclass(caddr_t data) 1078005d3febSMarek Pospisil { 1079005d3febSMarek Pospisil au_evclass_map_t event; 1080005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 1081005d3febSMarek Pospisil 1082005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t))) 1083005d3febSMarek Pospisil return (EFAULT); 1084005d3febSMarek Pospisil 1085005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS) 1086005d3febSMarek Pospisil return (EINVAL); 1087005d3febSMarek Pospisil 1088005d3febSMarek Pospisil event.ec_class = kctx->auk_ets[event.ec_number]; 1089005d3febSMarek Pospisil 1090005d3febSMarek Pospisil if (copyout(&event, data, sizeof (au_evclass_map_t))) 1091005d3febSMarek Pospisil return (EFAULT); 1092005d3febSMarek Pospisil 1093005d3febSMarek Pospisil return (0); 1094005d3febSMarek Pospisil } 1095005d3febSMarek Pospisil 1096005d3febSMarek Pospisil static int 1097005d3febSMarek Pospisil setclass(caddr_t data) 1098005d3febSMarek Pospisil { 1099005d3febSMarek Pospisil au_evclass_map_t event; 1100005d3febSMarek Pospisil au_kcontext_t *kctx; 1101005d3febSMarek Pospisil 1102005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 1103005d3febSMarek Pospisil return (EINVAL); 1104005d3febSMarek Pospisil 1105005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 1106005d3febSMarek Pospisil 1107005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t))) 1108005d3febSMarek Pospisil return (EFAULT); 1109005d3febSMarek Pospisil 1110005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS) 1111005d3febSMarek Pospisil return (EINVAL); 1112005d3febSMarek Pospisil 1113005d3febSMarek Pospisil kctx->auk_ets[event.ec_number] = event.ec_class; 1114005d3febSMarek Pospisil 1115005d3febSMarek Pospisil return (0); 1116005d3febSMarek Pospisil } 1117005d3febSMarek Pospisil 1118005d3febSMarek Pospisil static int 1119005d3febSMarek Pospisil getpinfo(caddr_t data) 1120005d3febSMarek Pospisil { 1121005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo); 1122005d3febSMarek Pospisil proc_t *proc; 1123005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 1124005d3febSMarek Pospisil model_t model; 1125005d3febSMarek Pospisil cred_t *cr, *newcred; 1126005d3febSMarek Pospisil 1127005d3febSMarek Pospisil model = get_udatamodel(); 1128005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1129005d3febSMarek Pospisil 1130005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1131005d3febSMarek Pospisil return (EFAULT); 1132005d3febSMarek Pospisil 1133005d3febSMarek Pospisil newcred = cralloc(); 1134005d3febSMarek Pospisil 1135005d3febSMarek Pospisil mutex_enter(&pidlock); 1136005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1137005d3febSMarek Pospisil mutex_exit(&pidlock); 1138005d3febSMarek Pospisil crfree(newcred); 1139005d3febSMarek Pospisil return (ESRCH); /* no such process */ 1140005d3febSMarek Pospisil } 1141005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1142005d3febSMarek Pospisil mutex_exit(&pidlock); 1143005d3febSMarek Pospisil 1144005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */ 1145005d3febSMarek Pospisil 1146005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1147005d3febSMarek Pospisil crhold(cr = proc->p_cred); 1148005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1149005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1150005d3febSMarek Pospisil 1151005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 1152005d3febSMarek Pospisil if (ainfo == NULL) { 1153005d3febSMarek Pospisil crfree(cr); 1154005d3febSMarek Pospisil return (EINVAL); 1155005d3febSMarek Pospisil } 1156005d3febSMarek Pospisil 1157005d3febSMarek Pospisil /* designated process has an ipv6 address? */ 1158005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6) { 1159005d3febSMarek Pospisil crfree(cr); 1160005d3febSMarek Pospisil return (EOVERFLOW); 1161005d3febSMarek Pospisil } 1162005d3febSMarek Pospisil 1163005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid); 1164005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid); 1165005d3febSMarek Pospisil #ifdef _LP64 1166005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 1167005d3febSMarek Pospisil dev32_t dev; 1168005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 1169005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 1170005d3febSMarek Pospisil crfree(cr); 1171005d3febSMarek Pospisil return (EOVERFLOW); 1172005d3febSMarek Pospisil } 1173005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, dev); 1174005d3febSMarek Pospisil } else 1175005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port); 1176005d3febSMarek Pospisil #else 1177005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port); 1178005d3febSMarek Pospisil #endif 1179005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]); 1180005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask); 1181005d3febSMarek Pospisil 1182005d3febSMarek Pospisil crfree(cr); 1183005d3febSMarek Pospisil 1184005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo))) 1185005d3febSMarek Pospisil return (EFAULT); 1186005d3febSMarek Pospisil 1187005d3febSMarek Pospisil return (0); 1188005d3febSMarek Pospisil } 1189005d3febSMarek Pospisil 1190005d3febSMarek Pospisil static int 1191005d3febSMarek Pospisil getpinfo_addr(caddr_t data, int len) 1192005d3febSMarek Pospisil { 1193005d3febSMarek Pospisil STRUCT_DECL(auditpinfo_addr, apinfo); 1194005d3febSMarek Pospisil proc_t *proc; 1195005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 1196005d3febSMarek Pospisil model_t model; 1197005d3febSMarek Pospisil cred_t *cr, *newcred; 1198005d3febSMarek Pospisil 1199005d3febSMarek Pospisil model = get_udatamodel(); 1200005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1201005d3febSMarek Pospisil 1202005d3febSMarek Pospisil if (len < STRUCT_SIZE(apinfo)) 1203005d3febSMarek Pospisil return (EOVERFLOW); 1204005d3febSMarek Pospisil 1205005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1206005d3febSMarek Pospisil return (EFAULT); 1207005d3febSMarek Pospisil 1208005d3febSMarek Pospisil newcred = cralloc(); 1209005d3febSMarek Pospisil 1210005d3febSMarek Pospisil mutex_enter(&pidlock); 1211005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1212005d3febSMarek Pospisil mutex_exit(&pidlock); 1213005d3febSMarek Pospisil crfree(newcred); 1214005d3febSMarek Pospisil return (ESRCH); 1215005d3febSMarek Pospisil } 1216005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1217005d3febSMarek Pospisil mutex_exit(&pidlock); 1218005d3febSMarek Pospisil 1219005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */ 1220005d3febSMarek Pospisil 1221005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1222005d3febSMarek Pospisil crhold(cr = proc->p_cred); 1223005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1224005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1225005d3febSMarek Pospisil 1226005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 1227005d3febSMarek Pospisil if (ainfo == NULL) { 1228005d3febSMarek Pospisil crfree(cr); 1229005d3febSMarek Pospisil return (EINVAL); 1230005d3febSMarek Pospisil } 1231005d3febSMarek Pospisil 1232005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid); 1233005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid); 1234005d3febSMarek Pospisil #ifdef _LP64 1235005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 1236005d3febSMarek Pospisil dev32_t dev; 1237005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 1238005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 1239005d3febSMarek Pospisil crfree(cr); 1240005d3febSMarek Pospisil return (EOVERFLOW); 1241005d3febSMarek Pospisil } 1242005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, dev); 1243005d3febSMarek Pospisil } else 1244005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, 1245005d3febSMarek Pospisil ainfo->ai_termid.at_port); 1246005d3febSMarek Pospisil #else 1247005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port); 1248005d3febSMarek Pospisil #endif 1249005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type); 1250005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]); 1251005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]); 1252005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]); 1253005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]); 1254005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask); 1255005d3febSMarek Pospisil 1256005d3febSMarek Pospisil crfree(cr); 1257005d3febSMarek Pospisil 1258005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo))) 1259005d3febSMarek Pospisil return (EFAULT); 1260005d3febSMarek Pospisil 1261005d3febSMarek Pospisil return (0); 1262005d3febSMarek Pospisil } 1263005d3febSMarek Pospisil 1264005d3febSMarek Pospisil static int 1265005d3febSMarek Pospisil setpmask(caddr_t data) 1266005d3febSMarek Pospisil { 1267005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo); 1268005d3febSMarek Pospisil proc_t *proc; 1269005d3febSMarek Pospisil cred_t *newcred; 1270005d3febSMarek Pospisil auditinfo_addr_t *ainfo; 1271005d3febSMarek Pospisil struct p_audit_data *pad; 1272005d3febSMarek Pospisil 1273005d3febSMarek Pospisil model_t model; 1274005d3febSMarek Pospisil 1275005d3febSMarek Pospisil model = get_udatamodel(); 1276005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1277005d3febSMarek Pospisil 1278005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1279005d3febSMarek Pospisil return (EFAULT); 1280005d3febSMarek Pospisil 1281005d3febSMarek Pospisil mutex_enter(&pidlock); 1282005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1283005d3febSMarek Pospisil mutex_exit(&pidlock); 1284005d3febSMarek Pospisil return (ESRCH); 1285005d3febSMarek Pospisil } 1286005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1287005d3febSMarek Pospisil mutex_exit(&pidlock); 1288005d3febSMarek Pospisil 1289005d3febSMarek Pospisil newcred = cralloc(); 1290005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { 1291005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1292005d3febSMarek Pospisil crfree(newcred); 1293005d3febSMarek Pospisil return (EINVAL); 1294005d3febSMarek Pospisil } 1295005d3febSMarek Pospisil 1296005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1297005d3febSMarek Pospisil crcopy_to(proc->p_cred, newcred); 1298005d3febSMarek Pospisil proc->p_cred = newcred; 1299005d3febSMarek Pospisil 1300005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask); 1301005d3febSMarek Pospisil 1302005d3febSMarek Pospisil /* 1303005d3febSMarek Pospisil * Unlock. No need to broadcast changes via set_proc_pre_sys(), 1304005d3febSMarek Pospisil * since t_pre_sys is ALWAYS on when audit is enabled... due to 1305005d3febSMarek Pospisil * syscall auditing. 1306005d3febSMarek Pospisil */ 1307005d3febSMarek Pospisil crfree(newcred); 1308005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1309005d3febSMarek Pospisil 1310005d3febSMarek Pospisil /* Reset flag for any previous pending mask change; this supercedes */ 1311005d3febSMarek Pospisil pad = P2A(proc); 1312005d3febSMarek Pospisil ASSERT(pad != NULL); 1313005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 1314005d3febSMarek Pospisil pad->pad_flags &= ~PAD_SETMASK; 1315005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 1316005d3febSMarek Pospisil 1317005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1318005d3febSMarek Pospisil 1319005d3febSMarek Pospisil return (0); 1320005d3febSMarek Pospisil } 1321005d3febSMarek Pospisil 1322005d3febSMarek Pospisil /* 1323005d3febSMarek Pospisil * The out of control system call 1324005d3febSMarek Pospisil * This is audit kitchen sink aka auditadm, aka auditon 1325005d3febSMarek Pospisil */ 1326005d3febSMarek Pospisil int 1327005d3febSMarek Pospisil auditctl( 1328005d3febSMarek Pospisil int cmd, 1329005d3febSMarek Pospisil caddr_t data, 1330005d3febSMarek Pospisil int length) 1331005d3febSMarek Pospisil { 1332005d3febSMarek Pospisil int result; 1333005d3febSMarek Pospisil 1334005d3febSMarek Pospisil switch (cmd) { 1335005d3febSMarek Pospisil case A_GETCOND: 1336005d3febSMarek Pospisil case A_GETCAR: 1337005d3febSMarek Pospisil case A_GETCLASS: 1338005d3febSMarek Pospisil case A_GETCWD: 1339005d3febSMarek Pospisil case A_GETKAUDIT: 1340005d3febSMarek Pospisil case A_GETKMASK: 1341005d3febSMarek Pospisil case A_GETPINFO: 1342005d3febSMarek Pospisil case A_GETPINFO_ADDR: 1343005d3febSMarek Pospisil case A_GETPOLICY: 1344005d3febSMarek Pospisil case A_GETQCTRL: 1345005d3febSMarek Pospisil case A_GETSTAT: 1346*134a1f4eSCasper H.S. Dik if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0) 1347005d3febSMarek Pospisil return (EPERM); 1348005d3febSMarek Pospisil break; 1349005d3febSMarek Pospisil default: 1350005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0) 1351005d3febSMarek Pospisil return (EPERM); 1352005d3febSMarek Pospisil break; 1353005d3febSMarek Pospisil } 1354005d3febSMarek Pospisil 1355005d3febSMarek Pospisil switch (cmd) { 1356005d3febSMarek Pospisil case A_GETPOLICY: 1357005d3febSMarek Pospisil result = getpolicy(data); 1358005d3febSMarek Pospisil break; 1359005d3febSMarek Pospisil case A_SETPOLICY: 1360005d3febSMarek Pospisil result = setpolicy(data); 1361005d3febSMarek Pospisil break; 1362005d3febSMarek Pospisil case A_GETKMASK: 1363005d3febSMarek Pospisil result = getkmask(data); 1364005d3febSMarek Pospisil break; 1365005d3febSMarek Pospisil case A_SETKMASK: 1366005d3febSMarek Pospisil result = setkmask(data); 1367005d3febSMarek Pospisil break; 1368005d3febSMarek Pospisil case A_GETKAUDIT: 1369005d3febSMarek Pospisil result = getkaudit(data, length); 1370005d3febSMarek Pospisil break; 1371005d3febSMarek Pospisil case A_SETKAUDIT: 1372005d3febSMarek Pospisil result = setkaudit(data, length); 1373005d3febSMarek Pospisil break; 1374005d3febSMarek Pospisil case A_GETQCTRL: 1375005d3febSMarek Pospisil result = getqctrl(data); 1376005d3febSMarek Pospisil break; 1377005d3febSMarek Pospisil case A_SETQCTRL: 1378005d3febSMarek Pospisil result = setqctrl(data); 1379005d3febSMarek Pospisil break; 1380005d3febSMarek Pospisil case A_GETCWD: 1381005d3febSMarek Pospisil result = getcwd(data, length); 1382005d3febSMarek Pospisil break; 1383005d3febSMarek Pospisil case A_GETCAR: 1384005d3febSMarek Pospisil result = getcar(data, length); 1385005d3febSMarek Pospisil break; 1386005d3febSMarek Pospisil case A_GETSTAT: 1387005d3febSMarek Pospisil result = getstat(data); 1388005d3febSMarek Pospisil break; 1389005d3febSMarek Pospisil case A_SETSTAT: 1390005d3febSMarek Pospisil result = setstat(data); 1391005d3febSMarek Pospisil break; 1392005d3febSMarek Pospisil case A_SETUMASK: 1393005d3febSMarek Pospisil result = setumask(data); 1394005d3febSMarek Pospisil break; 1395005d3febSMarek Pospisil case A_SETSMASK: 1396005d3febSMarek Pospisil result = setsmask(data); 1397005d3febSMarek Pospisil break; 1398005d3febSMarek Pospisil case A_GETCOND: 1399005d3febSMarek Pospisil result = getcond(data); 1400005d3febSMarek Pospisil break; 1401005d3febSMarek Pospisil case A_SETCOND: 1402005d3febSMarek Pospisil result = setcond(data); 1403005d3febSMarek Pospisil break; 1404005d3febSMarek Pospisil case A_GETCLASS: 1405005d3febSMarek Pospisil result = getclass(data); 1406005d3febSMarek Pospisil break; 1407005d3febSMarek Pospisil case A_SETCLASS: 1408005d3febSMarek Pospisil result = setclass(data); 1409005d3febSMarek Pospisil break; 1410005d3febSMarek Pospisil case A_GETPINFO: 1411005d3febSMarek Pospisil result = getpinfo(data); 1412005d3febSMarek Pospisil break; 1413005d3febSMarek Pospisil case A_GETPINFO_ADDR: 1414005d3febSMarek Pospisil result = getpinfo_addr(data, length); 1415005d3febSMarek Pospisil break; 1416005d3febSMarek Pospisil case A_SETPMASK: 1417005d3febSMarek Pospisil result = setpmask(data); 1418005d3febSMarek Pospisil break; 1419005d3febSMarek Pospisil default: 1420005d3febSMarek Pospisil result = EINVAL; 1421005d3febSMarek Pospisil break; 1422005d3febSMarek Pospisil } 1423005d3febSMarek Pospisil return (result); 14247c478bd9Sstevel@tonic-gate } 1425