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