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