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