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 *cred, *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 (ESRCH); 318 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) 319 return (ESRCH); 320 if ((error = p_cansee(td, tp)) != 0) { 321 PROC_UNLOCK(tp); 322 return (error); 323 } 324 cred = tp->p_ucred; 325 if (cred->cr_audit.ai_termid.at_type == AU_IPv6) { 326 PROC_UNLOCK(tp); 327 return (EINVAL); 328 } 329 udata.au_aupinfo.ap_auid = cred->cr_audit.ai_auid; 330 udata.au_aupinfo.ap_mask.am_success = 331 cred->cr_audit.ai_mask.am_success; 332 udata.au_aupinfo.ap_mask.am_failure = 333 cred->cr_audit.ai_mask.am_failure; 334 udata.au_aupinfo.ap_termid.machine = 335 cred->cr_audit.ai_termid.at_addr[0]; 336 udata.au_aupinfo.ap_termid.port = 337 (dev_t)cred->cr_audit.ai_termid.at_port; 338 udata.au_aupinfo.ap_asid = cred->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 (ESRCH); 345 newcred = crget(); 346 if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) { 347 crfree(newcred); 348 return (ESRCH); 349 } 350 if ((error = p_cansee(td, tp)) != 0) { 351 PROC_UNLOCK(tp); 352 crfree(newcred); 353 return (error); 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 (ESRCH); 381 if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL) 382 return (ESRCH); 383 cred = tp->p_ucred; 384 udata.au_aupinfo_addr.ap_auid = cred->cr_audit.ai_auid; 385 udata.au_aupinfo_addr.ap_mask.am_success = 386 cred->cr_audit.ai_mask.am_success; 387 udata.au_aupinfo_addr.ap_mask.am_failure = 388 cred->cr_audit.ai_mask.am_failure; 389 udata.au_aupinfo_addr.ap_termid = cred->cr_audit.ai_termid; 390 udata.au_aupinfo_addr.ap_asid = cred->cr_audit.ai_asid; 391 PROC_UNLOCK(tp); 392 break; 393 394 case A_GETKAUDIT: 395 audit_get_kinfo(&udata.au_kau_info); 396 break; 397 398 case A_SETKAUDIT: 399 if (udata.au_kau_info.ai_termid.at_type != AU_IPv4 && 400 udata.au_kau_info.ai_termid.at_type != AU_IPv6) 401 return (EINVAL); 402 audit_set_kinfo(&udata.au_kau_info); 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 struct ucred *cred; 504 int error; 505 506 cred = td->td_ucred; 507 if (jailed(cred)) 508 return (ENOSYS); 509 error = priv_check(td, PRIV_AUDIT_GETAUDIT); 510 if (error) 511 return (error); 512 if (cred->cr_audit.ai_termid.at_type == AU_IPv6) 513 return (E2BIG); 514 bzero(&ai, sizeof(ai)); 515 ai.ai_auid = cred->cr_audit.ai_auid; 516 ai.ai_mask = cred->cr_audit.ai_mask; 517 ai.ai_asid = cred->cr_audit.ai_asid; 518 ai.ai_termid.machine = cred->cr_audit.ai_termid.at_addr[0]; 519 ai.ai_termid.port = cred->cr_audit.ai_termid.at_port; 520 return (copyout(&ai, uap->auditinfo, sizeof(ai))); 521 } 522 523 /* ARGSUSED */ 524 int 525 setaudit(struct thread *td, struct setaudit_args *uap) 526 { 527 struct ucred *newcred, *oldcred; 528 struct auditinfo ai; 529 int error; 530 531 if (jailed(td->td_ucred)) 532 return (ENOSYS); 533 error = copyin(uap->auditinfo, &ai, sizeof(ai)); 534 if (error) 535 return (error); 536 audit_arg_auditinfo(&ai); 537 newcred = crget(); 538 PROC_LOCK(td->td_proc); 539 oldcred = td->td_proc->p_ucred; 540 crcopy(newcred, oldcred); 541 #ifdef MAC 542 error = mac_proc_check_setaudit(oldcred, &ai); 543 if (error) 544 goto fail; 545 #endif 546 error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0); 547 if (error) 548 goto fail; 549 bzero(&newcred->cr_audit, sizeof(newcred->cr_audit)); 550 newcred->cr_audit.ai_auid = ai.ai_auid; 551 newcred->cr_audit.ai_mask = ai.ai_mask; 552 newcred->cr_audit.ai_asid = ai.ai_asid; 553 newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine; 554 newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port; 555 newcred->cr_audit.ai_termid.at_type = AU_IPv4; 556 td->td_proc->p_ucred = newcred; 557 PROC_UNLOCK(td->td_proc); 558 crfree(oldcred); 559 return (0); 560 fail: 561 PROC_UNLOCK(td->td_proc); 562 crfree(newcred); 563 return (error); 564 } 565 566 /* ARGSUSED */ 567 int 568 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 569 { 570 int error; 571 572 if (jailed(td->td_ucred)) 573 return (ENOSYS); 574 if (uap->length < sizeof(*uap->auditinfo_addr)) 575 return (EOVERFLOW); 576 error = priv_check(td, PRIV_AUDIT_GETAUDIT); 577 if (error) 578 return (error); 579 return (copyout(&td->td_ucred->cr_audit, uap->auditinfo_addr, 580 sizeof(*uap->auditinfo_addr))); 581 } 582 583 /* ARGSUSED */ 584 int 585 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 586 { 587 struct ucred *newcred, *oldcred; 588 struct auditinfo_addr aia; 589 int error; 590 591 if (jailed(td->td_ucred)) 592 return (ENOSYS); 593 error = copyin(uap->auditinfo_addr, &aia, sizeof(aia)); 594 if (error) 595 return (error); 596 audit_arg_auditinfo_addr(&aia); 597 if (aia.ai_termid.at_type != AU_IPv6 && 598 aia.ai_termid.at_type != AU_IPv4) 599 return (EINVAL); 600 newcred = crget(); 601 PROC_LOCK(td->td_proc); 602 oldcred = td->td_proc->p_ucred; 603 crcopy(newcred, oldcred); 604 #ifdef MAC 605 error = mac_proc_check_setaudit_addr(oldcred, &aia); 606 if (error) 607 goto fail; 608 #endif 609 error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0); 610 if (error) 611 goto fail; 612 newcred->cr_audit = aia; 613 td->td_proc->p_ucred = newcred; 614 PROC_UNLOCK(td->td_proc); 615 crfree(oldcred); 616 return (0); 617 fail: 618 PROC_UNLOCK(td->td_proc); 619 crfree(newcred); 620 return (error); 621 } 622 623 /* 624 * Syscall to manage audit files. 625 */ 626 /* ARGSUSED */ 627 int 628 auditctl(struct thread *td, struct auditctl_args *uap) 629 { 630 struct nameidata nd; 631 struct ucred *cred; 632 struct vnode *vp; 633 int error = 0; 634 int flags, vfslocked; 635 636 if (jailed(td->td_ucred)) 637 return (ENOSYS); 638 error = priv_check(td, PRIV_AUDIT_CONTROL); 639 if (error) 640 return (error); 641 642 vp = NULL; 643 cred = NULL; 644 645 /* 646 * If a path is specified, open the replacement vnode, perform 647 * validity checks, and grab another reference to the current 648 * credential. 649 * 650 * On Darwin, a NULL path argument is also used to disable audit. 651 */ 652 if (uap->path == NULL) 653 return (EINVAL); 654 655 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, 656 UIO_USERSPACE, uap->path, td); 657 flags = AUDIT_OPEN_FLAGS; 658 error = vn_open(&nd, &flags, 0, NULL); 659 if (error) 660 return (error); 661 vfslocked = NDHASGIANT(&nd); 662 vp = nd.ni_vp; 663 #ifdef MAC 664 error = mac_system_check_auditctl(td->td_ucred, vp); 665 VOP_UNLOCK(vp, 0); 666 if (error) { 667 vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); 668 VFS_UNLOCK_GIANT(vfslocked); 669 return (error); 670 } 671 #else 672 VOP_UNLOCK(vp, 0); 673 #endif 674 NDFREE(&nd, NDF_ONLY_PNBUF); 675 if (vp->v_type != VREG) { 676 vn_close(vp, AUDIT_CLOSE_FLAGS, td->td_ucred, td); 677 VFS_UNLOCK_GIANT(vfslocked); 678 return (EINVAL); 679 } 680 VFS_UNLOCK_GIANT(vfslocked); 681 cred = td->td_ucred; 682 crhold(cred); 683 684 /* 685 * XXXAUDIT: Should audit_suspended actually be cleared by 686 * audit_worker? 687 */ 688 audit_suspended = 0; 689 690 audit_rotate_vnode(cred, vp); 691 692 return (error); 693 } 694 695 #else /* !AUDIT */ 696 697 int 698 audit(struct thread *td, struct audit_args *uap) 699 { 700 701 return (ENOSYS); 702 } 703 704 int 705 auditon(struct thread *td, struct auditon_args *uap) 706 { 707 708 return (ENOSYS); 709 } 710 711 int 712 getauid(struct thread *td, struct getauid_args *uap) 713 { 714 715 return (ENOSYS); 716 } 717 718 int 719 setauid(struct thread *td, struct setauid_args *uap) 720 { 721 722 return (ENOSYS); 723 } 724 725 int 726 getaudit(struct thread *td, struct getaudit_args *uap) 727 { 728 729 return (ENOSYS); 730 } 731 732 int 733 setaudit(struct thread *td, struct setaudit_args *uap) 734 { 735 736 return (ENOSYS); 737 } 738 739 int 740 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap) 741 { 742 743 return (ENOSYS); 744 } 745 746 int 747 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap) 748 { 749 750 return (ENOSYS); 751 } 752 753 int 754 auditctl(struct thread *td, struct auditctl_args *uap) 755 { 756 757 return (ENOSYS); 758 } 759 #endif /* AUDIT */ 760