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*005d3febSMarek 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> 31*005d3febSMarek Pospisil #include <c2/audit_kernel.h> 32*005d3febSMarek Pospisil #include <c2/audit_record.h> 33*005d3febSMarek Pospisil 34*005d3febSMarek Pospisil #define CLEAR_VAL -1 35*005d3febSMarek Pospisil 36*005d3febSMarek Pospisil extern kmutex_t pidlock; 37*005d3febSMarek Pospisil 38*005d3febSMarek Pospisil int audit_policy; /* global audit policies in force */ 39*005d3febSMarek 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; 46*005d3febSMarek Pospisil int result = 0; 477c478bd9Sstevel@tonic-gate 48*005d3febSMarek Pospisil if (audit_active == C2AUDIT_DISABLED) 49405e5d68Stz204579 return (ENOTSUP); 50405e5d68Stz204579 517c478bd9Sstevel@tonic-gate switch (uap->code) { 527c478bd9Sstevel@tonic-gate case BSM_GETAUID: 53*005d3febSMarek Pospisil result = getauid((caddr_t)uap->a1); 54*005d3febSMarek Pospisil break; 557c478bd9Sstevel@tonic-gate case BSM_SETAUID: 56*005d3febSMarek Pospisil result = setauid((caddr_t)uap->a1); 57*005d3febSMarek Pospisil break; 587c478bd9Sstevel@tonic-gate case BSM_GETAUDIT: 59*005d3febSMarek Pospisil result = getaudit((caddr_t)uap->a1); 60*005d3febSMarek Pospisil break; 61*005d3febSMarek Pospisil case BSM_GETAUDIT_ADDR: 62*005d3febSMarek Pospisil result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2); 63*005d3febSMarek Pospisil break; 647c478bd9Sstevel@tonic-gate case BSM_SETAUDIT: 65*005d3febSMarek Pospisil result = setaudit((caddr_t)uap->a1); 66*005d3febSMarek Pospisil break; 67*005d3febSMarek Pospisil case BSM_SETAUDIT_ADDR: 68*005d3febSMarek Pospisil result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2); 69*005d3febSMarek Pospisil break; 707c478bd9Sstevel@tonic-gate case BSM_AUDITCTL: 71*005d3febSMarek Pospisil result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3); 72*005d3febSMarek Pospisil break; 73*005d3febSMarek Pospisil case BSM_AUDIT: 74*005d3febSMarek Pospisil if (audit_active == C2AUDIT_UNLOADED) 75*005d3febSMarek Pospisil return (0); 76*005d3febSMarek Pospisil result = audit((caddr_t)uap->a1, (int)uap->a2); 77*005d3febSMarek Pospisil break; 78*005d3febSMarek Pospisil case BSM_AUDITDOOR: 79*005d3febSMarek Pospisil if (audit_active == C2AUDIT_LOADED) { 80*005d3febSMarek Pospisil result = auditdoor((int)uap->a1); 81*005d3febSMarek Pospisil break; 82*005d3febSMarek Pospisil } 837c478bd9Sstevel@tonic-gate default: 84*005d3febSMarek Pospisil if (audit_active == C2AUDIT_LOADED) { 85*005d3febSMarek Pospisil result = EINVAL; 86*005d3febSMarek Pospisil break; 87*005d3febSMarek 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 } 95*005d3febSMarek Pospisil rvp->r_vals = result; 96*005d3febSMarek Pospisil return (result); 97*005d3febSMarek Pospisil } 98*005d3febSMarek Pospisil 99*005d3febSMarek Pospisil /* 100*005d3febSMarek Pospisil * Return the audit user ID for the current process. Currently only 101*005d3febSMarek Pospisil * the privileged processes may see the audit id. That may change. 102*005d3febSMarek Pospisil * If copyout is unsucessful return EFAULT. 103*005d3febSMarek Pospisil */ 104*005d3febSMarek Pospisil int 105*005d3febSMarek Pospisil getauid(caddr_t auid_p) 106*005d3febSMarek Pospisil { 107*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 108*005d3febSMarek Pospisil 109*005d3febSMarek Pospisil if (secpolicy_audit_getattr(CRED()) != 0) 110*005d3febSMarek Pospisil return (EPERM); 111*005d3febSMarek Pospisil 112*005d3febSMarek Pospisil ainfo = crgetauinfo(CRED()); 113*005d3febSMarek Pospisil if (ainfo == NULL) 114*005d3febSMarek Pospisil return (EINVAL); 115*005d3febSMarek Pospisil 116*005d3febSMarek Pospisil if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t))) 117*005d3febSMarek Pospisil return (EFAULT); 118*005d3febSMarek Pospisil 119*005d3febSMarek Pospisil return (0); 120*005d3febSMarek Pospisil } 121*005d3febSMarek Pospisil 122*005d3febSMarek Pospisil /* 123*005d3febSMarek Pospisil * Set the audit userid, for a process. This can only be changed by 124*005d3febSMarek Pospisil * privileged processes. The audit userid is inherited across forks & execs. 125*005d3febSMarek Pospisil * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT. 126*005d3febSMarek Pospisil */ 127*005d3febSMarek Pospisil int 128*005d3febSMarek Pospisil setauid(caddr_t auid_p) 129*005d3febSMarek Pospisil { 130*005d3febSMarek Pospisil proc_t *p; 131*005d3febSMarek Pospisil au_id_t auid; 132*005d3febSMarek Pospisil cred_t *newcred; 133*005d3febSMarek Pospisil auditinfo_addr_t *auinfo; 134*005d3febSMarek Pospisil 135*005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0) 136*005d3febSMarek Pospisil return (EPERM); 137*005d3febSMarek Pospisil 138*005d3febSMarek Pospisil if (copyin(auid_p, &auid, sizeof (au_id_t))) { 139*005d3febSMarek Pospisil return (EFAULT); 140*005d3febSMarek Pospisil } 141*005d3febSMarek Pospisil 142*005d3febSMarek Pospisil newcred = cralloc(); 143*005d3febSMarek Pospisil if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) { 144*005d3febSMarek Pospisil crfree(newcred); 145*005d3febSMarek Pospisil return (EINVAL); 146*005d3febSMarek Pospisil } 147*005d3febSMarek Pospisil 148*005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */ 149*005d3febSMarek Pospisil p = curproc; 150*005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 151*005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred); 152*005d3febSMarek Pospisil p->p_cred = newcred; 153*005d3febSMarek Pospisil 154*005d3febSMarek Pospisil auinfo->ai_auid = auid; /* update the auid */ 155*005d3febSMarek Pospisil 156*005d3febSMarek Pospisil /* unlock and broadcast the cred changes */ 157*005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 158*005d3febSMarek Pospisil crset(p, newcred); 159*005d3febSMarek Pospisil 160*005d3febSMarek Pospisil return (0); 161*005d3febSMarek Pospisil } 162*005d3febSMarek Pospisil 163*005d3febSMarek Pospisil /* 164*005d3febSMarek Pospisil * Get the audit state information from the current process. 165*005d3febSMarek Pospisil * Return EFAULT if copyout fails. 166*005d3febSMarek Pospisil */ 167*005d3febSMarek Pospisil int 168*005d3febSMarek Pospisil getaudit(caddr_t info_p) 169*005d3febSMarek Pospisil { 170*005d3febSMarek Pospisil STRUCT_DECL(auditinfo, info); 171*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 172*005d3febSMarek Pospisil model_t model; 173*005d3febSMarek Pospisil 174*005d3febSMarek Pospisil if (secpolicy_audit_getattr(CRED()) != 0) 175*005d3febSMarek Pospisil return (EPERM); 176*005d3febSMarek Pospisil 177*005d3febSMarek Pospisil model = get_udatamodel(); 178*005d3febSMarek Pospisil STRUCT_INIT(info, model); 179*005d3febSMarek Pospisil 180*005d3febSMarek Pospisil ainfo = crgetauinfo(CRED()); 181*005d3febSMarek Pospisil if (ainfo == NULL) 182*005d3febSMarek Pospisil return (EINVAL); 183*005d3febSMarek Pospisil 184*005d3febSMarek Pospisil /* trying to read a process with an IPv6 address? */ 185*005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6) 186*005d3febSMarek Pospisil return (EOVERFLOW); 187*005d3febSMarek Pospisil 188*005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, ainfo->ai_auid); 189*005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, ainfo->ai_mask); 190*005d3febSMarek Pospisil #ifdef _LP64 191*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 192*005d3febSMarek Pospisil dev32_t dev; 193*005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 194*005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 195*005d3febSMarek Pospisil return (EOVERFLOW); 196*005d3febSMarek Pospisil } 197*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, dev); 198*005d3febSMarek Pospisil } else 199*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port); 200*005d3febSMarek Pospisil #else 201*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port); 202*005d3febSMarek Pospisil #endif 203*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]); 204*005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, ainfo->ai_asid); 205*005d3febSMarek Pospisil 206*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info))) 207*005d3febSMarek Pospisil return (EFAULT); 208*005d3febSMarek Pospisil 209*005d3febSMarek Pospisil return (0); 210*005d3febSMarek Pospisil } 211*005d3febSMarek Pospisil 212*005d3febSMarek Pospisil /* 213*005d3febSMarek Pospisil * Get the audit state information from the current process. 214*005d3febSMarek Pospisil * Return EFAULT if copyout fails. 215*005d3febSMarek Pospisil */ 216*005d3febSMarek Pospisil int 217*005d3febSMarek Pospisil getaudit_addr(caddr_t info_p, int len) 218*005d3febSMarek Pospisil { 219*005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 220*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 221*005d3febSMarek Pospisil model_t model; 222*005d3febSMarek Pospisil 223*005d3febSMarek Pospisil if (secpolicy_audit_getattr(CRED()) != 0) 224*005d3febSMarek Pospisil return (EPERM); 225*005d3febSMarek Pospisil 226*005d3febSMarek Pospisil model = get_udatamodel(); 227*005d3febSMarek Pospisil STRUCT_INIT(info, model); 228*005d3febSMarek Pospisil 229*005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 230*005d3febSMarek Pospisil return (EOVERFLOW); 231*005d3febSMarek Pospisil 232*005d3febSMarek Pospisil ainfo = crgetauinfo(CRED()); 233*005d3febSMarek Pospisil 234*005d3febSMarek Pospisil if (ainfo == NULL) 235*005d3febSMarek Pospisil return (EINVAL); 236*005d3febSMarek Pospisil 237*005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, ainfo->ai_auid); 238*005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, ainfo->ai_mask); 239*005d3febSMarek Pospisil #ifdef _LP64 240*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 241*005d3febSMarek Pospisil dev32_t dev; 242*005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 243*005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 244*005d3febSMarek Pospisil return (EOVERFLOW); 245*005d3febSMarek Pospisil } 246*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, dev); 247*005d3febSMarek Pospisil } else 248*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port); 249*005d3febSMarek Pospisil #else 250*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port); 251*005d3febSMarek Pospisil #endif 252*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type); 253*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]); 254*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]); 255*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]); 256*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]); 257*005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, ainfo->ai_asid); 258*005d3febSMarek Pospisil 259*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info))) 260*005d3febSMarek Pospisil return (EFAULT); 261*005d3febSMarek Pospisil 262*005d3febSMarek Pospisil return (0); 263*005d3febSMarek Pospisil } 264*005d3febSMarek Pospisil 265*005d3febSMarek Pospisil /* 266*005d3febSMarek Pospisil * Set the audit state information for the current process. 267*005d3febSMarek Pospisil * Return EFAULT if copyout fails. 268*005d3febSMarek Pospisil */ 269*005d3febSMarek Pospisil int 270*005d3febSMarek Pospisil setaudit(caddr_t info_p) 271*005d3febSMarek Pospisil { 272*005d3febSMarek Pospisil STRUCT_DECL(auditinfo, info); 273*005d3febSMarek Pospisil proc_t *p; 274*005d3febSMarek Pospisil cred_t *newcred; 275*005d3febSMarek Pospisil model_t model; 276*005d3febSMarek Pospisil auditinfo_addr_t *ainfo; 277*005d3febSMarek Pospisil 278*005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0) 279*005d3febSMarek Pospisil return (EPERM); 280*005d3febSMarek Pospisil 281*005d3febSMarek Pospisil model = get_udatamodel(); 282*005d3febSMarek Pospisil STRUCT_INIT(info, model); 283*005d3febSMarek Pospisil 284*005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) 285*005d3febSMarek Pospisil return (EFAULT); 286*005d3febSMarek Pospisil 287*005d3febSMarek Pospisil newcred = cralloc(); 288*005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { 289*005d3febSMarek Pospisil crfree(newcred); 290*005d3febSMarek Pospisil return (EINVAL); 291*005d3febSMarek Pospisil } 292*005d3febSMarek Pospisil 293*005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */ 294*005d3febSMarek Pospisil p = curproc; 295*005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 296*005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred); 297*005d3febSMarek Pospisil p->p_cred = newcred; 298*005d3febSMarek Pospisil 299*005d3febSMarek Pospisil /* Set audit mask, id, termid and session id as specified */ 300*005d3febSMarek Pospisil ainfo->ai_auid = STRUCT_FGET(info, ai_auid); 301*005d3febSMarek Pospisil #ifdef _LP64 302*005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */ 303*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) 304*005d3febSMarek Pospisil ainfo->ai_termid.at_port = 305*005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.port)); 306*005d3febSMarek Pospisil else 307*005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port); 308*005d3febSMarek Pospisil #else 309*005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port); 310*005d3febSMarek Pospisil #endif 311*005d3febSMarek Pospisil ainfo->ai_termid.at_type = AU_IPv4; 312*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine); 313*005d3febSMarek Pospisil ainfo->ai_asid = STRUCT_FGET(info, ai_asid); 314*005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(info, ai_mask); 315*005d3febSMarek Pospisil 316*005d3febSMarek Pospisil /* unlock and broadcast the cred changes */ 317*005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 318*005d3febSMarek Pospisil crset(p, newcred); 319*005d3febSMarek Pospisil 320*005d3febSMarek Pospisil return (0); 321*005d3febSMarek Pospisil } 322*005d3febSMarek Pospisil 323*005d3febSMarek Pospisil /* 324*005d3febSMarek Pospisil * Set the audit state information for the current process. 325*005d3febSMarek Pospisil * Return EFAULT if copyin fails. 326*005d3febSMarek Pospisil */ 327*005d3febSMarek Pospisil int 328*005d3febSMarek Pospisil setaudit_addr(caddr_t info_p, int len) 329*005d3febSMarek Pospisil { 330*005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 331*005d3febSMarek Pospisil proc_t *p; 332*005d3febSMarek Pospisil cred_t *newcred; 333*005d3febSMarek Pospisil model_t model; 334*005d3febSMarek Pospisil int i; 335*005d3febSMarek Pospisil int type; 336*005d3febSMarek Pospisil auditinfo_addr_t *ainfo; 337*005d3febSMarek Pospisil 338*005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0) 339*005d3febSMarek Pospisil return (EPERM); 340*005d3febSMarek Pospisil 341*005d3febSMarek Pospisil model = get_udatamodel(); 342*005d3febSMarek Pospisil STRUCT_INIT(info, model); 343*005d3febSMarek Pospisil 344*005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 345*005d3febSMarek Pospisil return (EOVERFLOW); 346*005d3febSMarek Pospisil 347*005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) 348*005d3febSMarek Pospisil return (EFAULT); 349*005d3febSMarek Pospisil 350*005d3febSMarek Pospisil type = STRUCT_FGET(info, ai_termid.at_type); 351*005d3febSMarek Pospisil if ((type != AU_IPv4) && (type != AU_IPv6)) 352*005d3febSMarek Pospisil return (EINVAL); 353*005d3febSMarek Pospisil 354*005d3febSMarek Pospisil newcred = cralloc(); 355*005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { 356*005d3febSMarek Pospisil crfree(newcred); 357*005d3febSMarek Pospisil return (EINVAL); 358*005d3febSMarek Pospisil } 359*005d3febSMarek Pospisil 360*005d3febSMarek Pospisil /* grab p_crlock and switch to new cred */ 361*005d3febSMarek Pospisil p = curproc; 362*005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 363*005d3febSMarek Pospisil crcopy_to(p->p_cred, newcred); 364*005d3febSMarek Pospisil p->p_cred = newcred; 365*005d3febSMarek Pospisil 366*005d3febSMarek Pospisil /* Set audit mask, id, termid and session id as specified */ 367*005d3febSMarek Pospisil ainfo->ai_auid = STRUCT_FGET(info, ai_auid); 368*005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(info, ai_mask); 369*005d3febSMarek Pospisil #ifdef _LP64 370*005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */ 371*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) 372*005d3febSMarek Pospisil ainfo->ai_termid.at_port = 373*005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.at_port)); 374*005d3febSMarek Pospisil else 375*005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); 376*005d3febSMarek Pospisil #else 377*005d3febSMarek Pospisil ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); 378*005d3febSMarek Pospisil #endif 379*005d3febSMarek Pospisil ainfo->ai_termid.at_type = type; 380*005d3febSMarek Pospisil bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr)); 381*005d3febSMarek Pospisil for (i = 0; i < (type/sizeof (int)); i++) 382*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[i] = 383*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[i]); 384*005d3febSMarek Pospisil 385*005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6 && 386*005d3febSMarek Pospisil IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) { 387*005d3febSMarek Pospisil ainfo->ai_termid.at_type = AU_IPv4; 388*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3]; 389*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[1] = 0; 390*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[2] = 0; 391*005d3febSMarek Pospisil ainfo->ai_termid.at_addr[3] = 0; 392*005d3febSMarek Pospisil } 393*005d3febSMarek Pospisil 394*005d3febSMarek Pospisil ainfo->ai_asid = STRUCT_FGET(info, ai_asid); 395*005d3febSMarek Pospisil 396*005d3febSMarek Pospisil /* unlock and broadcast the cred changes */ 397*005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 398*005d3febSMarek Pospisil crset(p, newcred); 399*005d3febSMarek Pospisil 400*005d3febSMarek Pospisil return (0); 401*005d3febSMarek Pospisil } 402*005d3febSMarek Pospisil 403*005d3febSMarek Pospisil /* 404*005d3febSMarek Pospisil * Get the global policy flag 405*005d3febSMarek Pospisil */ 406*005d3febSMarek Pospisil static int 407*005d3febSMarek Pospisil getpolicy(caddr_t data) 408*005d3febSMarek Pospisil { 409*005d3febSMarek Pospisil int policy; 410*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 411*005d3febSMarek Pospisil 412*005d3febSMarek Pospisil policy = audit_policy | kctx->auk_policy; 413*005d3febSMarek Pospisil 414*005d3febSMarek Pospisil if (copyout(&policy, data, sizeof (int))) 415*005d3febSMarek Pospisil return (EFAULT); 416*005d3febSMarek Pospisil return (0); 417*005d3febSMarek Pospisil } 418*005d3febSMarek Pospisil 419*005d3febSMarek Pospisil /* 420*005d3febSMarek Pospisil * Set the global and local policy flags 421*005d3febSMarek Pospisil * 422*005d3febSMarek Pospisil * The global flags only make sense from the global zone; 423*005d3febSMarek Pospisil * the local flags depend on the AUDIT_PERZONE policy: 424*005d3febSMarek Pospisil * if the perzone policy is set, then policy is set separately 425*005d3febSMarek Pospisil * per zone, else held only in the global zone. 426*005d3febSMarek Pospisil * 427*005d3febSMarek Pospisil * The initial value of a local zone's policy flag is determined 428*005d3febSMarek Pospisil * by the value of the global zone's flags at the time the 429*005d3febSMarek Pospisil * local zone is created. 430*005d3febSMarek Pospisil * 431*005d3febSMarek Pospisil * While auditconfig(1M) allows setting and unsetting policies one bit 432*005d3febSMarek Pospisil * at a time, the mask passed in from auditconfig() is created by a 433*005d3febSMarek Pospisil * syscall to getpolicy and then modified based on the auditconfig() 434*005d3febSMarek Pospisil * cmd line, so the input policy value is used to replace the existing 435*005d3febSMarek Pospisil * policy. 436*005d3febSMarek Pospisil */ 437*005d3febSMarek Pospisil static int 438*005d3febSMarek Pospisil setpolicy(caddr_t data) 439*005d3febSMarek Pospisil { 440*005d3febSMarek Pospisil int policy; 441*005d3febSMarek Pospisil au_kcontext_t *kctx; 442*005d3febSMarek Pospisil 443*005d3febSMarek Pospisil if (copyin(data, &policy, sizeof (int))) 444*005d3febSMarek Pospisil return (EFAULT); 445*005d3febSMarek Pospisil 446*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 447*005d3febSMarek Pospisil 448*005d3febSMarek Pospisil if (INGLOBALZONE(curproc)) { 449*005d3febSMarek Pospisil if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL)) 450*005d3febSMarek Pospisil return (EINVAL); 451*005d3febSMarek Pospisil 452*005d3febSMarek Pospisil audit_policy = policy & AUDIT_GLOBAL; 453*005d3febSMarek Pospisil } else { 454*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE)) 455*005d3febSMarek Pospisil return (EINVAL); 456*005d3febSMarek Pospisil 457*005d3febSMarek Pospisil if (policy & ~AUDIT_LOCAL) /* global bits are a no-no */ 458*005d3febSMarek Pospisil return (EINVAL); 459*005d3febSMarek Pospisil } 460*005d3febSMarek Pospisil kctx->auk_policy = policy & AUDIT_LOCAL; 461*005d3febSMarek Pospisil 462*005d3febSMarek Pospisil /* 463*005d3febSMarek Pospisil * auk_current_vp is NULL before auditd starts (or during early 464*005d3febSMarek Pospisil * auditd starup) or if auditd is halted; in either case, 465*005d3febSMarek Pospisil * notification of a policy change is not needed, since auditd 466*005d3febSMarek Pospisil * reads policy as it comes up. The error return from au_doormsg() 467*005d3febSMarek Pospisil * is ignored to avoid a race condition -- for example if auditd 468*005d3febSMarek Pospisil * segv's, the audit state may be "auditing" but the door may 469*005d3febSMarek Pospisil * be closed. Returning an error if the door is open makes it 470*005d3febSMarek Pospisil * impossible for Greenline to restart auditd. 471*005d3febSMarek Pospisil */ 472*005d3febSMarek Pospisil if (kctx->auk_current_vp != NULL) 473*005d3febSMarek Pospisil (void) au_doormsg(kctx, AU_DBUF_POLICY, &policy); 474*005d3febSMarek Pospisil 475*005d3febSMarek Pospisil /* 476*005d3febSMarek Pospisil * Wake up anyone who might have blocked on full audit 477*005d3febSMarek Pospisil * partitions. audit daemons need to set AUDIT_FULL when no 478*005d3febSMarek Pospisil * space so we can tell if we should start dropping records. 479*005d3febSMarek Pospisil */ 480*005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 481*005d3febSMarek Pospisil 482*005d3febSMarek Pospisil if ((policy & (AUDIT_CNT | AUDIT_SCNT) && 483*005d3febSMarek Pospisil (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater))) 484*005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv)); 485*005d3febSMarek Pospisil 486*005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 487*005d3febSMarek Pospisil 488*005d3febSMarek Pospisil return (0); 489*005d3febSMarek Pospisil } 490*005d3febSMarek Pospisil 491*005d3febSMarek Pospisil static int 492*005d3febSMarek Pospisil getkmask(caddr_t data) 493*005d3febSMarek Pospisil { 494*005d3febSMarek Pospisil au_kcontext_t *kctx; 495*005d3febSMarek Pospisil 496*005d3febSMarek Pospisil kctx = GET_KCTX_PZ; 497*005d3febSMarek Pospisil 498*005d3febSMarek Pospisil if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t))) 499*005d3febSMarek Pospisil return (EFAULT); 500*005d3febSMarek Pospisil return (0); 501*005d3febSMarek Pospisil } 502*005d3febSMarek Pospisil 503*005d3febSMarek Pospisil static int 504*005d3febSMarek Pospisil setkmask(caddr_t data) 505*005d3febSMarek Pospisil { 506*005d3febSMarek Pospisil au_mask_t mask; 507*005d3febSMarek Pospisil au_kcontext_t *kctx; 508*005d3febSMarek Pospisil 509*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 510*005d3febSMarek Pospisil return (EINVAL); 511*005d3febSMarek Pospisil 512*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 513*005d3febSMarek Pospisil 514*005d3febSMarek Pospisil if (copyin(data, &mask, sizeof (au_mask_t))) 515*005d3febSMarek Pospisil return (EFAULT); 516*005d3febSMarek Pospisil 517*005d3febSMarek Pospisil kctx->auk_info.ai_mask = mask; 518*005d3febSMarek Pospisil return (0); 519*005d3febSMarek Pospisil } 520*005d3febSMarek Pospisil 521*005d3febSMarek Pospisil static int 522*005d3febSMarek Pospisil getkaudit(caddr_t info_p, int len) 523*005d3febSMarek Pospisil { 524*005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 525*005d3febSMarek Pospisil model_t model; 526*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 527*005d3febSMarek Pospisil 528*005d3febSMarek Pospisil model = get_udatamodel(); 529*005d3febSMarek Pospisil STRUCT_INIT(info, model); 530*005d3febSMarek Pospisil 531*005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 532*005d3febSMarek Pospisil return (EOVERFLOW); 533*005d3febSMarek Pospisil 534*005d3febSMarek Pospisil STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid); 535*005d3febSMarek Pospisil STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask); 536*005d3febSMarek Pospisil #ifdef _LP64 537*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 538*005d3febSMarek Pospisil dev32_t dev; 539*005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 540*005d3febSMarek Pospisil if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) { 541*005d3febSMarek Pospisil return (EOVERFLOW); 542*005d3febSMarek Pospisil } 543*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, dev); 544*005d3febSMarek Pospisil } else { 545*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, 546*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port); 547*005d3febSMarek Pospisil } 548*005d3febSMarek Pospisil #else 549*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_port, 550*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port); 551*005d3febSMarek Pospisil #endif 552*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_type, 553*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type); 554*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[0], 555*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0]); 556*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[1], 557*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1]); 558*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[2], 559*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2]); 560*005d3febSMarek Pospisil STRUCT_FSET(info, ai_termid.at_addr[3], 561*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3]); 562*005d3febSMarek Pospisil STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid); 563*005d3febSMarek Pospisil 564*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info))) 565*005d3febSMarek Pospisil return (EFAULT); 566*005d3febSMarek Pospisil 567*005d3febSMarek Pospisil return (0); 568*005d3febSMarek Pospisil } 569*005d3febSMarek Pospisil 570*005d3febSMarek Pospisil /* 571*005d3febSMarek Pospisil * the host address for AUDIT_PERZONE == 0 is that of the global 572*005d3febSMarek Pospisil * zone and for local zones it is of the current zone. 573*005d3febSMarek Pospisil */ 574*005d3febSMarek Pospisil static int 575*005d3febSMarek Pospisil setkaudit(caddr_t info_p, int len) 576*005d3febSMarek Pospisil { 577*005d3febSMarek Pospisil STRUCT_DECL(auditinfo_addr, info); 578*005d3febSMarek Pospisil model_t model; 579*005d3febSMarek Pospisil au_kcontext_t *kctx; 580*005d3febSMarek Pospisil 581*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 582*005d3febSMarek Pospisil return (EINVAL); 583*005d3febSMarek Pospisil 584*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 585*005d3febSMarek Pospisil 586*005d3febSMarek Pospisil model = get_udatamodel(); 587*005d3febSMarek Pospisil STRUCT_INIT(info, model); 588*005d3febSMarek Pospisil 589*005d3febSMarek Pospisil if (len < STRUCT_SIZE(info)) 590*005d3febSMarek Pospisil return (EOVERFLOW); 591*005d3febSMarek Pospisil 592*005d3febSMarek Pospisil if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info))) 593*005d3febSMarek Pospisil return (EFAULT); 594*005d3febSMarek Pospisil 595*005d3febSMarek Pospisil if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) && 596*005d3febSMarek Pospisil (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6)) 597*005d3febSMarek Pospisil return (EINVAL); 598*005d3febSMarek Pospisil 599*005d3febSMarek Pospisil /* Set audit mask, termid and session id as specified */ 600*005d3febSMarek Pospisil kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid); 601*005d3febSMarek Pospisil kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask); 602*005d3febSMarek Pospisil #ifdef _LP64 603*005d3febSMarek Pospisil /* only convert to 64 bit if coming from a 32 bit binary */ 604*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) 605*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = 606*005d3febSMarek Pospisil DEVEXPL(STRUCT_FGET(info, ai_termid.at_port)); 607*005d3febSMarek Pospisil else 608*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = 609*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_port); 610*005d3febSMarek Pospisil #else 611*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port); 612*005d3febSMarek Pospisil #endif 613*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type); 614*005d3febSMarek Pospisil bzero(&kctx->auk_info.ai_termid.at_addr[0], 615*005d3febSMarek Pospisil sizeof (kctx->auk_info.ai_termid.at_addr)); 616*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] = 617*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[0]); 618*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] = 619*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[1]); 620*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] = 621*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[2]); 622*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] = 623*005d3febSMarek Pospisil STRUCT_FGET(info, ai_termid.at_addr[3]); 624*005d3febSMarek Pospisil kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid); 625*005d3febSMarek Pospisil 626*005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6 && 627*005d3febSMarek Pospisil IN6_IS_ADDR_V4MAPPED( 628*005d3febSMarek Pospisil ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) { 629*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_type = AU_IPv4; 630*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[0] = 631*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3]; 632*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[1] = 0; 633*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[2] = 0; 634*005d3febSMarek Pospisil kctx->auk_info.ai_termid.at_addr[3] = 0; 635*005d3febSMarek Pospisil } 636*005d3febSMarek Pospisil if (kctx->auk_info.ai_termid.at_type == AU_IPv6) 637*005d3febSMarek Pospisil kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED( 638*005d3febSMarek Pospisil (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1; 639*005d3febSMarek Pospisil else 640*005d3febSMarek Pospisil kctx->auk_hostaddr_valid = 641*005d3febSMarek Pospisil (kctx->auk_info.ai_termid.at_addr[0] == 642*005d3febSMarek Pospisil htonl(INADDR_ANY)) ? 0 : 1; 643*005d3febSMarek Pospisil 644*005d3febSMarek Pospisil return (0); 645*005d3febSMarek Pospisil } 646*005d3febSMarek Pospisil 647*005d3febSMarek Pospisil static int 648*005d3febSMarek Pospisil getqctrl(caddr_t data) 649*005d3febSMarek Pospisil { 650*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 651*005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl); 652*005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel()); 653*005d3febSMarek Pospisil 654*005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 655*005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater); 656*005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater); 657*005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz); 658*005d3febSMarek Pospisil STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay); 659*005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 660*005d3febSMarek Pospisil 661*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl))) 662*005d3febSMarek Pospisil return (EFAULT); 663*005d3febSMarek Pospisil 664*005d3febSMarek Pospisil return (0); 665*005d3febSMarek Pospisil } 666*005d3febSMarek Pospisil 667*005d3febSMarek Pospisil static int 668*005d3febSMarek Pospisil setqctrl(caddr_t data) 669*005d3febSMarek Pospisil { 670*005d3febSMarek Pospisil au_kcontext_t *kctx; 671*005d3febSMarek Pospisil struct au_qctrl qctrl_tmp; 672*005d3febSMarek Pospisil STRUCT_DECL(au_qctrl, qctrl); 673*005d3febSMarek Pospisil STRUCT_INIT(qctrl, get_udatamodel()); 674*005d3febSMarek Pospisil 675*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 676*005d3febSMarek Pospisil return (EINVAL); 677*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 678*005d3febSMarek Pospisil 679*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl))) 680*005d3febSMarek Pospisil return (EFAULT); 681*005d3febSMarek Pospisil 682*005d3febSMarek Pospisil qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater); 683*005d3febSMarek Pospisil qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater); 684*005d3febSMarek Pospisil qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz); 685*005d3febSMarek Pospisil qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay); 686*005d3febSMarek Pospisil 687*005d3febSMarek Pospisil /* enforce sane values */ 688*005d3febSMarek Pospisil 689*005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater) 690*005d3febSMarek Pospisil return (EINVAL); 691*005d3febSMarek Pospisil 692*005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater < AQ_LOWATER) 693*005d3febSMarek Pospisil return (EINVAL); 694*005d3febSMarek Pospisil 695*005d3febSMarek Pospisil if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH) 696*005d3febSMarek Pospisil return (EINVAL); 697*005d3febSMarek Pospisil 698*005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz < AQ_BUFSZ) 699*005d3febSMarek Pospisil return (EINVAL); 700*005d3febSMarek Pospisil 701*005d3febSMarek Pospisil if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ) 702*005d3febSMarek Pospisil return (EINVAL); 703*005d3febSMarek Pospisil 704*005d3febSMarek Pospisil if (qctrl_tmp.aq_delay == 0) 705*005d3febSMarek Pospisil return (EINVAL); 706*005d3febSMarek Pospisil 707*005d3febSMarek Pospisil if (qctrl_tmp.aq_delay > AQ_MAXDELAY) 708*005d3febSMarek Pospisil return (EINVAL); 709*005d3febSMarek Pospisil 710*005d3febSMarek Pospisil /* update everything at once so things are consistant */ 711*005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 712*005d3febSMarek Pospisil kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater; 713*005d3febSMarek Pospisil kctx->auk_queue.lowater = qctrl_tmp.aq_lowater; 714*005d3febSMarek Pospisil kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz; 715*005d3febSMarek Pospisil kctx->auk_queue.delay = qctrl_tmp.aq_delay; 716*005d3febSMarek Pospisil 717*005d3febSMarek Pospisil if (kctx->auk_queue.rd_block && 718*005d3febSMarek Pospisil kctx->auk_queue.cnt > kctx->auk_queue.lowater) 719*005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv)); 720*005d3febSMarek Pospisil 721*005d3febSMarek Pospisil if (kctx->auk_queue.wt_block && 722*005d3febSMarek Pospisil kctx->auk_queue.cnt < kctx->auk_queue.hiwater) 723*005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv)); 724*005d3febSMarek Pospisil 725*005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 726*005d3febSMarek Pospisil 727*005d3febSMarek Pospisil return (0); 728*005d3febSMarek Pospisil } 729*005d3febSMarek Pospisil 730*005d3febSMarek Pospisil static int 731*005d3febSMarek Pospisil getcwd(caddr_t data, int length) 732*005d3febSMarek Pospisil { 733*005d3febSMarek Pospisil struct p_audit_data *pad; 734*005d3febSMarek Pospisil struct audit_path *app; 735*005d3febSMarek Pospisil int pathlen; 736*005d3febSMarek Pospisil 737*005d3febSMarek Pospisil pad = P2A(curproc); 738*005d3febSMarek Pospisil ASSERT(pad != NULL); 739*005d3febSMarek Pospisil 740*005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 741*005d3febSMarek Pospisil app = pad->pad_cwd; 742*005d3febSMarek Pospisil au_pathhold(app); 743*005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 744*005d3febSMarek Pospisil 745*005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0]; 746*005d3febSMarek Pospisil if (pathlen > length) { 747*005d3febSMarek Pospisil au_pathrele(app); 748*005d3febSMarek Pospisil return (E2BIG); 749*005d3febSMarek Pospisil } 750*005d3febSMarek Pospisil 751*005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) { 752*005d3febSMarek Pospisil au_pathrele(app); 753*005d3febSMarek Pospisil return (EFAULT); 754*005d3febSMarek Pospisil } 755*005d3febSMarek Pospisil 756*005d3febSMarek Pospisil au_pathrele(app); 757*005d3febSMarek Pospisil return (0); 758*005d3febSMarek Pospisil } 759*005d3febSMarek Pospisil 760*005d3febSMarek Pospisil static int 761*005d3febSMarek Pospisil getcar(caddr_t data, int length) 762*005d3febSMarek Pospisil { 763*005d3febSMarek Pospisil struct p_audit_data *pad; 764*005d3febSMarek Pospisil struct audit_path *app; 765*005d3febSMarek Pospisil int pathlen; 766*005d3febSMarek Pospisil 767*005d3febSMarek Pospisil pad = P2A(curproc); 768*005d3febSMarek Pospisil ASSERT(pad != NULL); 769*005d3febSMarek Pospisil 770*005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 771*005d3febSMarek Pospisil app = pad->pad_root; 772*005d3febSMarek Pospisil au_pathhold(app); 773*005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 774*005d3febSMarek Pospisil 775*005d3febSMarek Pospisil pathlen = app->audp_sect[1] - app->audp_sect[0]; 776*005d3febSMarek Pospisil if (pathlen > length) { 777*005d3febSMarek Pospisil au_pathrele(app); 778*005d3febSMarek Pospisil return (E2BIG); 779*005d3febSMarek Pospisil } 780*005d3febSMarek Pospisil 781*005d3febSMarek Pospisil if (copyout(app->audp_sect[0], data, pathlen)) { 782*005d3febSMarek Pospisil au_pathrele(app); 783*005d3febSMarek Pospisil return (EFAULT); 784*005d3febSMarek Pospisil } 785*005d3febSMarek Pospisil 786*005d3febSMarek Pospisil au_pathrele(app); 787*005d3febSMarek Pospisil return (0); 788*005d3febSMarek Pospisil } 789*005d3febSMarek Pospisil 790*005d3febSMarek Pospisil static int 791*005d3febSMarek Pospisil getstat(caddr_t data) 792*005d3febSMarek Pospisil { 793*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 794*005d3febSMarek Pospisil 795*005d3febSMarek Pospisil membar_consumer(); 796*005d3febSMarek Pospisil 797*005d3febSMarek Pospisil if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t))) 798*005d3febSMarek Pospisil return (EFAULT); 799*005d3febSMarek Pospisil return (0); 800*005d3febSMarek Pospisil } 801*005d3febSMarek Pospisil 802*005d3febSMarek Pospisil static int 803*005d3febSMarek Pospisil setstat(caddr_t data) 804*005d3febSMarek Pospisil { 805*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 806*005d3febSMarek Pospisil au_stat_t au_stat; 807*005d3febSMarek Pospisil 808*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 809*005d3febSMarek Pospisil return (EINVAL); 810*005d3febSMarek Pospisil 811*005d3febSMarek Pospisil if (copyin(data, &au_stat, sizeof (au_stat_t))) 812*005d3febSMarek Pospisil return (EFAULT); 813*005d3febSMarek Pospisil 814*005d3febSMarek Pospisil if (au_stat.as_generated == CLEAR_VAL) 815*005d3febSMarek Pospisil kctx->auk_statistics.as_generated = 0; 816*005d3febSMarek Pospisil if (au_stat.as_nonattrib == CLEAR_VAL) 817*005d3febSMarek Pospisil kctx->auk_statistics.as_nonattrib = 0; 818*005d3febSMarek Pospisil if (au_stat.as_kernel == CLEAR_VAL) 819*005d3febSMarek Pospisil kctx->auk_statistics.as_kernel = 0; 820*005d3febSMarek Pospisil if (au_stat.as_audit == CLEAR_VAL) 821*005d3febSMarek Pospisil kctx->auk_statistics.as_audit = 0; 822*005d3febSMarek Pospisil if (au_stat.as_auditctl == CLEAR_VAL) 823*005d3febSMarek Pospisil kctx->auk_statistics.as_auditctl = 0; 824*005d3febSMarek Pospisil if (au_stat.as_enqueue == CLEAR_VAL) 825*005d3febSMarek Pospisil kctx->auk_statistics.as_enqueue = 0; 826*005d3febSMarek Pospisil if (au_stat.as_written == CLEAR_VAL) 827*005d3febSMarek Pospisil kctx->auk_statistics.as_written = 0; 828*005d3febSMarek Pospisil if (au_stat.as_wblocked == CLEAR_VAL) 829*005d3febSMarek Pospisil kctx->auk_statistics.as_wblocked = 0; 830*005d3febSMarek Pospisil if (au_stat.as_rblocked == CLEAR_VAL) 831*005d3febSMarek Pospisil kctx->auk_statistics.as_rblocked = 0; 832*005d3febSMarek Pospisil if (au_stat.as_dropped == CLEAR_VAL) 833*005d3febSMarek Pospisil kctx->auk_statistics.as_dropped = 0; 834*005d3febSMarek Pospisil if (au_stat.as_totalsize == CLEAR_VAL) 835*005d3febSMarek Pospisil kctx->auk_statistics.as_totalsize = 0; 836*005d3febSMarek Pospisil 837*005d3febSMarek Pospisil membar_producer(); 838*005d3febSMarek Pospisil 839*005d3febSMarek Pospisil return (0); 840*005d3febSMarek Pospisil 841*005d3febSMarek Pospisil } 842*005d3febSMarek Pospisil 843*005d3febSMarek Pospisil static int 844*005d3febSMarek Pospisil setumask(caddr_t data) 845*005d3febSMarek Pospisil { 846*005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info); 847*005d3febSMarek Pospisil struct proc *p; 848*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 849*005d3febSMarek Pospisil model_t model; 850*005d3febSMarek Pospisil 851*005d3febSMarek Pospisil /* setumask not applicable in non-global zones without perzone policy */ 852*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 853*005d3febSMarek Pospisil return (EINVAL); 854*005d3febSMarek Pospisil 855*005d3febSMarek Pospisil model = get_udatamodel(); 856*005d3febSMarek Pospisil STRUCT_INIT(user_info, model); 857*005d3febSMarek Pospisil 858*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info))) 859*005d3febSMarek Pospisil return (EFAULT); 860*005d3febSMarek Pospisil 861*005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */ 862*005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) { 863*005d3febSMarek Pospisil cred_t *cr; 864*005d3febSMarek Pospisil 865*005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */ 866*005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id)) 867*005d3febSMarek Pospisil continue; 868*005d3febSMarek Pospisil 869*005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */ 870*005d3febSMarek Pospisil 871*005d3febSMarek Pospisil /* skip system processes and ones being created or going away */ 872*005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB || 873*005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) { 874*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 875*005d3febSMarek Pospisil continue; 876*005d3febSMarek Pospisil } 877*005d3febSMarek Pospisil 878*005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 879*005d3febSMarek Pospisil crhold(cr = p->p_cred); 880*005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 881*005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 882*005d3febSMarek Pospisil if (ainfo == NULL) { 883*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 884*005d3febSMarek Pospisil crfree(cr); 885*005d3febSMarek Pospisil continue; 886*005d3febSMarek Pospisil } 887*005d3febSMarek Pospisil 888*005d3febSMarek Pospisil if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) { 889*005d3febSMarek Pospisil au_mask_t mask; 890*005d3febSMarek Pospisil int err; 891*005d3febSMarek Pospisil 892*005d3febSMarek Pospisil /* 893*005d3febSMarek Pospisil * Here's a process which matches the specified auid. 894*005d3febSMarek Pospisil * If its mask doesn't already match the new mask, 895*005d3febSMarek Pospisil * save the new mask in the pad, to be picked up 896*005d3febSMarek Pospisil * next syscall. 897*005d3febSMarek Pospisil */ 898*005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask); 899*005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t)); 900*005d3febSMarek Pospisil crfree(cr); 901*005d3febSMarek Pospisil if (err != 0) { 902*005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p); 903*005d3febSMarek Pospisil ASSERT(pad != NULL); 904*005d3febSMarek Pospisil 905*005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 906*005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK; 907*005d3febSMarek Pospisil pad->pad_newmask = mask; 908*005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 909*005d3febSMarek Pospisil 910*005d3febSMarek Pospisil /* 911*005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since 912*005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is 913*005d3febSMarek Pospisil * enabled...due to syscall auditing. 914*005d3febSMarek Pospisil */ 915*005d3febSMarek Pospisil } 916*005d3febSMarek Pospisil } else { 917*005d3febSMarek Pospisil crfree(cr); 918*005d3febSMarek Pospisil } 919*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 920*005d3febSMarek Pospisil } 921*005d3febSMarek Pospisil mutex_exit(&pidlock); 922*005d3febSMarek Pospisil 923*005d3febSMarek Pospisil return (0); 924*005d3febSMarek Pospisil } 925*005d3febSMarek Pospisil 926*005d3febSMarek Pospisil static int 927*005d3febSMarek Pospisil setsmask(caddr_t data) 928*005d3febSMarek Pospisil { 929*005d3febSMarek Pospisil STRUCT_DECL(auditinfo, user_info); 930*005d3febSMarek Pospisil struct proc *p; 931*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 932*005d3febSMarek Pospisil model_t model; 933*005d3febSMarek Pospisil 934*005d3febSMarek Pospisil /* setsmask not applicable in non-global zones without perzone policy */ 935*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 936*005d3febSMarek Pospisil return (EINVAL); 937*005d3febSMarek Pospisil 938*005d3febSMarek Pospisil model = get_udatamodel(); 939*005d3febSMarek Pospisil STRUCT_INIT(user_info, model); 940*005d3febSMarek Pospisil 941*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info))) 942*005d3febSMarek Pospisil return (EFAULT); 943*005d3febSMarek Pospisil 944*005d3febSMarek Pospisil mutex_enter(&pidlock); /* lock the process queue against updates */ 945*005d3febSMarek Pospisil for (p = practive; p != NULL; p = p->p_next) { 946*005d3febSMarek Pospisil cred_t *cr; 947*005d3febSMarek Pospisil 948*005d3febSMarek Pospisil /* if in non-global zone only modify processes in same zone */ 949*005d3febSMarek Pospisil if (!HASZONEACCESS(curproc, p->p_zone->zone_id)) 950*005d3febSMarek Pospisil continue; 951*005d3febSMarek Pospisil 952*005d3febSMarek Pospisil mutex_enter(&p->p_lock); /* so process doesn't go away */ 953*005d3febSMarek Pospisil 954*005d3febSMarek Pospisil /* skip system processes and ones being created or going away */ 955*005d3febSMarek Pospisil if (p->p_stat == SIDL || p->p_stat == SZOMB || 956*005d3febSMarek Pospisil (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) { 957*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 958*005d3febSMarek Pospisil continue; 959*005d3febSMarek Pospisil } 960*005d3febSMarek Pospisil 961*005d3febSMarek Pospisil mutex_enter(&p->p_crlock); 962*005d3febSMarek Pospisil crhold(cr = p->p_cred); 963*005d3febSMarek Pospisil mutex_exit(&p->p_crlock); 964*005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 965*005d3febSMarek Pospisil if (ainfo == NULL) { 966*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 967*005d3febSMarek Pospisil crfree(cr); 968*005d3febSMarek Pospisil continue; 969*005d3febSMarek Pospisil } 970*005d3febSMarek Pospisil 971*005d3febSMarek Pospisil if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) { 972*005d3febSMarek Pospisil au_mask_t mask; 973*005d3febSMarek Pospisil int err; 974*005d3febSMarek Pospisil 975*005d3febSMarek Pospisil /* 976*005d3febSMarek Pospisil * Here's a process which matches the specified asid. 977*005d3febSMarek Pospisil * If its mask doesn't already match the new mask, 978*005d3febSMarek Pospisil * save the new mask in the pad, to be picked up 979*005d3febSMarek Pospisil * next syscall. 980*005d3febSMarek Pospisil */ 981*005d3febSMarek Pospisil mask = STRUCT_FGET(user_info, ai_mask); 982*005d3febSMarek Pospisil err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t)); 983*005d3febSMarek Pospisil crfree(cr); 984*005d3febSMarek Pospisil if (err != 0) { 985*005d3febSMarek Pospisil struct p_audit_data *pad = P2A(p); 986*005d3febSMarek Pospisil ASSERT(pad != NULL); 987*005d3febSMarek Pospisil 988*005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 989*005d3febSMarek Pospisil pad->pad_flags |= PAD_SETMASK; 990*005d3febSMarek Pospisil pad->pad_newmask = mask; 991*005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 992*005d3febSMarek Pospisil 993*005d3febSMarek Pospisil /* 994*005d3febSMarek Pospisil * No need to call set_proc_pre_sys(), since 995*005d3febSMarek Pospisil * t_pre_sys is ALWAYS on when audit is 996*005d3febSMarek Pospisil * enabled...due to syscall auditing. 997*005d3febSMarek Pospisil */ 998*005d3febSMarek Pospisil } 999*005d3febSMarek Pospisil } else { 1000*005d3febSMarek Pospisil crfree(cr); 1001*005d3febSMarek Pospisil } 1002*005d3febSMarek Pospisil mutex_exit(&p->p_lock); 1003*005d3febSMarek Pospisil } 1004*005d3febSMarek Pospisil mutex_exit(&pidlock); 1005*005d3febSMarek Pospisil 1006*005d3febSMarek Pospisil return (0); 1007*005d3febSMarek Pospisil } 1008*005d3febSMarek Pospisil 1009*005d3febSMarek Pospisil /* 1010*005d3febSMarek Pospisil * Get the current audit state of the system 1011*005d3febSMarek Pospisil */ 1012*005d3febSMarek Pospisil static int 1013*005d3febSMarek Pospisil getcond(caddr_t data) 1014*005d3febSMarek Pospisil { 1015*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 1016*005d3febSMarek Pospisil 1017*005d3febSMarek Pospisil if (copyout(&(kctx->auk_auditstate), data, sizeof (int))) 1018*005d3febSMarek Pospisil return (EFAULT); 1019*005d3febSMarek Pospisil 1020*005d3febSMarek Pospisil return (0); 1021*005d3febSMarek Pospisil } 1022*005d3febSMarek Pospisil 1023*005d3febSMarek Pospisil /* 1024*005d3febSMarek Pospisil * Set the current audit state of the system to on (AUC_AUDITING) or 1025*005d3febSMarek Pospisil * off (AUC_NOAUDIT). 1026*005d3febSMarek Pospisil */ 1027*005d3febSMarek Pospisil /* ARGSUSED */ 1028*005d3febSMarek Pospisil static int 1029*005d3febSMarek Pospisil setcond(caddr_t data) 1030*005d3febSMarek Pospisil { 1031*005d3febSMarek Pospisil int auditstate; 1032*005d3febSMarek Pospisil au_kcontext_t *kctx; 1033*005d3febSMarek Pospisil 1034*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc))) 1035*005d3febSMarek Pospisil return (EINVAL); 1036*005d3febSMarek Pospisil 1037*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 1038*005d3febSMarek Pospisil 1039*005d3febSMarek Pospisil if (copyin(data, &auditstate, sizeof (int))) 1040*005d3febSMarek Pospisil return (EFAULT); 1041*005d3febSMarek Pospisil 1042*005d3febSMarek Pospisil switch (auditstate) { 1043*005d3febSMarek Pospisil case AUC_AUDITING: /* Turn auditing on */ 1044*005d3febSMarek Pospisil if (audit_active == C2AUDIT_UNLOADED) 1045*005d3febSMarek Pospisil audit_init_module(); 1046*005d3febSMarek Pospisil kctx->auk_auditstate = AUC_AUDITING; 1047*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc)) 1048*005d3febSMarek Pospisil set_all_zone_usr_proc_sys(ALL_ZONES); 1049*005d3febSMarek Pospisil else 1050*005d3febSMarek Pospisil set_all_zone_usr_proc_sys(curproc->p_zone->zone_id); 1051*005d3febSMarek Pospisil break; 1052*005d3febSMarek Pospisil 1053*005d3febSMarek Pospisil case AUC_NOAUDIT: /* Turn auditing off */ 1054*005d3febSMarek Pospisil if (kctx->auk_auditstate == AUC_NOAUDIT) 1055*005d3febSMarek Pospisil break; 1056*005d3febSMarek Pospisil kctx->auk_auditstate = AUC_NOAUDIT; 1057*005d3febSMarek Pospisil 1058*005d3febSMarek Pospisil /* clear out the audit queue */ 1059*005d3febSMarek Pospisil 1060*005d3febSMarek Pospisil mutex_enter(&(kctx->auk_queue.lock)); 1061*005d3febSMarek Pospisil if (kctx->auk_queue.wt_block) 1062*005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.write_cv)); 1063*005d3febSMarek Pospisil 1064*005d3febSMarek Pospisil /* unblock au_output_thread */ 1065*005d3febSMarek Pospisil cv_broadcast(&(kctx->auk_queue.read_cv)); 1066*005d3febSMarek Pospisil 1067*005d3febSMarek Pospisil mutex_exit(&(kctx->auk_queue.lock)); 1068*005d3febSMarek Pospisil break; 1069*005d3febSMarek Pospisil 1070*005d3febSMarek Pospisil default: 1071*005d3febSMarek Pospisil return (EINVAL); 1072*005d3febSMarek Pospisil } 1073*005d3febSMarek Pospisil 1074*005d3febSMarek Pospisil return (0); 1075*005d3febSMarek Pospisil } 1076*005d3febSMarek Pospisil 1077*005d3febSMarek Pospisil static int 1078*005d3febSMarek Pospisil getclass(caddr_t data) 1079*005d3febSMarek Pospisil { 1080*005d3febSMarek Pospisil au_evclass_map_t event; 1081*005d3febSMarek Pospisil au_kcontext_t *kctx = GET_KCTX_PZ; 1082*005d3febSMarek Pospisil 1083*005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t))) 1084*005d3febSMarek Pospisil return (EFAULT); 1085*005d3febSMarek Pospisil 1086*005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS) 1087*005d3febSMarek Pospisil return (EINVAL); 1088*005d3febSMarek Pospisil 1089*005d3febSMarek Pospisil event.ec_class = kctx->auk_ets[event.ec_number]; 1090*005d3febSMarek Pospisil 1091*005d3febSMarek Pospisil if (copyout(&event, data, sizeof (au_evclass_map_t))) 1092*005d3febSMarek Pospisil return (EFAULT); 1093*005d3febSMarek Pospisil 1094*005d3febSMarek Pospisil return (0); 1095*005d3febSMarek Pospisil } 1096*005d3febSMarek Pospisil 1097*005d3febSMarek Pospisil static int 1098*005d3febSMarek Pospisil setclass(caddr_t data) 1099*005d3febSMarek Pospisil { 1100*005d3febSMarek Pospisil au_evclass_map_t event; 1101*005d3febSMarek Pospisil au_kcontext_t *kctx; 1102*005d3febSMarek Pospisil 1103*005d3febSMarek Pospisil if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc)) 1104*005d3febSMarek Pospisil return (EINVAL); 1105*005d3febSMarek Pospisil 1106*005d3febSMarek Pospisil kctx = GET_KCTX_NGZ; 1107*005d3febSMarek Pospisil 1108*005d3febSMarek Pospisil if (copyin(data, &event, sizeof (au_evclass_map_t))) 1109*005d3febSMarek Pospisil return (EFAULT); 1110*005d3febSMarek Pospisil 1111*005d3febSMarek Pospisil if (event.ec_number > MAX_KEVENTS) 1112*005d3febSMarek Pospisil return (EINVAL); 1113*005d3febSMarek Pospisil 1114*005d3febSMarek Pospisil kctx->auk_ets[event.ec_number] = event.ec_class; 1115*005d3febSMarek Pospisil 1116*005d3febSMarek Pospisil return (0); 1117*005d3febSMarek Pospisil } 1118*005d3febSMarek Pospisil 1119*005d3febSMarek Pospisil static int 1120*005d3febSMarek Pospisil getpinfo(caddr_t data) 1121*005d3febSMarek Pospisil { 1122*005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo); 1123*005d3febSMarek Pospisil proc_t *proc; 1124*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 1125*005d3febSMarek Pospisil model_t model; 1126*005d3febSMarek Pospisil cred_t *cr, *newcred; 1127*005d3febSMarek Pospisil 1128*005d3febSMarek Pospisil model = get_udatamodel(); 1129*005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1130*005d3febSMarek Pospisil 1131*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1132*005d3febSMarek Pospisil return (EFAULT); 1133*005d3febSMarek Pospisil 1134*005d3febSMarek Pospisil newcred = cralloc(); 1135*005d3febSMarek Pospisil 1136*005d3febSMarek Pospisil mutex_enter(&pidlock); 1137*005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1138*005d3febSMarek Pospisil mutex_exit(&pidlock); 1139*005d3febSMarek Pospisil crfree(newcred); 1140*005d3febSMarek Pospisil return (ESRCH); /* no such process */ 1141*005d3febSMarek Pospisil } 1142*005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1143*005d3febSMarek Pospisil mutex_exit(&pidlock); 1144*005d3febSMarek Pospisil 1145*005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */ 1146*005d3febSMarek Pospisil 1147*005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1148*005d3febSMarek Pospisil crhold(cr = proc->p_cred); 1149*005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1150*005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1151*005d3febSMarek Pospisil 1152*005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 1153*005d3febSMarek Pospisil if (ainfo == NULL) { 1154*005d3febSMarek Pospisil crfree(cr); 1155*005d3febSMarek Pospisil return (EINVAL); 1156*005d3febSMarek Pospisil } 1157*005d3febSMarek Pospisil 1158*005d3febSMarek Pospisil /* designated process has an ipv6 address? */ 1159*005d3febSMarek Pospisil if (ainfo->ai_termid.at_type == AU_IPv6) { 1160*005d3febSMarek Pospisil crfree(cr); 1161*005d3febSMarek Pospisil return (EOVERFLOW); 1162*005d3febSMarek Pospisil } 1163*005d3febSMarek Pospisil 1164*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid); 1165*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid); 1166*005d3febSMarek Pospisil #ifdef _LP64 1167*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 1168*005d3febSMarek Pospisil dev32_t dev; 1169*005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 1170*005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 1171*005d3febSMarek Pospisil crfree(cr); 1172*005d3febSMarek Pospisil return (EOVERFLOW); 1173*005d3febSMarek Pospisil } 1174*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, dev); 1175*005d3febSMarek Pospisil } else 1176*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port); 1177*005d3febSMarek Pospisil #else 1178*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port); 1179*005d3febSMarek Pospisil #endif 1180*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]); 1181*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask); 1182*005d3febSMarek Pospisil 1183*005d3febSMarek Pospisil crfree(cr); 1184*005d3febSMarek Pospisil 1185*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo))) 1186*005d3febSMarek Pospisil return (EFAULT); 1187*005d3febSMarek Pospisil 1188*005d3febSMarek Pospisil return (0); 1189*005d3febSMarek Pospisil } 1190*005d3febSMarek Pospisil 1191*005d3febSMarek Pospisil static int 1192*005d3febSMarek Pospisil getpinfo_addr(caddr_t data, int len) 1193*005d3febSMarek Pospisil { 1194*005d3febSMarek Pospisil STRUCT_DECL(auditpinfo_addr, apinfo); 1195*005d3febSMarek Pospisil proc_t *proc; 1196*005d3febSMarek Pospisil const auditinfo_addr_t *ainfo; 1197*005d3febSMarek Pospisil model_t model; 1198*005d3febSMarek Pospisil cred_t *cr, *newcred; 1199*005d3febSMarek Pospisil 1200*005d3febSMarek Pospisil model = get_udatamodel(); 1201*005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1202*005d3febSMarek Pospisil 1203*005d3febSMarek Pospisil if (len < STRUCT_SIZE(apinfo)) 1204*005d3febSMarek Pospisil return (EOVERFLOW); 1205*005d3febSMarek Pospisil 1206*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1207*005d3febSMarek Pospisil return (EFAULT); 1208*005d3febSMarek Pospisil 1209*005d3febSMarek Pospisil newcred = cralloc(); 1210*005d3febSMarek Pospisil 1211*005d3febSMarek Pospisil mutex_enter(&pidlock); 1212*005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1213*005d3febSMarek Pospisil mutex_exit(&pidlock); 1214*005d3febSMarek Pospisil crfree(newcred); 1215*005d3febSMarek Pospisil return (ESRCH); 1216*005d3febSMarek Pospisil } 1217*005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1218*005d3febSMarek Pospisil mutex_exit(&pidlock); 1219*005d3febSMarek Pospisil 1220*005d3febSMarek Pospisil audit_update_context(proc, newcred); /* make sure it's up-to-date */ 1221*005d3febSMarek Pospisil 1222*005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1223*005d3febSMarek Pospisil crhold(cr = proc->p_cred); 1224*005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1225*005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1226*005d3febSMarek Pospisil 1227*005d3febSMarek Pospisil ainfo = crgetauinfo(cr); 1228*005d3febSMarek Pospisil if (ainfo == NULL) { 1229*005d3febSMarek Pospisil crfree(cr); 1230*005d3febSMarek Pospisil return (EINVAL); 1231*005d3febSMarek Pospisil } 1232*005d3febSMarek Pospisil 1233*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid); 1234*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid); 1235*005d3febSMarek Pospisil #ifdef _LP64 1236*005d3febSMarek Pospisil if (model == DATAMODEL_ILP32) { 1237*005d3febSMarek Pospisil dev32_t dev; 1238*005d3febSMarek Pospisil /* convert internal 64 bit form to 32 bit version */ 1239*005d3febSMarek Pospisil if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) { 1240*005d3febSMarek Pospisil crfree(cr); 1241*005d3febSMarek Pospisil return (EOVERFLOW); 1242*005d3febSMarek Pospisil } 1243*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, dev); 1244*005d3febSMarek Pospisil } else 1245*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, 1246*005d3febSMarek Pospisil ainfo->ai_termid.at_port); 1247*005d3febSMarek Pospisil #else 1248*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port); 1249*005d3febSMarek Pospisil #endif 1250*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type); 1251*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]); 1252*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]); 1253*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]); 1254*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]); 1255*005d3febSMarek Pospisil STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask); 1256*005d3febSMarek Pospisil 1257*005d3febSMarek Pospisil crfree(cr); 1258*005d3febSMarek Pospisil 1259*005d3febSMarek Pospisil if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo))) 1260*005d3febSMarek Pospisil return (EFAULT); 1261*005d3febSMarek Pospisil 1262*005d3febSMarek Pospisil return (0); 1263*005d3febSMarek Pospisil } 1264*005d3febSMarek Pospisil 1265*005d3febSMarek Pospisil static int 1266*005d3febSMarek Pospisil setpmask(caddr_t data) 1267*005d3febSMarek Pospisil { 1268*005d3febSMarek Pospisil STRUCT_DECL(auditpinfo, apinfo); 1269*005d3febSMarek Pospisil proc_t *proc; 1270*005d3febSMarek Pospisil cred_t *newcred; 1271*005d3febSMarek Pospisil auditinfo_addr_t *ainfo; 1272*005d3febSMarek Pospisil struct p_audit_data *pad; 1273*005d3febSMarek Pospisil 1274*005d3febSMarek Pospisil model_t model; 1275*005d3febSMarek Pospisil 1276*005d3febSMarek Pospisil model = get_udatamodel(); 1277*005d3febSMarek Pospisil STRUCT_INIT(apinfo, model); 1278*005d3febSMarek Pospisil 1279*005d3febSMarek Pospisil if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo))) 1280*005d3febSMarek Pospisil return (EFAULT); 1281*005d3febSMarek Pospisil 1282*005d3febSMarek Pospisil mutex_enter(&pidlock); 1283*005d3febSMarek Pospisil if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) { 1284*005d3febSMarek Pospisil mutex_exit(&pidlock); 1285*005d3febSMarek Pospisil return (ESRCH); 1286*005d3febSMarek Pospisil } 1287*005d3febSMarek Pospisil mutex_enter(&proc->p_lock); /* so process doesn't go away */ 1288*005d3febSMarek Pospisil mutex_exit(&pidlock); 1289*005d3febSMarek Pospisil 1290*005d3febSMarek Pospisil newcred = cralloc(); 1291*005d3febSMarek Pospisil if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) { 1292*005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1293*005d3febSMarek Pospisil crfree(newcred); 1294*005d3febSMarek Pospisil return (EINVAL); 1295*005d3febSMarek Pospisil } 1296*005d3febSMarek Pospisil 1297*005d3febSMarek Pospisil mutex_enter(&proc->p_crlock); 1298*005d3febSMarek Pospisil crcopy_to(proc->p_cred, newcred); 1299*005d3febSMarek Pospisil proc->p_cred = newcred; 1300*005d3febSMarek Pospisil 1301*005d3febSMarek Pospisil ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask); 1302*005d3febSMarek Pospisil 1303*005d3febSMarek Pospisil /* 1304*005d3febSMarek Pospisil * Unlock. No need to broadcast changes via set_proc_pre_sys(), 1305*005d3febSMarek Pospisil * since t_pre_sys is ALWAYS on when audit is enabled... due to 1306*005d3febSMarek Pospisil * syscall auditing. 1307*005d3febSMarek Pospisil */ 1308*005d3febSMarek Pospisil crfree(newcred); 1309*005d3febSMarek Pospisil mutex_exit(&proc->p_crlock); 1310*005d3febSMarek Pospisil 1311*005d3febSMarek Pospisil /* Reset flag for any previous pending mask change; this supercedes */ 1312*005d3febSMarek Pospisil pad = P2A(proc); 1313*005d3febSMarek Pospisil ASSERT(pad != NULL); 1314*005d3febSMarek Pospisil mutex_enter(&(pad->pad_lock)); 1315*005d3febSMarek Pospisil pad->pad_flags &= ~PAD_SETMASK; 1316*005d3febSMarek Pospisil mutex_exit(&(pad->pad_lock)); 1317*005d3febSMarek Pospisil 1318*005d3febSMarek Pospisil mutex_exit(&proc->p_lock); 1319*005d3febSMarek Pospisil 1320*005d3febSMarek Pospisil return (0); 1321*005d3febSMarek Pospisil } 1322*005d3febSMarek Pospisil 1323*005d3febSMarek Pospisil /* 1324*005d3febSMarek Pospisil * The out of control system call 1325*005d3febSMarek Pospisil * This is audit kitchen sink aka auditadm, aka auditon 1326*005d3febSMarek Pospisil */ 1327*005d3febSMarek Pospisil int 1328*005d3febSMarek Pospisil auditctl( 1329*005d3febSMarek Pospisil int cmd, 1330*005d3febSMarek Pospisil caddr_t data, 1331*005d3febSMarek Pospisil int length) 1332*005d3febSMarek Pospisil { 1333*005d3febSMarek Pospisil int result; 1334*005d3febSMarek Pospisil 1335*005d3febSMarek Pospisil switch (cmd) { 1336*005d3febSMarek Pospisil case A_GETCOND: 1337*005d3febSMarek Pospisil case A_GETCAR: 1338*005d3febSMarek Pospisil case A_GETCLASS: 1339*005d3febSMarek Pospisil case A_GETCWD: 1340*005d3febSMarek Pospisil case A_GETKAUDIT: 1341*005d3febSMarek Pospisil case A_GETKMASK: 1342*005d3febSMarek Pospisil case A_GETPINFO: 1343*005d3febSMarek Pospisil case A_GETPINFO_ADDR: 1344*005d3febSMarek Pospisil case A_GETPOLICY: 1345*005d3febSMarek Pospisil case A_GETQCTRL: 1346*005d3febSMarek Pospisil case A_GETSTAT: 1347*005d3febSMarek Pospisil if (secpolicy_audit_getattr(CRED()) != 0) 1348*005d3febSMarek Pospisil return (EPERM); 1349*005d3febSMarek Pospisil break; 1350*005d3febSMarek Pospisil default: 1351*005d3febSMarek Pospisil if (secpolicy_audit_config(CRED()) != 0) 1352*005d3febSMarek Pospisil return (EPERM); 1353*005d3febSMarek Pospisil break; 1354*005d3febSMarek Pospisil } 1355*005d3febSMarek Pospisil 1356*005d3febSMarek Pospisil switch (cmd) { 1357*005d3febSMarek Pospisil case A_GETPOLICY: 1358*005d3febSMarek Pospisil result = getpolicy(data); 1359*005d3febSMarek Pospisil break; 1360*005d3febSMarek Pospisil case A_SETPOLICY: 1361*005d3febSMarek Pospisil result = setpolicy(data); 1362*005d3febSMarek Pospisil break; 1363*005d3febSMarek Pospisil case A_GETKMASK: 1364*005d3febSMarek Pospisil result = getkmask(data); 1365*005d3febSMarek Pospisil break; 1366*005d3febSMarek Pospisil case A_SETKMASK: 1367*005d3febSMarek Pospisil result = setkmask(data); 1368*005d3febSMarek Pospisil break; 1369*005d3febSMarek Pospisil case A_GETKAUDIT: 1370*005d3febSMarek Pospisil result = getkaudit(data, length); 1371*005d3febSMarek Pospisil break; 1372*005d3febSMarek Pospisil case A_SETKAUDIT: 1373*005d3febSMarek Pospisil result = setkaudit(data, length); 1374*005d3febSMarek Pospisil break; 1375*005d3febSMarek Pospisil case A_GETQCTRL: 1376*005d3febSMarek Pospisil result = getqctrl(data); 1377*005d3febSMarek Pospisil break; 1378*005d3febSMarek Pospisil case A_SETQCTRL: 1379*005d3febSMarek Pospisil result = setqctrl(data); 1380*005d3febSMarek Pospisil break; 1381*005d3febSMarek Pospisil case A_GETCWD: 1382*005d3febSMarek Pospisil result = getcwd(data, length); 1383*005d3febSMarek Pospisil break; 1384*005d3febSMarek Pospisil case A_GETCAR: 1385*005d3febSMarek Pospisil result = getcar(data, length); 1386*005d3febSMarek Pospisil break; 1387*005d3febSMarek Pospisil case A_GETSTAT: 1388*005d3febSMarek Pospisil result = getstat(data); 1389*005d3febSMarek Pospisil break; 1390*005d3febSMarek Pospisil case A_SETSTAT: 1391*005d3febSMarek Pospisil result = setstat(data); 1392*005d3febSMarek Pospisil break; 1393*005d3febSMarek Pospisil case A_SETUMASK: 1394*005d3febSMarek Pospisil result = setumask(data); 1395*005d3febSMarek Pospisil break; 1396*005d3febSMarek Pospisil case A_SETSMASK: 1397*005d3febSMarek Pospisil result = setsmask(data); 1398*005d3febSMarek Pospisil break; 1399*005d3febSMarek Pospisil case A_GETCOND: 1400*005d3febSMarek Pospisil result = getcond(data); 1401*005d3febSMarek Pospisil break; 1402*005d3febSMarek Pospisil case A_SETCOND: 1403*005d3febSMarek Pospisil result = setcond(data); 1404*005d3febSMarek Pospisil break; 1405*005d3febSMarek Pospisil case A_GETCLASS: 1406*005d3febSMarek Pospisil result = getclass(data); 1407*005d3febSMarek Pospisil break; 1408*005d3febSMarek Pospisil case A_SETCLASS: 1409*005d3febSMarek Pospisil result = setclass(data); 1410*005d3febSMarek Pospisil break; 1411*005d3febSMarek Pospisil case A_GETPINFO: 1412*005d3febSMarek Pospisil result = getpinfo(data); 1413*005d3febSMarek Pospisil break; 1414*005d3febSMarek Pospisil case A_GETPINFO_ADDR: 1415*005d3febSMarek Pospisil result = getpinfo_addr(data, length); 1416*005d3febSMarek Pospisil break; 1417*005d3febSMarek Pospisil case A_SETPMASK: 1418*005d3febSMarek Pospisil result = setpmask(data); 1419*005d3febSMarek Pospisil break; 1420*005d3febSMarek Pospisil default: 1421*005d3febSMarek Pospisil result = EINVAL; 1422*005d3febSMarek Pospisil break; 1423*005d3febSMarek Pospisil } 1424*005d3febSMarek Pospisil return (result); 14257c478bd9Sstevel@tonic-gate } 1426