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