1 /*- 2 * Copyright (c) 1999-2005 Apple Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include "opt_mac.h" 34 35 #include <sys/param.h> 36 #include <sys/mount.h> 37 #include <sys/namei.h> 38 #include <sys/priv.h> 39 #include <sys/proc.h> 40 #include <sys/sysproto.h> 41 #include <sys/systm.h> 42 #include <sys/vnode.h> 43 #include <sys/jail.h> 44 45 #include <bsm/audit.h> 46 #include <bsm/audit_kevents.h> 47 48 #include <security/audit/audit.h> 49 #include <security/audit/audit_private.h> 50 #include <security/mac/mac_framework.h> 51 52 #ifdef AUDIT 53 54 /* 55 * System call to allow a user space application to submit a BSM audit record 56 * to the kernel for inclusion in the audit log. This function does little 57 * verification on the audit record that is submitted. 58 * 59 * XXXAUDIT: Audit preselection for user records does not currently work, 60 * since we pre-select only based on the AUE_audit event type, not the event 61 * type submitted as part of the user audit data. 62 */ 63 /* ARGSUSED */ 64 int 65 audit(struct thread *td, struct audit_args *uap) 66 { 67 int error; 68 void * rec; 69 struct kaudit_record *ar; 70 71 if (jailed(td->td_ucred)) 72 return (ENOSYS); 73 error = priv_check(td, PRIV_AUDIT_SUBMIT); 74 if (error) 75 return (error); 76 77 if ((uap->length <= 0) || (uap->length > audit_qctrl.aq_bufsz)) 78 return (EINVAL); 79 80 ar = currecord(); 81 82 /* 83 * If there's no current audit record (audit() itself not audited) 84 * commit the user audit record. 85 */ 86 if (ar == NULL) { 87 88 /* 89 * This is not very efficient; we're required to allocate a 90 * complete kernel audit record just so the user record can 91 * tag along. 92 * 93 * XXXAUDIT: Maybe AUE_AUDIT in the system call context and 94 * special pre-select handling? 95 */ 96 td->td_ar = audit_new(AUE_NULL, td); 97 if (td->td_ar == NULL) 98 return (ENOTSUP); 99 ar = td->td_ar; 100 } 101 102 if (uap->length > MAX_AUDIT_RECORD_SIZE) 103 return (EINVAL); 104 105 rec = malloc(uap->length, M_AUDITDATA, M_WAITOK); 106 107 error = copyin(uap->record, rec, uap->length); 108 if (error) 109 goto free_out; 110 111 /* Verify the record. */ 112 if (bsm_rec_verify(rec) == 0) { 113 error = EINVAL; 114 goto free_out; 115 } 116 117 #ifdef MAC 118 error = mac_system_check_audit(td->td_ucred, rec, uap->length); 119 if (error) 120 goto free_out; 121 #endif 122 123 /* 124 * Attach the user audit record to the kernel audit record. Because 125 * this system call is an auditable event, we will write the user 126 * record along with the record for this audit event. 127 * 128 * XXXAUDIT: KASSERT appropriate starting values of k_udata, k_ulen, 129 * k_ar_commit & AR_COMMIT_USER? 130 */ 131 ar->k_udata = rec; 132 ar->k_ulen = uap->length; 133 ar->k_ar_commit |= AR_COMMIT_USER; 134 135 /* 136 * Currently we assume that all preselection has been performed in 137 * userspace. We unconditionally set these masks so that the records 138 * get committed both to the trail and pipe. In the future we will 139 * want to setup kernel based preselection. 140 */ 141 ar->k_ar_commit |= (AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE); 142 return (0); 143 144 free_out: 145 /* 146 * audit_syscall_exit() will free the audit record on the thread even 147 * if we allocated it above. 148 */ 149 free(rec, M_AUDITDATA); 150 return (error); 151 } 152 153 /* 154 * System call to manipulate auditing. 155 */ 156 /* ARGSUSED */ 157 int 158 auditon(struct thread *td, struct auditon_args *uap) 159 { 160 struct ucred *newcred, *oldcred; 161 int error; 162 union auditon_udata udata; 163 struct proc *tp; 164 165 if (jailed(td->td_ucred)) 166 return (ENOSYS); 167 AUDIT_ARG(cmd, uap->cmd); 168 169 #ifdef MAC 170 error = mac_system_check_auditon(td->td_ucred, uap->cmd); 171 if (error) 172 return (error); 173 #endif 174 175 error = priv_check(td, PRIV_AUDIT_CONTROL); 176 if (error) 177 return (error); 178 179 if ((uap->length <= 0) || (uap->length > sizeof(union auditon_udata))) 180 return (EINVAL); 181 182 memset((void *)&udata, 0, sizeof(udata)); 183 184 /* 185 * Some of the GET commands use the arguments too. 186 */ 187 switch (uap->cmd) { 188 case A_SETPOLICY: 189 case A_SETKMASK: 190 case A_SETQCTRL: 191 case A_SETSTAT: 192 case A_SETUMASK: 193 case A_SETSMASK: 194 case A_SETCOND: 195 case A_SETCLASS: 196 case A_SETPMASK: 197 case A_SETFSIZE: 198 case A_SETKAUDIT: 199 case A_GETCLASS: 200 case A_GETPINFO: 201 case A_GETPINFO_ADDR: 202 case A_SENDTRIGGER: 203 error = copyin(uap->data, (void *)&udata, uap->length); 204 if (error) 205 return (error); 206 AUDIT_ARG(auditon, &udata); 207 break; 208 } 209 210 /* 211 * XXXAUDIT: Locking? 212 */ 213 switch (uap->cmd) { 214 case A_GETPOLICY: 215 if (!audit_fail_stop) 216 udata.au_policy |= AUDIT_CNT; 217 if (audit_panic_on_write_fail) 218 udata.au_policy |= AUDIT_AHLT; 219 if (audit_argv) 220 udata.au_policy |= AUDIT_ARGV; 221 if (audit_arge) 222 udata.au_policy |= AUDIT_ARGE; 223 break; 224 225 case A_SETPOLICY: 226 if (udata.au_policy & ~(AUDIT_CNT|AUDIT_AHLT|AUDIT_ARGV| 227 AUDIT_ARGE)) 228 return (EINVAL); 229 /* 230 * XXX - Need to wake up waiters if the policy relaxes? 231 */ 232 audit_fail_stop = ((udata.au_policy & AUDIT_CNT) == 0); 233 audit_panic_on_write_fail = (udata.au_policy & AUDIT_AHLT); 234 audit_argv = (udata.au_policy & AUDIT_ARGV); 235 audit_arge = (udata.au_policy & AUDIT_ARGE); 236 break; 237 238 case A_GETKMASK: 239 udata.au_mask = audit_nae_mask; 240 break; 241 242 case A_SETKMASK: 243 audit_nae_mask = udata.au_mask; 244 break; 245 246 case A_GETQCTRL: 247 udata.au_qctrl = audit_qctrl; 248 break; 249 250 case A_SETQCTRL: 251 if ((udata.au_qctrl.aq_hiwater > AQ_MAXHIGH) || 252 (udata.au_qctrl.aq_lowater >= udata.au_qctrl.aq_hiwater) || 253 (udata.au_qctrl.aq_bufsz > AQ_MAXBUFSZ) || 254 (udata.au_qctrl.aq_minfree < 0) || 255 (udata.au_qctrl.aq_minfree > 100)) 256 return (EINVAL); 257 258 audit_qctrl = udata.au_qctrl; 259 /* XXX The queue delay value isn't used with the kernel. */ 260 audit_qctrl.aq_delay = -1; 261 break; 262 263 case A_GETCWD: 264 return (ENOSYS); 265 break; 266 267 case A_GETCAR: 268 return (ENOSYS); 269 break; 270 271 case A_GETSTAT: 272 return (ENOSYS); 273 break; 274 275 case A_SETSTAT: 276 return (ENOSYS); 277 break; 278 279 case A_SETUMASK: 280 return (ENOSYS); 281 break; 282 283 case A_SETSMASK: 284 return (ENOSYS); 285 break; 286 287 case A_GETCOND: 288 if (audit_enabled && !audit_suspended) 289 udata.au_cond = AUC_AUDITING; 290 else 291 udata.au_cond = AUC_NOAUDIT; 292 break; 293 294 case A_SETCOND: 295 if (udata.au_cond == AUC_NOAUDIT) 296 audit_suspended = 1; 297 if (udata.au_cond == AUC_AUDITING) 298 audit_suspended = 0; 299 if (udata.au_cond == AUC_DISABLED) { 300 audit_suspended = 1; 301 audit_shutdown(NULL, 0); 302 } 303 break; 304 305 case A_GETCLASS: 306 udata.au_evclass.ec_class = au_event_class( 307 udata.au_evclass.ec_number); 308 break; 309 310 case A_SETCLASS: 311 au_evclassmap_insert(udata.au_evclass.ec_number, 312 udata.au_evclass.ec_class); 313 break; 314 315 case A_GETPINFO: 316 if (udata.au_aupinfo.ap_pid < 1) 317 return (EINVAL); 318 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) 319 return (EINVAL); 320 if (p_cansee(td, tp) != 0) { 321 PROC_UNLOCK(tp); 322 return (EINVAL); 323 } 324 if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) { 325 PROC_UNLOCK(tp); 326 return (EINVAL); 327 } 328 udata.au_aupinfo.ap_auid = 329 tp->p_ucred->cr_audit.ai_auid; 330 udata.au_aupinfo.ap_mask.am_success = 331 tp->p_ucred->cr_audit.ai_mask.am_success; 332 udata.au_aupinfo.ap_mask.am_failure = 333 tp->p_ucred->cr_audit.ai_mask.am_failure; 334 udata.au_aupinfo.ap_termid.machine = 335 tp->p_ucred->cr_audit.ai_termid.at_addr[0]; 336 udata.au_aupinfo.ap_termid.port = 337 (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port; 338 udata.au_aupinfo.ap_asid = 339 tp->p_ucred->cr_audit.ai_asid; 340 PROC_UNLOCK(tp); 341 break; 342 343 case A_SETPMASK: 344 if (udata.au_aupinfo.ap_pid < 1) 345 return (EINVAL); 346 newcred = crget(); 347 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) { 348 crfree(newcred); 349 return (EINVAL); 350 } 351 if (p_cansee(td, tp) != 0) { 352 PROC_UNLOCK(tp); 353 crfree(newcred); 354 return (EINVAL); 355 } 356 oldcred = tp->p_ucred; 357 crcopy(newcred, oldcred); 358 newcred->cr_audit.ai_mask.am_success = 359 udata.au_aupinfo.ap_mask.am_success; 360 newcred->cr_audit.ai_mask.am_failure = 361 udata.au_aupinfo.ap_mask.am_failure; 362 td->td_proc->p_ucred = newcred; 363 PROC_UNLOCK(tp); 364 crfree(oldcred); 365 break; 366 367 case A_SETFSIZE: 368 if ((udata.au_fstat.af_filesz != 0) && 369 (udata.au_fstat.af_filesz < MIN_AUDIT_FILE_SIZE)) 370 return (EINVAL); 371 audit_fstat.af_filesz = udata.au_fstat.af_filesz; 372 break; 373 374 case A_GETFSIZE: 375 udata.au_fstat.af_filesz = audit_fstat.af_filesz; 376 udata.au_fstat.af_currsz = audit_fstat.af_currsz; 377 break; 378 379 case A_GETPINFO_ADDR: 380 if (udata.au_aupinfo_addr.ap_pid < 1) 381 return (EINVAL); 382 if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL) 383 return (EINVAL); 384 udata.au_aupinfo_addr.ap_auid = 385 tp->p_ucred->cr_audit.ai_auid; 386 udata.au_aupinfo_addr.ap_mask.am_success = 387 tp->p_ucred->cr_audit.ai_mask.am_success; 388 udata.au_aupinfo_addr.ap_mask.am_failure = 389 tp->p_ucred->cr_audit.ai_mask.am_failure; 390 udata.au_aupinfo_addr.ap_termid = 391 tp->p_ucred->cr_audit.ai_termid; 392 udata.au_aupinfo_addr.ap_asid = 393 tp->p_ucred->cr_audit.ai_asid; 394 PROC_UNLOCK(tp); 395 break; 396 397 case A_GETKAUDIT: 398 return (ENOSYS); 399 break; 400 401 case A_SETKAUDIT: 402 return (ENOSYS); 403 break; 404 405 case A_SENDTRIGGER: 406 if ((udata.au_trigger < AUDIT_TRIGGER_MIN) || 407 (udata.au_trigger > AUDIT_TRIGGER_MAX)) 408 return (EINVAL); 409 return (audit_send_trigger(udata.au_trigger)); 410 411 default: 412 return (EINVAL); 413 } 414 415 /* 416 * Copy data back to userspace for the GET comands. 417 */ 418 switch (uap->cmd) { 419 case A_GETPOLICY: 420 case A_GETKMASK: 421 case A_GETQCTRL: 422 case A_GETCWD: 423 case A_GETCAR: 424 case A_GETSTAT: 425 case A_GETCOND: 426 case A_GETCLASS: 427 case A_GETPINFO: 428 case A_GETFSIZE: 429 case A_GETPINFO_ADDR: 430 case A_GETKAUDIT: 431 error = copyout((void *)&udata, uap->data, uap->length); 432 if (error) 433 return (error); 434 break; 435 } 436 437 return (0); 438 } 439 440 /* 441 * System calls to manage the user audit information. 442 */ 443 /* ARGSUSED */ 444 int 445 getauid(struct thread *td, struct getauid_args *uap) 446 { 447 int error; 448 449 if (jailed(td->td_ucred)) 450 return (ENOSYS); 451 error = priv_check(td, PRIV_AUDIT_GETAUDIT); 452 if (error) 453 return (error); 454 return (copyout(&td->td_ucred->cr_audit.ai_auid, uap->auid, 455 sizeof(td->td_ucred->cr_audit.ai_auid))); 456 } 457 458 /* ARGSUSED */ 459 int 460 setauid(struct thread *td, struct setauid_args *uap) 461 { 462 struct ucred *newcred, *oldcred; 463 au_id_t id; 464 int error; 465 466 if (jailed(td->td_ucred)) 467 return (ENOSYS); 468 error = copyin(uap->auid, &id, sizeof(id)); 469 if (error) 470 return (error); 471 audit_arg_auid(id); 472 newcred = crget(); 473 PROC_LOCK(td->td_proc); 474 oldcred = td->td_proc->p_ucred; 475 crcopy(newcred, oldcred); 476 #ifdef MAC 477 error = mac_proc_check_setauid(oldcred, id); 478 if (error) 479 goto fail; 480 #endif 481 error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0); 482 if (error) 483 goto fail; 484 newcred->cr_audit.ai_auid = id; 485 td->td_proc->p_ucred = newcred; 486 PROC_UNLOCK(td->td_proc); 487 crfree(oldcred); 488 return (0); 489 fail: 490 PROC_UNLOCK(td->td_proc); 491 crfree(newcred); 492 return (error); 493 } 494 495 /* 496 * System calls to get and set process audit information. 497 */ 498 /* ARGSUSED */ 499 int 500 getaudit(struct thread *td, struct getaudit_args *uap) 501 { 502 struct auditinfo ai; 503 int error; 504 505 if (jailed(td->td_ucred)) 506 return (ENOSYS); 507 error = priv_check(td, PRIV_AUDIT_GETAUDIT); 508 if (error) 509 return (error); 510 if (td->td_ucred->cr_audit.ai_termid.at_type == AU_IPv6) 511 return (E2BIG); 512 bzero(&ai, sizeof(ai)); 513 ai.ai_auid = td->td_ucred->cr_audit.ai_auid; 514 ai.ai_mask = td->td_ucred->cr_audit.ai_mask; 515 ai.ai_asid = td->td_ucred->cr_audit.ai_asid; 516 ai.ai_termid.machine = td->td_ucred->cr_audit.ai_termid.at_addr[0]; 517 ai.ai_termid.port = td->td_ucred->cr_audit.ai_termid.at_port; 518 return (copyout(&ai, uap->auditinfo, sizeof(ai))); 519 } 520 521 /* ARGSUSED */ 522 int 523 setaudit(struct thread *td, struct setaudit_args *uap) 524 { 525 struct ucred *newcred, *oldcred; 526 struct auditinfo ai; 527 int error; 528 529 if (jailed(td->td_ucred)) 530 return (ENOSYS); 531 error = copyin(uap->auditinfo, &ai, sizeof(ai)); 532 if (error) 533 return (error); 534 audit_arg_auditinfo(&ai); 535 newcred = crget(); 536 PROC_LOCK(td->td_proc); 537 oldcred = td->td_proc->p_ucred; 538 crcopy(newcred, oldcred); 539 #ifdef MAC 540 error = mac_proc_check_setaudit(oldcred, &ai); 541 if (error) 542 goto fail; 543 #endif 544 error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0); 545 if (error) 546 goto fail; 547 bzero(&newcred->cr_audit, sizeof(newcred->cr_audit)); 548 newcred->cr_audit.ai_auid = ai.ai_auid; 549 newcred->cr_audit.ai_mask = ai.ai_mask; 550 newcred->cr_audit.ai_asid = ai.ai_asid; 551 newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine; 552 newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port; 553 newcred->cr_audit.ai_termid.at_type = AU_IPv4; 554 td->td_proc->p_ucred = newcred; 555 PROC_UNLOCK(td->td_proc); 556 crfree(oldcred); 557 return (0); 558 fail: 559 PROC_UNLOCK(td->td_proc); 560 crfree(newcred); 561 return (error); 562 } 563 564 /* ARGSUSED */ 565 int 566 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 567 { 568 int error; 569 570 if (jailed(td->td_ucred)) 571 return (ENOSYS); 572 if (uap->length < sizeof(*uap->auditinfo_addr)) 573 return (EOVERFLOW); 574 error = priv_check(td, PRIV_AUDIT_GETAUDIT); 575 if (error) 576 return (error); 577 return (copyout(&td->td_ucred->cr_audit, uap->auditinfo_addr, 578 sizeof(*uap->auditinfo_addr))); 579 } 580 581 /* ARGSUSED */ 582 int 583 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 584 { 585 struct ucred *newcred, *oldcred; 586 struct auditinfo_addr aia; 587 int error; 588 589 if (jailed(td->td_ucred)) 590 return (ENOSYS); 591 error = copyin(uap->auditinfo_addr, &aia, sizeof(aia)); 592 if (error) 593 return (error); 594 audit_arg_auditinfo_addr(&aia); 595 if (aia.ai_termid.at_type != AU_IPv6 && 596 aia.ai_termid.at_type != AU_IPv4) 597 return (EINVAL); 598 newcred = crget(); 599 PROC_LOCK(td->td_proc); 600 oldcred = td->td_proc->p_ucred; 601 crcopy(newcred, oldcred); 602 #ifdef MAC 603 error = mac_proc_check_setaudit_addr(oldcred, &aia); 604 if (error) 605 goto fail; 606 #endif 607 error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0); 608 if (error) 609 goto fail; 610 newcred->cr_audit = aia; 611 td->td_proc->p_ucred = newcred; 612 PROC_UNLOCK(td->td_proc); 613 crfree(oldcred); 614 return (0); 615 fail: 616 PROC_UNLOCK(td->td_proc); 617 crfree(newcred); 618 return (error); 619 } 620 621 /* 622 * Syscall to manage audit files. 623 */ 624 /* ARGSUSED */ 625 int 626 auditctl(struct thread *td, struct auditctl_args *uap) 627 { 628 struct nameidata nd; 629 struct ucred *cred; 630 struct vnode *vp; 631 int error = 0; 632 int flags, vfslocked; 633 634 if (jailed(td->td_ucred)) 635 return (ENOSYS); 636 error = priv_check(td, PRIV_AUDIT_CONTROL); 637 if (error) 638 return (error); 639 640 vp = NULL; 641 cred = NULL; 642 643 /* 644 * If a path is specified, open the replacement vnode, perform 645 * validity checks, and grab another reference to the current 646 * credential. 647 * 648 * On Darwin, a NULL path argument is also used to disable audit. 649 */ 650 if (uap->path == NULL) 651 return (EINVAL); 652 653 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 654 UIO_USERSPACE, uap->path, td); 655 flags = AUDIT_OPEN_FLAGS; 656 error = vn_open(&nd, &flags, 0, NULL); 657 if (error) 658 return (error); 659 vfslocked = NDHASGIANT(&nd); 660 vp = nd.ni_vp; 661 #ifdef MAC 662 error = mac_system_check_auditctl(td->td_ucred, vp); 663 VOP_UNLOCK(vp, 0); 664 if (error) { 665 vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); 666 VFS_UNLOCK_GIANT(vfslocked); 667 return (error); 668 } 669 #else 670 VOP_UNLOCK(vp, 0); 671 #endif 672 NDFREE(&nd, NDF_ONLY_PNBUF); 673 if (vp->v_type != VREG) { 674 vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); 675 VFS_UNLOCK_GIANT(vfslocked); 676 return (EINVAL); 677 } 678 VFS_UNLOCK_GIANT(vfslocked); 679 cred = td->td_ucred; 680 crhold(cred); 681 682 /* 683 * XXXAUDIT: Should audit_suspended actually be cleared by 684 * audit_worker? 685 */ 686 audit_suspended = 0; 687 688 audit_rotate_vnode(cred, vp); 689 690 return (error); 691 } 692 693 #else /* !AUDIT */ 694 695 int 696 audit(struct thread *td, struct audit_args *uap) 697 { 698 699 return (ENOSYS); 700 } 701 702 int 703 auditon(struct thread *td, struct auditon_args *uap) 704 { 705 706 return (ENOSYS); 707 } 708 709 int 710 getauid(struct thread *td, struct getauid_args *uap) 711 { 712 713 return (ENOSYS); 714 } 715 716 int 717 setauid(struct thread *td, struct setauid_args *uap) 718 { 719 720 return (ENOSYS); 721 } 722 723 int 724 getaudit(struct thread *td, struct getaudit_args *uap) 725 { 726 727 return (ENOSYS); 728 } 729 730 int 731 setaudit(struct thread *td, struct setaudit_args *uap) 732 { 733 734 return (ENOSYS); 735 } 736 737 int 738 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 739 { 740 741 return (ENOSYS); 742 } 743 744 int 745 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 746 { 747 748 return (ENOSYS); 749 } 750 751 int 752 auditctl(struct thread *td, struct auditctl_args *uap) 753 { 754 755 return (ENOSYS); 756 } 757 #endif /* AUDIT */ 758