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