1 /*- 2 * Copyright (c) 2008-2009 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 * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#11 $ 30 */ 31 32 #include <sys/param.h> 33 34 #include <config/config.h> 35 36 #include <sys/dirent.h> 37 #ifdef HAVE_FULL_QUEUE_H 38 #include <sys/queue.h> 39 #else /* !HAVE_FULL_QUEUE_H */ 40 #include <compat/queue.h> 41 #endif /* !HAVE_FULL_QUEUE_H */ 42 #include <sys/mount.h> 43 #include <sys/socket.h> 44 45 #include <sys/stat.h> 46 #include <sys/time.h> 47 48 #include <netinet/in.h> 49 50 #include <bsm/audit.h> 51 #include <bsm/audit_uevents.h> 52 #include <bsm/auditd_lib.h> 53 #include <bsm/libbsm.h> 54 55 #include <dirent.h> 56 #include <err.h> 57 #include <errno.h> 58 #include <fcntl.h> 59 #include <stdio.h> 60 #include <string.h> 61 #include <stdlib.h> 62 #include <time.h> 63 #include <unistd.h> 64 #include <netdb.h> 65 66 #ifdef __APPLE__ 67 #include <notify.h> 68 #ifndef __BSM_INTERNAL_NOTIFY_KEY 69 #define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change" 70 #endif /* __BSM_INTERNAL_NOTIFY_KEY */ 71 #endif /* __APPLE__ */ 72 73 /* 74 * XXX This is temporary until this is moved to <bsm/audit.h> and shared with 75 * the kernel. 76 */ 77 #ifndef AUDIT_HARD_LIMIT_FREE_BLOCKS 78 #define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 79 #endif 80 81 /* 82 * Number of seconds to January 1, 2000 83 */ 84 #define JAN_01_2000 946598400 85 86 struct dir_ent { 87 char *dirname; 88 uint8_t softlim; 89 uint8_t hardlim; 90 TAILQ_ENTRY(dir_ent) dirs; 91 }; 92 93 static TAILQ_HEAD(, dir_ent) dir_q; 94 95 struct audit_trail { 96 time_t at_time; 97 char *at_path; 98 off_t at_size; 99 100 TAILQ_ENTRY(audit_trail) at_trls; 101 }; 102 103 static int auditd_minval = -1; 104 105 static char auditd_host[MAXHOSTNAMELEN]; 106 static int auditd_hostlen = -1; 107 108 static char *auditd_errmsg[] = { 109 "no error", /* ADE_NOERR ( 0) */ 110 "could not parse audit_control(5) file", /* ADE_PARSE ( 1) */ 111 "auditon(2) failed", /* ADE_AUDITON ( 2) */ 112 "malloc(3) failed", /* ADE_NOMEM ( 3) */ 113 "all audit log directories over soft limit", /* ADE_SOFTLIM ( 4) */ 114 "all audit log directories over hard limit", /* ADE_HARDLIM ( 5) */ 115 "could not create file name string", /* ADE_STRERR ( 6) */ 116 "could not open audit record", /* ADE_AU_OPEN ( 7) */ 117 "could not close audit record", /* ADE_AU_CLOSE ( 8) */ 118 "could not set active audit session state", /* ADE_SETAUDIT ( 9) */ 119 "auditctl(2) failed (trail still swapped)", /* ADE_ACTL (10) */ 120 "auditctl(2) failed (trail not swapped)", /* ADE_ACTLERR (11) */ 121 "could not swap audit trail file", /* ADE_SWAPERR (12) */ 122 "could not rename crash recovery file", /* ADE_RENAME (13) */ 123 "could not read 'current' link file", /* ADE_READLINK (14) */ 124 "could not create 'current' link file", /* ADE_SYMLINK (15) */ 125 "invalid argument", /* ADE_INVAL (16) */ 126 "could not resolve hostname to address", /* ADE_GETADDR (17) */ 127 "address family not supported", /* ADE_ADDRFAM (18) */ 128 "error expiring audit trail files", /* ADE_EXPIRE (19) */ 129 }; 130 131 #define MAXERRCODE (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0])) 132 133 #define NA_EVENT_STR_SIZE 128 134 #define POL_STR_SIZE 128 135 136 137 /* 138 * Look up and return the error string for the given audit error code. 139 */ 140 const char * 141 auditd_strerror(int errcode) 142 { 143 int idx = -errcode; 144 145 if (idx < 0 || idx > (int)MAXERRCODE) 146 return ("Invalid auditd error code"); 147 148 return (auditd_errmsg[idx]); 149 } 150 151 152 /* 153 * Free our local list of directory names and init list 154 */ 155 static void 156 free_dir_q(void) 157 { 158 struct dir_ent *d1, *d2; 159 160 d1 = TAILQ_FIRST(&dir_q); 161 while (d1 != NULL) { 162 d2 = TAILQ_NEXT(d1, dirs); 163 free(d1->dirname); 164 free(d1); 165 d1 = d2; 166 } 167 TAILQ_INIT(&dir_q); 168 } 169 170 /* 171 * Concat the directory name to the given file name. 172 * XXX We should affix the hostname also 173 */ 174 static char * 175 affixdir(char *name, struct dir_ent *dirent) 176 { 177 char *fn = NULL; 178 179 /* 180 * Sanity check on file name. 181 */ 182 if (strlen(name) != (FILENAME_LEN - 1)) { 183 errno = EINVAL; 184 return (NULL); 185 } 186 187 /* 188 * If the host is set then also add the hostname to the filename. 189 */ 190 if (auditd_hostlen != -1) 191 asprintf(&fn, "%s/%s.%s", dirent->dirname, name, auditd_host); 192 else 193 asprintf(&fn, "%s/%s", dirent->dirname, name); 194 return (fn); 195 } 196 197 /* 198 * Insert the directory entry in the list by the way they are ordered in 199 * audit_control(5). Move the entries that are over the soft and hard limits 200 * toward the tail. 201 */ 202 static void 203 insert_orderly(struct dir_ent *denew) 204 { 205 struct dir_ent *dep; 206 207 TAILQ_FOREACH(dep, &dir_q, dirs) { 208 if (dep->softlim == 1 && denew->softlim == 0) { 209 TAILQ_INSERT_BEFORE(dep, denew, dirs); 210 return; 211 } 212 if (dep->hardlim == 1 && denew->hardlim == 0) { 213 TAILQ_INSERT_BEFORE(dep, denew, dirs); 214 return; 215 } 216 } 217 TAILQ_INSERT_TAIL(&dir_q, denew, dirs); 218 } 219 220 /* 221 * Get the host from audit_control(5) and set it in the audit kernel 222 * information. Return: 223 * ADE_NOERR on success. 224 * ADE_PARSE error parsing audit_control(5). 225 * ADE_AUDITON error getting/setting auditon(2) value. 226 * ADE_GETADDR error getting address info for host. 227 * ADE_ADDRFAM un-supported address family. 228 */ 229 int 230 auditd_set_host(void) 231 { 232 struct sockaddr_in6 *sin6; 233 struct sockaddr_in *sin; 234 struct addrinfo *res; 235 struct auditinfo_addr aia; 236 int error, ret = ADE_NOERR; 237 238 if (getachost(auditd_host, sizeof(auditd_host)) != 0) { 239 ret = ADE_PARSE; 240 241 /* 242 * To maintain reverse compatability with older audit_control 243 * files, simply drop a warning if the host parameter has not 244 * been set. However, we will explicitly disable the 245 * generation of extended audit header by passing in a zeroed 246 * termid structure. 247 */ 248 bzero(&aia, sizeof(aia)); 249 aia.ai_termid.at_type = AU_IPv4; 250 error = audit_set_kaudit(&aia, sizeof(aia)); 251 if (error < 0 && errno != ENOSYS) 252 ret = ADE_AUDITON; 253 return (ret); 254 } 255 auditd_hostlen = strlen(auditd_host); 256 error = getaddrinfo(auditd_host, NULL, NULL, &res); 257 if (error) 258 return (ADE_GETADDR); 259 switch (res->ai_family) { 260 case PF_INET6: 261 sin6 = (struct sockaddr_in6 *) res->ai_addr; 262 bcopy(&sin6->sin6_addr.s6_addr, 263 &aia.ai_termid.at_addr[0], sizeof(struct in6_addr)); 264 aia.ai_termid.at_type = AU_IPv6; 265 break; 266 267 case PF_INET: 268 sin = (struct sockaddr_in *) res->ai_addr; 269 bcopy(&sin->sin_addr.s_addr, 270 &aia.ai_termid.at_addr[0], sizeof(struct in_addr)); 271 aia.ai_termid.at_type = AU_IPv4; 272 break; 273 274 default: 275 /* Un-supported address family in host parameter. */ 276 errno = EAFNOSUPPORT; 277 return (ADE_ADDRFAM); 278 } 279 280 if (audit_set_kaudit(&aia, sizeof(aia)) < 0) 281 ret = ADE_AUDITON; 282 283 return (ret); 284 } 285 286 /* 287 * Get the min percentage of free blocks from audit_control(5) and that 288 * value in the kernel. Return: 289 * ADE_NOERR on success, 290 * ADE_PARSE error parsing audit_control(5), 291 * ADE_AUDITON error getting/setting auditon(2) value. 292 */ 293 int 294 auditd_set_minfree(void) 295 { 296 au_qctrl_t qctrl; 297 298 if (getacmin(&auditd_minval) != 0) 299 return (ADE_PARSE); 300 301 if (audit_get_qctrl(&qctrl, sizeof(qctrl)) != 0) 302 return (ADE_AUDITON); 303 304 if (qctrl.aq_minfree != auditd_minval) { 305 qctrl.aq_minfree = auditd_minval; 306 if (audit_set_qctrl(&qctrl, sizeof(qctrl)) != 0) 307 return (ADE_AUDITON); 308 } 309 310 return (0); 311 } 312 313 /* 314 * Convert a trailname into a timestamp (seconds). Return 0 if the conversion 315 * was successful. 316 */ 317 static int 318 trailname_to_tstamp(char *fn, time_t *tstamp) 319 { 320 struct tm tm; 321 char ts[TIMESTAMP_LEN]; 322 char *p; 323 324 *tstamp = 0; 325 326 /* 327 * Get the ending time stamp. 328 */ 329 if ((p = strchr(fn, '.')) == NULL) 330 return (1); 331 strlcpy(ts, ++p, TIMESTAMP_LEN); 332 if (strlen(ts) != POSTFIX_LEN) 333 return (1); 334 335 bzero(&tm, sizeof(tm)); 336 337 /* seconds (0-60) */ 338 p = ts + POSTFIX_LEN - 2; 339 tm.tm_sec = atol(p); 340 if (tm.tm_sec < 0 || tm.tm_sec > 60) 341 return (1); 342 343 /* minutes (0-59) */ 344 *p = '\0'; p -= 2; 345 tm.tm_min = atol(p); 346 if (tm.tm_min < 0 || tm.tm_min > 59) 347 return (1); 348 349 /* hours (0 - 23) */ 350 *p = '\0'; p -= 2; 351 tm.tm_hour = atol(p); 352 if (tm.tm_hour < 0 || tm.tm_hour > 23) 353 return (1); 354 355 /* day of month (1-31) */ 356 *p = '\0'; p -= 2; 357 tm.tm_mday = atol(p); 358 if (tm.tm_mday < 1 || tm.tm_mday > 31) 359 return (1); 360 361 /* month (0 - 11) */ 362 *p = '\0'; p -= 2; 363 tm.tm_mon = atol(p) - 1; 364 if (tm.tm_mon < 0 || tm.tm_mon > 11) 365 return (1); 366 367 /* year (year - 1900) */ 368 *p = '\0'; p -= 4; 369 tm.tm_year = atol(p) - 1900; 370 if (tm.tm_year < 0) 371 return (1); 372 373 *tstamp = timegm(&tm); 374 375 return (0); 376 } 377 378 /* 379 * Remove audit trails files according to the expiration conditions. Returns: 380 * ADE_NOERR on success or there is nothing to do. 381 * ADE_PARSE if error parsing audit_control(5). 382 * ADE_NOMEM if could not allocate memory. 383 * ADE_EXPIRE if there was an unespected error. 384 */ 385 int 386 auditd_expire_trails(int (*warn_expired)(char *)) 387 { 388 int andflg, ret = ADE_NOERR; 389 size_t expire_size, total_size = 0L; 390 time_t expire_age, oldest_time, current_time = time(NULL); 391 struct dir_ent *traildir; 392 struct audit_trail *at; 393 char *afnp, *pn; 394 TAILQ_HEAD(au_trls_head, audit_trail) head = 395 TAILQ_HEAD_INITIALIZER(head); 396 struct stat stbuf; 397 char activefn[MAXPATHLEN]; 398 399 /* 400 * Read the expiration conditions. If no conditions then return no 401 * error. 402 */ 403 if (getacexpire(&andflg, &expire_age, &expire_size) < 0) 404 return (ADE_PARSE); 405 if (!expire_age && !expire_size) 406 return (ADE_NOERR); 407 408 /* 409 * Read the 'current' trail file name. Trim off directory path. 410 */ 411 activefn[0] = '\0'; 412 readlink(AUDIT_CURRENT_LINK, activefn, MAXPATHLEN - 1); 413 if ((afnp = strrchr(activefn, '/')) != NULL) 414 afnp++; 415 416 417 /* 418 * Build tail queue of the trail files. 419 */ 420 TAILQ_FOREACH(traildir, &dir_q, dirs) { 421 DIR *dirp; 422 struct dirent *dp; 423 424 dirp = opendir(traildir->dirname); 425 while ((dp = readdir(dirp)) != NULL) { 426 time_t tstamp = 0; 427 struct audit_trail *new; 428 429 /* 430 * Quickly filter non-trail files. 431 */ 432 if (dp->d_namlen != (FILENAME_LEN - 1) || 433 #ifdef DT_REG 434 dp->d_type != DT_REG || 435 #endif 436 dp->d_name[POSTFIX_LEN] != '.') 437 continue; 438 439 if (asprintf(&pn, "%s/%s", traildir->dirname, 440 dp->d_name) < 0) { 441 ret = ADE_NOMEM; 442 break; 443 } 444 445 if (stat(pn, &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) { 446 free(pn); 447 continue; 448 } 449 450 total_size += stbuf.st_size; 451 452 /* 453 * If this is the 'current' audit trail then 454 * don't add it to the tail queue. 455 */ 456 if (NULL != afnp && 457 strncmp(dp->d_name, afnp, FILENAME_LEN) == 0) { 458 free(pn); 459 continue; 460 } 461 462 /* 463 * Get the ending time stamp encoded in the trail 464 * name. If we can't read it or if it is older 465 * than Jan 1, 2000 then use the mtime. 466 */ 467 if (trailname_to_tstamp(dp->d_name, &tstamp) != 0 || 468 tstamp < JAN_01_2000) 469 tstamp = stbuf.st_mtime; 470 471 /* 472 * If the time stamp is older than Jan 1, 2000 then 473 * update the mtime of the trail file to the current 474 * time. This is so we don't prematurely remove a trail 475 * file that was created while the system clock reset 476 * to the * "beginning of time" but later the system 477 * clock is set to the correct current time. 478 */ 479 if (current_time >= JAN_01_2000 && 480 tstamp < JAN_01_2000) { 481 struct timeval tv[2]; 482 483 tstamp = stbuf.st_mtime = current_time; 484 TIMESPEC_TO_TIMEVAL(&tv[0], 485 &stbuf.st_atimespec); 486 TIMESPEC_TO_TIMEVAL(&tv[1], 487 &stbuf.st_mtimespec); 488 utimes(pn, tv); 489 } 490 491 /* 492 * Allocate and populate the new entry. 493 */ 494 new = malloc(sizeof(*new)); 495 if (NULL == new) { 496 free(pn); 497 ret = ADE_NOMEM; 498 break; 499 } 500 new->at_time = tstamp; 501 new->at_size = stbuf.st_size; 502 new->at_path = pn; 503 504 /* 505 * Check to see if we have a new head. Otherwise, 506 * walk the tailq from the tail first and do a simple 507 * insertion sort. 508 */ 509 if (TAILQ_EMPTY(&head) || 510 (new->at_time <= TAILQ_FIRST(&head)->at_time)) { 511 TAILQ_INSERT_HEAD(&head, new, at_trls); 512 continue; 513 } 514 515 TAILQ_FOREACH_REVERSE(at, &head, au_trls_head, at_trls) 516 if (new->at_time >= at->at_time) { 517 TAILQ_INSERT_AFTER(&head, at, new, 518 at_trls); 519 break; 520 } 521 522 } 523 closedir(dirp); 524 } 525 526 oldest_time = current_time - expire_age; 527 528 /* 529 * Expire trail files, oldest (mtime) first, if the given 530 * conditions are met. 531 */ 532 at = TAILQ_FIRST(&head); 533 while (NULL != at) { 534 struct audit_trail *at_next = TAILQ_NEXT(at, at_trls); 535 536 if (andflg) { 537 if ((expire_size && total_size > expire_size) && 538 (expire_age && at->at_time < oldest_time)) { 539 if (warn_expired) 540 (*warn_expired)(at->at_path); 541 if (unlink(at->at_path) < 0) 542 ret = ADE_EXPIRE; 543 total_size -= at->at_size; 544 } 545 } else { 546 if ((expire_size && total_size > expire_size) || 547 (expire_age && at->at_time < oldest_time)) { 548 if (warn_expired) 549 (*warn_expired)(at->at_path); 550 if (unlink(at->at_path) < 0) 551 ret = ADE_EXPIRE; 552 total_size -= at->at_size; 553 } 554 } 555 556 free(at->at_path); 557 free(at); 558 at = at_next; 559 } 560 561 return (ret); 562 } 563 564 /* 565 * Parses the "dir" entry in audit_control(5) into an ordered list. Also, will 566 * set the minfree and host values if not already set. Arguments include 567 * function pointers to audit_warn functions for soft and hard limits. Returns: 568 * ADE_NOERR on success, 569 * ADE_PARSE error parsing audit_control(5), 570 * ADE_AUDITON error getting/setting auditon(2) value, 571 * ADE_NOMEM error allocating memory, 572 * ADE_SOFTLIM if all the directories are over the soft limit, 573 * ADE_HARDLIM if all the directories are over the hard limit, 574 */ 575 int 576 auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *)) 577 { 578 char cur_dir[MAXNAMLEN]; 579 struct dir_ent *dirent; 580 struct statfs sfs; 581 int err; 582 char soft, hard; 583 int tcnt = 0; 584 int scnt = 0; 585 int hcnt = 0; 586 587 if (auditd_minval == -1 && (err = auditd_set_minfree()) != 0) 588 return (err); 589 590 if (auditd_hostlen == -1) 591 auditd_set_host(); 592 593 /* 594 * Init directory q. Force a re-read of the file the next time. 595 */ 596 free_dir_q(); 597 endac(); 598 599 /* 600 * Read the list of directories into an ordered linked list 601 * admin's preference, then those over soft limit and, finally, 602 * those over the hard limit. 603 * 604 * XXX We should use the reentrant interfaces once they are 605 * available. 606 */ 607 while (getacdir(cur_dir, MAXNAMLEN) >= 0) { 608 if (statfs(cur_dir, &sfs) < 0) 609 continue; /* XXX should warn */ 610 soft = (sfs.f_bfree < (sfs.f_blocks / (100 / auditd_minval))) ? 611 1 : 0; 612 hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0; 613 if (soft) { 614 if (warn_soft) 615 (*warn_soft)(cur_dir); 616 scnt++; 617 } 618 if (hard) { 619 if (warn_hard) 620 (*warn_hard)(cur_dir); 621 hcnt++; 622 } 623 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent)); 624 if (dirent == NULL) 625 return (ADE_NOMEM); 626 dirent->softlim = soft; 627 dirent->hardlim = hard; 628 dirent->dirname = (char *) malloc(MAXNAMLEN); 629 if (dirent->dirname == NULL) { 630 free(dirent); 631 return (ADE_NOMEM); 632 } 633 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN); 634 insert_orderly(dirent); 635 tcnt++; 636 } 637 638 if (hcnt == tcnt) 639 return (ADE_HARDLIM); 640 if (scnt == tcnt) 641 return (ADE_SOFTLIM); 642 return (0); 643 } 644 645 void 646 auditd_close_dirs(void) 647 { 648 free_dir_q(); 649 auditd_minval = -1; 650 auditd_hostlen = -1; 651 } 652 653 654 /* 655 * Process the audit event file, obtaining a class mapping for each event, and 656 * set that mapping into the kernel. Return: 657 * n number of event mappings that were successfully processed, 658 * ADE_NOMEM if there was an error allocating memory. 659 */ 660 int 661 auditd_set_evcmap(void) 662 { 663 au_event_ent_t ev, *evp; 664 au_evclass_map_t evc_map; 665 int ctr = 0; 666 667 668 /* 669 * XXX There's a risk here that the BSM library will return NULL 670 * for an event when it can't properly map it to a class. In that 671 * case, we will not process any events beyond the one that failed, 672 * but should. We need a way to get a count of the events. 673 */ 674 ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX); 675 ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX); 676 if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) { 677 if (ev.ae_name != NULL) 678 free(ev.ae_name); 679 return (ADE_NOMEM); 680 } 681 682 /* 683 * XXXRW: Currently we have no way to remove mappings from the kernel 684 * when they are removed from the file-based mappings. 685 */ 686 evp = &ev; 687 setauevent(); 688 while ((evp = getauevent_r(evp)) != NULL) { 689 evc_map.ec_number = evp->ae_number; 690 evc_map.ec_class = evp->ae_class; 691 if (audit_set_class(&evc_map, sizeof(evc_map)) == 0) 692 ctr++; 693 } 694 endauevent(); 695 free(ev.ae_name); 696 free(ev.ae_desc); 697 698 return (ctr); 699 } 700 701 /* 702 * Get the non-attributable event string and set the kernel mask. Return: 703 * ADE_NOERR on success, 704 * ADE_PARSE error parsing audit_control(5), 705 * ADE_AUDITON error setting the mask using auditon(2). 706 */ 707 int 708 auditd_set_namask(void) 709 { 710 au_mask_t aumask; 711 char naeventstr[NA_EVENT_STR_SIZE]; 712 713 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) != 0) || 714 (getauditflagsbin(naeventstr, &aumask) != 0)) 715 return (ADE_PARSE); 716 717 if (audit_set_kmask(&aumask, sizeof(aumask)) != 0) 718 return (ADE_AUDITON); 719 720 return (ADE_NOERR); 721 } 722 723 /* 724 * Set the audit control policy if a policy is configured in audit_control(5), 725 * implement the policy. However, if one isn't defined or if there is an error 726 * parsing the control file, set AUDIT_CNT to avoid leaving the system in a 727 * fragile state. Return: 728 * ADE_NOERR on success, 729 * ADE_PARSE error parsing audit_control(5), 730 * ADE_AUDITON error setting policy using auditon(2). 731 */ 732 int 733 auditd_set_policy(void) 734 { 735 int policy; 736 char polstr[POL_STR_SIZE]; 737 738 if ((getacpol(polstr, POL_STR_SIZE) != 0) || 739 (au_strtopol(polstr, &policy) != 0)) { 740 policy = AUDIT_CNT; 741 if (audit_set_policy(&policy) != 0) 742 return (ADE_AUDITON); 743 return (ADE_PARSE); 744 } 745 746 if (audit_set_policy(&policy) != 0) 747 return (ADE_AUDITON); 748 749 return (ADE_NOERR); 750 } 751 752 /* 753 * Set trail rotation size. Return: 754 * ADE_NOERR on success, 755 * ADE_PARSE error parsing audit_control(5), 756 * ADE_AUDITON error setting file size using auditon(2). 757 */ 758 int 759 auditd_set_fsize(void) 760 { 761 size_t filesz; 762 au_fstat_t au_fstat; 763 764 /* 765 * Set trail rotation size. 766 */ 767 if (getacfilesz(&filesz) != 0) 768 return (ADE_PARSE); 769 770 bzero(&au_fstat, sizeof(au_fstat)); 771 au_fstat.af_filesz = filesz; 772 if (audit_set_fsize(&au_fstat, sizeof(au_fstat)) != 0) 773 return (ADE_AUDITON); 774 775 return (ADE_NOERR); 776 } 777 778 /* 779 * Create the new audit file with appropriate permissions and ownership. Try 780 * to clean up if something goes wrong. 781 */ 782 static int 783 open_trail(char *fname, gid_t gid) 784 { 785 int error, fd; 786 787 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP); 788 if (fd < 0) 789 return (-1); 790 if (fchown(fd, -1, gid) < 0) { 791 error = errno; 792 close(fd); 793 (void)unlink(fname); 794 errno = error; 795 return (-1); 796 } 797 return (fd); 798 } 799 800 /* 801 * Create the new audit trail file, swap with existing audit file. Arguments 802 * include timestamp for the filename, a pointer to a string for returning the 803 * new file name, GID for trail file, and audit_warn function pointer for 804 * 'getacdir()' errors. Returns: 805 * ADE_NOERR on success, 806 * ADE_STRERR if the file name string could not be created, 807 * ADE_SWAPERR if the audit trail file could not be swapped, 808 * ADE_ACTL if the auditctl(2) call failed but file swap still 809 * successful. 810 * ADE_ACTLERR if the auditctl(2) call failed and file swap failed. 811 * ADE_SYMLINK if symlink(2) failed updating the current link. 812 */ 813 int 814 auditd_swap_trail(char *TS, char **newfile, gid_t gid, 815 int (*warn_getacdir)(char *)) 816 { 817 char timestr[FILENAME_LEN]; 818 char *fn; 819 struct dir_ent *dirent; 820 int fd; 821 int error; 822 int saverrno = 0; 823 824 if (strlen(TS) != (TIMESTAMP_LEN - 1) || 825 snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED) < 0) { 826 errno = EINVAL; 827 return (ADE_STRERR); 828 } 829 830 /* Try until we succeed. */ 831 TAILQ_FOREACH(dirent, &dir_q, dirs) { 832 if (dirent->hardlim) 833 continue; 834 if ((fn = affixdir(timestr, dirent)) == NULL) 835 return (ADE_STRERR); 836 837 /* 838 * Create and open the file; then close and pass to the 839 * kernel if all went well. 840 */ 841 fd = open_trail(fn, gid); 842 if (fd >= 0) { 843 error = auditctl(fn); 844 if (error) { 845 /* 846 * auditctl failed setting log file. 847 * Try again. 848 */ 849 saverrno = errno; 850 close(fd); 851 } else { 852 /* Success. */ 853 *newfile = fn; 854 close(fd); 855 if (error) 856 return (error); 857 if (saverrno) { 858 /* 859 * auditctl() failed but still 860 * successful. Return errno and "soft" 861 * error. 862 */ 863 errno = saverrno; 864 return (ADE_ACTL); 865 } 866 return (ADE_NOERR); 867 } 868 } 869 870 /* 871 * Tell the administrator about lack of permissions for dir. 872 */ 873 if (warn_getacdir != NULL) 874 (*warn_getacdir)(dirent->dirname); 875 } 876 if (saverrno) { 877 errno = saverrno; 878 return (ADE_ACTLERR); 879 } else 880 return (ADE_SWAPERR); 881 } 882 883 /* 884 * Mask calling process from being audited. Returns: 885 * ADE_NOERR on success, 886 * ADE_SETAUDIT if setaudit(2) fails. 887 */ 888 #ifdef __APPLE__ 889 int 890 auditd_prevent_audit(void) 891 { 892 auditinfo_addr_t aia; 893 894 /* 895 * To prevent event feedback cycles and avoid audit becoming stalled if 896 * auditing is suspended we mask this processes events from being 897 * audited. We allow the uid, tid, and mask fields to be implicitly 898 * set to zero, but do set the audit session ID to the PID. 899 * 900 * XXXRW: Is there more to it than this? 901 */ 902 bzero(&aia, sizeof(aia)); 903 aia.ai_asid = AU_ASSIGN_ASID; 904 aia.ai_termid.at_type = AU_IPv4; 905 if (setaudit_addr(&aia, sizeof(aia)) != 0) 906 return (ADE_SETAUDIT); 907 return (ADE_NOERR); 908 } 909 #else 910 int 911 auditd_prevent_audit(void) 912 { 913 auditinfo_t ai; 914 915 /* 916 * To prevent event feedback cycles and avoid audit becoming stalled if 917 * auditing is suspended we mask this processes events from being 918 * audited. We allow the uid, tid, and mask fields to be implicitly 919 * set to zero, but do set the audit session ID to the PID. 920 * 921 * XXXRW: Is there more to it than this? 922 */ 923 bzero(&ai, sizeof(ai)); 924 ai.ai_asid = getpid(); 925 if (setaudit(&ai) != 0) 926 return (ADE_SETAUDIT); 927 return (ADE_NOERR); 928 } 929 #endif /* __APPLE__ */ 930 931 /* 932 * Generate and submit audit record for audit startup or shutdown. The event 933 * argument can be AUE_audit_recovery, AUE_audit_startup or 934 * AUE_audit_shutdown. The path argument will add a path token, if not NULL. 935 * Returns: 936 * AUE_NOERR on success, 937 * ADE_NOMEM if memory allocation fails, 938 * ADE_AU_OPEN if au_open(3) fails, 939 * ADE_AU_CLOSE if au_close(3) fails. 940 */ 941 int 942 auditd_gen_record(int event, char *path) 943 { 944 int aufd; 945 uid_t uid; 946 pid_t pid; 947 char *autext = NULL; 948 token_t *tok; 949 struct auditinfo_addr aia; 950 951 if (event == AUE_audit_startup) 952 asprintf(&autext, "%s::Audit startup", getprogname()); 953 else if (event == AUE_audit_shutdown) 954 asprintf(&autext, "%s::Audit shutdown", getprogname()); 955 else if (event == AUE_audit_recovery) 956 asprintf(&autext, "%s::Audit recovery", getprogname()); 957 else 958 return (ADE_INVAL); 959 if (autext == NULL) 960 return (ADE_NOMEM); 961 962 if ((aufd = au_open()) == -1) { 963 free(autext); 964 return (ADE_AU_OPEN); 965 } 966 bzero(&aia, sizeof(aia)); 967 uid = getuid(); pid = getpid(); 968 if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, getgid(), 969 pid, pid, &aia.ai_termid)) != NULL) 970 au_write(aufd, tok); 971 if ((tok = au_to_text(autext)) != NULL) 972 au_write(aufd, tok); 973 free(autext); 974 if (path != NULL && (tok = au_to_path(path)) != NULL) 975 au_write(aufd, tok); 976 if ((tok = au_to_return32(0, 0)) != NULL) 977 au_write(aufd, tok); 978 if (au_close(aufd, 1, event) == -1) 979 return (ADE_AU_CLOSE); 980 981 return (ADE_NOERR); 982 } 983 984 /* 985 * Check for a 'current' symlink and do crash recovery, if needed. Create a new 986 * 'current' symlink. The argument 'curfile' is the file the 'current' symlink 987 * should point to. Returns: 988 * ADE_NOERR on success, 989 * ADE_AU_OPEN if au_open(3) fails, 990 * ADE_AU_CLOSE if au_close(3) fails. 991 * ADE_RENAME if error renaming audit trail file, 992 * ADE_READLINK if error reading the 'current' link, 993 * ADE_SYMLINK if error creating 'current' link. 994 */ 995 int 996 auditd_new_curlink(char *curfile) 997 { 998 int len, err; 999 char *ptr; 1000 char *path = NULL; 1001 struct stat sb; 1002 char recoveredname[MAXPATHLEN]; 1003 char newname[MAXPATHLEN]; 1004 1005 /* 1006 * Check to see if audit was shutdown properly. If not, clean up, 1007 * recover previous audit trail file, and generate audit record. 1008 */ 1009 len = readlink(AUDIT_CURRENT_LINK, recoveredname, MAXPATHLEN - 1); 1010 if (len > 0) { 1011 /* 'current' exist but is it pointing at a valid file? */ 1012 recoveredname[len++] = '\0'; 1013 if (stat(recoveredname, &sb) == 0) { 1014 /* Yes, rename it to a crash recovery file. */ 1015 strlcpy(newname, recoveredname, MAXPATHLEN); 1016 1017 if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) { 1018 memcpy(ptr, CRASH_RECOVERY, POSTFIX_LEN); 1019 if (rename(recoveredname, newname) != 0) 1020 return (ADE_RENAME); 1021 } else 1022 return (ADE_STRERR); 1023 1024 path = newname; 1025 } 1026 1027 /* 'current' symlink is (now) invalid so remove it. */ 1028 (void) unlink(AUDIT_CURRENT_LINK); 1029 1030 /* Note the crash recovery in current audit trail */ 1031 err = auditd_gen_record(AUE_audit_recovery, path); 1032 if (err) 1033 return (err); 1034 } 1035 1036 if (len < 0 && errno != ENOENT) 1037 return (ADE_READLINK); 1038 1039 if (symlink(curfile, AUDIT_CURRENT_LINK) != 0) 1040 return (ADE_SYMLINK); 1041 1042 return (0); 1043 } 1044 1045 /* 1046 * Do just what we need to quickly start auditing. Assume no system logging or 1047 * notify. Return: 1048 * 0 on success, 1049 * -1 on failure. 1050 */ 1051 int 1052 audit_quick_start(void) 1053 { 1054 int err; 1055 char *newfile = NULL; 1056 time_t tt; 1057 char TS[TIMESTAMP_LEN]; 1058 int ret = 0; 1059 1060 /* 1061 * Mask auditing of this process. 1062 */ 1063 if (auditd_prevent_audit() != 0) 1064 return (-1); 1065 1066 /* 1067 * Read audit_control and get log directories. 1068 */ 1069 err = auditd_read_dirs(NULL, NULL); 1070 if (err != ADE_NOERR && err != ADE_SOFTLIM) 1071 return (-1); 1072 1073 /* 1074 * Create a new audit trail log. 1075 */ 1076 if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0) 1077 return (-1); 1078 err = auditd_swap_trail(TS, &newfile, getgid(), NULL); 1079 if (err != ADE_NOERR && err != ADE_ACTL) { 1080 ret = -1; 1081 goto out; 1082 } 1083 1084 /* 1085 * Add the current symlink and recover from crash, if needed. 1086 */ 1087 if (auditd_new_curlink(newfile) != 0) { 1088 ret = -1; 1089 goto out; 1090 } 1091 1092 /* 1093 * At this point auditing has started so generate audit start-up record. 1094 */ 1095 if (auditd_gen_record(AUE_audit_startup, NULL) != 0) { 1096 ret = -1; 1097 goto out; 1098 } 1099 1100 /* 1101 * Configure the audit controls. 1102 */ 1103 (void) auditd_set_evcmap(); 1104 (void) auditd_set_namask(); 1105 (void) auditd_set_policy(); 1106 (void) auditd_set_fsize(); 1107 (void) auditd_set_minfree(); 1108 (void) auditd_set_host(); 1109 1110 out: 1111 if (newfile != NULL) 1112 free(newfile); 1113 1114 return (ret); 1115 } 1116 1117 /* 1118 * Shut down auditing quickly. Assumes that is only called on system shutdown. 1119 * Returns: 1120 * 0 on success, 1121 * -1 on failure. 1122 */ 1123 int 1124 audit_quick_stop(void) 1125 { 1126 int len; 1127 int cond; 1128 char *ptr; 1129 time_t tt; 1130 char oldname[MAXPATHLEN]; 1131 char newname[MAXPATHLEN]; 1132 char TS[TIMESTAMP_LEN]; 1133 1134 /* 1135 * Auditing already disabled? 1136 */ 1137 if (audit_get_cond(&cond) != 0) 1138 return (-1); 1139 if (cond == AUC_NOAUDIT) 1140 return (0); 1141 1142 /* 1143 * Generate audit shutdown record. 1144 */ 1145 (void) auditd_gen_record(AUE_audit_shutdown, NULL); 1146 1147 /* 1148 * Shutdown auditing in the kernel. 1149 */ 1150 cond = AUC_DISABLED; 1151 if (audit_set_cond(&cond) != 0) 1152 return (-1); 1153 #ifdef __BSM_INTERNAL_NOTIFY_KEY 1154 notify_post(__BSM_INTERNAL_NOTIFY_KEY); 1155 #endif 1156 1157 /* 1158 * Rename last audit trail and remove 'current' link. 1159 */ 1160 len = readlink(AUDIT_CURRENT_LINK, oldname, MAXPATHLEN - 1); 1161 if (len < 0) 1162 return (-1); 1163 oldname[len++] = '\0'; 1164 1165 if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0) 1166 return (-1); 1167 1168 strlcpy(newname, oldname, len); 1169 1170 if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) { 1171 memcpy(ptr, TS, POSTFIX_LEN); 1172 if (rename(oldname, newname) != 0) 1173 return (-1); 1174 } else 1175 return (-1); 1176 1177 (void) unlink(AUDIT_CURRENT_LINK); 1178 1179 return (0); 1180 } 1181