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