From owner-p4-projects@FreeBSD.ORG Wed Feb 4 05:46:27 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 382C51065674; Wed, 4 Feb 2009 05:46:27 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E12AC1065672 for ; Wed, 4 Feb 2009 05:46:26 +0000 (UTC) (envelope-from sson@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id CEAAF8FC1B for ; Wed, 4 Feb 2009 05:46:26 +0000 (UTC) (envelope-from sson@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n145kQD9060160 for ; Wed, 4 Feb 2009 05:46:26 GMT (envelope-from sson@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n145kQMW060158 for perforce@freebsd.org; Wed, 4 Feb 2009 05:46:26 GMT (envelope-from sson@FreeBSD.org) Date: Wed, 4 Feb 2009 05:46:26 GMT Message-Id: <200902040546.n145kQMW060158@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sson@FreeBSD.org using -f From: Stacey Son To: Perforce Change Reviews Cc: Subject: PERFORCE change 157125 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Feb 2009 05:46:28 -0000 http://perforce.freebsd.org/chv.cgi?CH=157125 Change 157125 by sson@sson_amd64 on 2009/02/04 05:46:22 Add support for automatic audit trail file expiration. Trails can expire and be removed based on the age of the trail, the total disk used by all the trails, or a combination of both. Expiration is specified by the "expire-after" parameter in audit_control(5). The "filesz" parameter in audit_control(5) value can now use the suffixes 'K' (Kilobytes), 'M' (Megabytes), and 'G' (Gigabytes). For example, "2M" can be used instead of "2097152" for the filesz value. Affected files ... .. //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#14 edit .. //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#14 edit .. //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#11 edit .. //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#43 edit .. //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#13 edit .. //depot/projects/trustedbsd/openbsm/bsm/auditd_lib.h#4 edit .. //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#42 edit .. //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#4 edit .. //depot/projects/trustedbsd/openbsm/libbsm/au_control.3#10 edit .. //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#27 edit .. //depot/projects/trustedbsd/openbsm/man/audit_control.5#22 edit .. //depot/projects/trustedbsd/openbsm/man/auditon.2#15 edit .. //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#5 edit Differences ... ==== //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#14 (text+ko) ==== @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004 Apple Inc. +.\" Copyright (c) 2004-2009 Apple Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,9 +25,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#13 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#14 $ .\" -.Dd December 11, 2008 +.Dd January 29, 2009 .Dt AUDIT 8 .Os .Sh NAME @@ -35,7 +35,7 @@ .Nd audit management utility .Sh SYNOPSIS .Nm -.Fl i | n | s | t +.Fl e | i | n | s | t .Sh DESCRIPTION The .Nm @@ -43,6 +43,10 @@ One of the following flags is required as an argument to .Nm : .Bl -tag -width indent +.It Fl e +Forces the audit system to immmediately removed audit log files that +meet the expiration criteria specified in the audit control file without +doing a log rotation. .It Fl i Initializes and starts auditing. This option is currently for Mac OS X only @@ -53,6 +57,8 @@ .It Fl n Forces the audit system to close the existing audit log file and rotate to a new log file in a location specified in the audit control file. +Also, audit log files that meet the expiration criteria specified in the +audit control file will be removed. .It Fl s Specifies that the audit system should [re]synchronize its configuration from the audit control file. ==== //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#14 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005-2008 Apple Inc. + * Copyright (c) 2005-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#13 $ + * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#14 $ */ /* * Program to trigger the audit daemon with a message that is either: @@ -68,12 +68,15 @@ #include "auditd_control.h" /* - * XXX the following is temporary until this can be added to the kernel + * XXX The following are temporary until these can be added to the kernel * audit.h header. */ #ifndef AUDIT_TRIGGER_INITIALIZE #define AUDIT_TRIGGER_INITIALIZE 7 #endif +#ifndef AUDIT_TRIGGER_EXPIRE_TRAILS +#define AUDIT_TRIGGER_EXPIRE_TRAILS 8 +#endif static int send_trigger(unsigned int trigger) @@ -125,7 +128,7 @@ usage(void) { - (void)fprintf(stderr, "Usage: audit -i | -n | -s | -t \n"); + (void)fprintf(stderr, "Usage: audit -e | -i | -n | -s | -t \n"); exit(-1); } @@ -141,9 +144,13 @@ if (argc != 2) usage(); - while ((ch = getopt(argc, argv, "inst")) != -1) { + while ((ch = getopt(argc, argv, "einst")) != -1) { switch(ch) { + case 'e': + trigger = AUDIT_TRIGGER_EXPIRE_TRAILS; + break; + case 'i': trigger = AUDIT_TRIGGER_INITIALIZE; break; ==== //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#11 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Apple Inc. + * Copyright (c) 2005-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#10 $ + * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#11 $ */ #include @@ -236,3 +236,18 @@ return (auditwarnlog(args)); } + +/* + * Indicates that this trail file has expired and was removed. + */ +int +audit_warn_expired(char *filename) +{ + char *args[3]; + + args[0] = EXPIRED_WARN; + args[1] = filename; + args[2] = NULL; + + return (auditwarnlog(args)); +} ==== //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#43 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2008 Apple Inc. + * Copyright (c) 2004-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#42 $ + * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#43 $ */ #include @@ -67,12 +67,16 @@ #endif /* - * XXX the following is temporary until this can be added to the kernel + * XXX The following are temporary until these can be added to the kernel * audit.h header. */ #ifndef AUDIT_TRIGGER_INITIALIZE #define AUDIT_TRIGGER_INITIALIZE 7 #endif +#ifndef AUDIT_TRIGGER_EXPIRE_TRAILS +#define AUDIT_TRIGGER_EXPIRE_TRAILS 8 +#endif + /* * LaunchD flag (Mac OS X and, maybe, FreeBSD only.) See launchd(8) and @@ -275,6 +279,14 @@ return (-1); } + /* + * Finally, see if there are any trail files to expire. + */ + err = auditd_expire_trails(audit_warn_expired); + if (err) + auditd_log_err("auditd_expire_trails(): %s", + auditd_strerror(err)); + return (0); } @@ -550,6 +562,14 @@ audit_setup(); break; + case AUDIT_TRIGGER_EXPIRE_TRAILS: + auditd_log_info("Got audit expire trails trigger"); + err = auditd_expire_trails(audit_warn_expired); + if (err) + auditd_log_err("auditd_expire_trails(): %s", + auditd_strerror(err)); + break; + default: auditd_log_err("Got unknown trigger %d", trigger); break; @@ -669,13 +689,18 @@ */ err = auditd_set_host(); if (err) { - auditd_log_err("auditd_set_host() %s: %m", - auditd_strerror(err)); - ret = -1; + if (err == ADE_PARSE) { + auditd_log_notice( + "audit_control(5) may be missing 'host:' field"); + } else { + auditd_log_err("auditd_set_host() %s: %m", + auditd_strerror(err)); + ret = -1; + } } else auditd_log_debug( "Set audit host address information in kernel."); - + return (ret); } ==== //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#13 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Apple Inc. + * Copyright (c) 2005-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#12 $ + * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#13 $ */ #ifndef _AUDITD_H_ @@ -57,6 +57,7 @@ #define POSTSIGTERM_WARN "postsigterm" #define SOFTLIM_WARN "soft" #define TMPFILE_WARN "tmpfile" +#define EXPIRED_WARN "expired" #define AUDITWARN_SCRIPT "/etc/security/audit_warn" #define AUDITD_PIDFILE "/var/run/auditd.pid" @@ -76,6 +77,7 @@ int audit_warn_postsigterm(void); int audit_warn_soft(char *filename); int audit_warn_tmpfile(void); +int audit_warn_expired(char *filename); void auditd_openlog(int debug, gid_t gid); void auditd_log_err(const char *fmt, ...); ==== //depot/projects/trustedbsd/openbsm/bsm/auditd_lib.h#4 (text+ko) ==== @@ -26,7 +26,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bsm/auditd_lib.h#3 $ + * $P4: //depot/projects/trustedbsd/openbsm/bsm/auditd_lib.h#4 $ */ #ifndef _BSM_AUDITD_LIB_H_ @@ -81,12 +81,14 @@ #define ADE_INVAL -16 /* Invalid argument. */ #define ADE_GETADDR -17 /* Error resolving address from hostname. */ #define ADE_ADDRFAM -18 /* Address family not supported. */ +#define ADE_EXPIRE -19 /* Error expiring audit trail files. */ /* * auditd_lib functions. */ const char *auditd_strerror(int errcode); int auditd_set_minfree(void); +int auditd_expire_trails(int (*warn_expired)(char *)); int auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *)); void auditd_close_dirs(void); int auditd_set_evcmap(void); ==== //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#42 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2008 Apple Inc. + * Copyright (c) 2004-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#41 $ + * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#42 $ */ #ifndef _LIBBSM_H_ @@ -76,13 +76,14 @@ #define AUDIT_CONTROL_FILE "/etc/security/audit_control" #define AUDIT_USER_FILE "/etc/security/audit_user" -#define DIR_CONTROL_ENTRY "dir" -#define MINFREE_CONTROL_ENTRY "minfree" -#define FILESZ_CONTROL_ENTRY "filesz" -#define FLAGS_CONTROL_ENTRY "flags" -#define NA_CONTROL_ENTRY "naflags" -#define POLICY_CONTROL_ENTRY "policy" +#define DIR_CONTROL_ENTRY "dir" +#define MINFREE_CONTROL_ENTRY "minfree" +#define FILESZ_CONTROL_ENTRY "filesz" +#define FLAGS_CONTROL_ENTRY "flags" +#define NA_CONTROL_ENTRY "naflags" +#define POLICY_CONTROL_ENTRY "policy" #define AUDIT_HOST_CONTROL_ENTRY "host" +#define EXPIRE_AFTER_CONTROL_ENTRY "expire-after" #define AU_CLASS_NAME_MAX 8 #define AU_CLASS_DESC_MAX 72 @@ -766,6 +767,7 @@ int getacna(char *auditstr, int len); int getacpol(char *auditstr, size_t len); int getachost(char *auditstr, size_t len); +int getacexpire(int *andflg, time_t *age, size_t *size); int getauditflagsbin(char *auditstr, au_mask_t *masks); int getauditflagschar(char *auditstr, au_mask_t *masks, int verbose); ==== //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#4 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008 Apple Inc. + * Copyright (c) 2008-2009 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#3 $ + * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#4 $ */ #include @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,11 @@ #define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 #endif +/* + * Number of seconds to January 1, 2000 + */ +#define JAN_01_2000 946598400 + struct dir_ent { char *dirname; uint8_t softlim; @@ -85,6 +91,13 @@ }; static TAILQ_HEAD(, dir_ent) dir_q; + +struct audit_trail { + time_t at_mtime; + char *at_path; + off_t at_size; +}; + static int auditd_minval = -1; static char auditd_host[MAXHOSTNAMELEN]; @@ -110,6 +123,7 @@ "invalid argument", /* ADE_INVAL (16) */ "could not resolve hostname to address", /* ADE_GETADDR (17) */ "address family not supported", /* ADE_ADDRFAM (18) */ + "error expiring audit trail files", /* ADE_EXPIRE (19) */ }; #define MAXERRCODE (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0])) @@ -295,6 +309,187 @@ } /* + * Comparison function for audit trail sorting. Compare modification times + * of trail files. + */ +static int +trails_cmp(const void *t1, const void *t2) +{ + struct audit_trail *a = (struct audit_trail *)t1; + struct audit_trail *b = (struct audit_trail *)t2; + + if (a->at_mtime < b->at_mtime) + return (-1); + if (a->at_mtime > b->at_mtime) + return (1); + return (0); +} + +/* + * Remove audit trails files according to the expiration conditions. Returns: + * ADE_NOERR on success or there is nothing to do. + * ADE_PARSE if error parsing audit_control(5). + * ADE_NOMEM if could not allocate memory. + * ADE_EXPIRE if there was an unespected error. + */ +int +auditd_expire_trails(int (*warn_expired)(char *)) +{ + int andflg, i, n = 0, num_trails = 0, ret = ADE_NOERR; + size_t expire_size, total_size = 0L; + time_t expire_age, oldest_time, current_time = time(NULL); + struct dir_ent *traildir; + struct audit_trail *trail; + char *afnp, *pn; + struct stat stbuf; + char activefn[MAXPATHLEN]; + + /* + * Read the expiration conditions. If no conditions then return no + * error. + */ + if (getacexpire(&andflg, &expire_age, &expire_size) < 0) + return (ADE_PARSE); + if (!expire_age && !expire_size) + return (ADE_NOERR); + + /* + * Read the 'current' trail file name. Trim off directory path. + */ + activefn[0] = '\0'; + readlink(AUDIT_CURRENT_LINK, activefn, MAXPATHLEN - 1); + if ((afnp = strrchr(activefn, '/')) != NULL) + afnp++; + + /* + * Count up the number of audit trail files we have in all the audit + * trail directories. + */ + num_trails = 0; + TAILQ_FOREACH(traildir, &dir_q, dirs) { + if (stat(traildir->dirname, &stbuf) == 0) + num_trails += (stbuf.st_nlink - 2); + } + + trail = (struct audit_trail *)malloc(sizeof(struct audit_trail) * + num_trails); + if (NULL == trail) + return (ADE_NOMEM); + + /* + * Build an array of the trail files. + */ + TAILQ_FOREACH(traildir, &dir_q, dirs) { + DIR *dirp; + struct dirent *dp; + + dirp = opendir(traildir->dirname); + while ((dp = readdir(dirp)) != NULL) { + + /* + * Filter non-trail files. + */ + if (dp->d_type != DT_REG || + dp->d_namlen != (FILENAME_LEN - 1) || + dp->d_name[POSTFIX_LEN] != '.') + continue; + + + if (n > num_trails) { + /* + * This shouldn't happen but, if it does, we + * break out of the loop and expire what trail + * files we have. Also, return there was an + * error. + */ + ret = ADE_EXPIRE; + break; + } + + if (asprintf(&pn, "%s/%s", traildir->dirname, + dp->d_name) < 0) { + ret = ADE_NOMEM; + break; + } + + if (stat(pn, &stbuf) < 0) { + free(pn); + continue; + } + + /* + * If the mtime is older than Jan 1, 2000 then update + * the mtime of the trail file to the current time. + * This is so we don't prematurely remove a trail file + * that was created while the system clock reset to the + * "beginning of time" but later the system clock is set + * to the correct current time. + */ + if (current_time >= JAN_01_2000 && + stbuf.st_mtime < JAN_01_2000) { + struct timeval tv[2]; + + stbuf.st_mtime = current_time; + TIMESPEC_TO_TIMEVAL(&tv[0], + &stbuf.st_atimespec); + TIMESPEC_TO_TIMEVAL(&tv[1], + &stbuf.st_mtimespec); + utimes(pn, tv); + } + + total_size += stbuf.st_size; + if (NULL != afnp && + strncmp(dp->d_name, afnp, FILENAME_LEN) == 0) { + free(pn); + continue; + } + + trail[n].at_mtime = stbuf.st_mtime; + trail[n].at_size = stbuf.st_size; + trail[n].at_path = pn; + n++; + } + } + + /* + * Sort the array of trail files by the modification date. + */ + qsort(trail, n, sizeof(struct audit_trail), trails_cmp); + + oldest_time = current_time - expire_age; + + /* + * Expire trail files, oldest (mtime) first, if the given + * conditions are met. + */ + for (i = 0; i < n; i++) { + if (andflg) { + if ((expire_size && total_size > expire_size) && + (expire_age && trail[i].at_mtime < oldest_time)) { + if (warn_expired) + (*warn_expired)(trail[i].at_path); + if (unlink(trail[i].at_path) < 0) + ret = ADE_EXPIRE; + total_size -= trail[i].at_size; + } + } else { + if ((expire_size && total_size > expire_size) || + (expire_age && trail[i].at_mtime < oldest_time)) { + if (warn_expired) + (*warn_expired)(trail[i].at_path); + if (unlink(trail[i].at_path) < 0) + ret = ADE_EXPIRE; + total_size -= trail[i].at_size; + } + } + free(trail[i].at_path); + } + free(trail); + + return (ret); +} + +/* * Parses the "dir" entry in audit_control(5) into an ordered list. Also, will * set the minfree and host values if not already set. Arguments include * function pointers to audit_warn functions for soft and hard limits. Returns: @@ -562,7 +757,7 @@ } /* Try until we succeed. */ - while ((dirent = TAILQ_FIRST(&dir_q))) { + TAILQ_FOREACH(dirent, &dir_q, dirs) { if (dirent->hardlim) continue; if ((fn = affixdir(timestr, dirent)) == NULL) ==== //depot/projects/trustedbsd/openbsm/libbsm/au_control.3#10 (text+ko) ==== @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_control.3#9 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_control.3#10 $ .\" .Dd April 19, 2005 .Dt AU_CONTROL 3 @@ -33,6 +33,7 @@ .Nm endac , .Nm getacdir , .Nm getacmin , +.Nm getacexpire , .Nm getacfilesz , .Nm getacflg , .Nm getacna , @@ -53,6 +54,8 @@ .Ft int .Fn getacmin "int *min_val" .Ft int +.Fn getacexpire "int *andflg, time_t *age, size_t *size" +.Ft int .Fn getacfilesz "size_t *size_val" .Ft int .Fn getacflg "char *auditstr" "int len" @@ -101,6 +104,24 @@ variable. .Pp The +.Fn getacexpire +function +returns the audit trail file expiration parameters in the passed +.Vt int +buffer +.Fa andflg , +.Vt time_t +buffer +.Fa age +and +.Vt size_t +buffer +.Fa size . +If the parameter is not specified in the +.Xr audit_control 5 +file it is set to zero. +.Pp +The .Fn getacfilesz function returns the audit trail rotation size in the passed @@ -153,6 +174,7 @@ The .Fn getacdir , .Fn getacmin , +.Fn getacexpire , .Fn getacflg , .Fn getacna , .Fn getacpol , ==== //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#27 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2004,2009 Apple Inc. * Copyright (c) 2006 Robert N. M. Watson * All rights reserved. * @@ -27,13 +27,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#26 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#27 $ */ #include #include +#include #include #include #ifdef HAVE_PTHREAD_MUTEX_LOCK @@ -138,6 +139,82 @@ } /* + * Convert a given time value with a multiplier (seconds, hours, days, years) to + * seconds. Return 0 on success. + */ +static int +au_timetosec(time_t *seconds, u_long value, char mult) +{ + if (NULL == seconds) + return (-1); + + switch(mult) { + case 's': + /* seconds */ + *seconds = (time_t)value; + break; + + case 'h': + /* hours */ + *seconds = (time_t)value * 60 * 60; + break; + + case 'd': + /* days */ + *seconds = (time_t)value * 60 * 60 * 24; + break; + + case 'y': + /* years. Add a day for each 4th (leap) year. */ + *seconds = (time_t)value * 60 * 60 * 24 * 364 + + ((time_t)value / 4) * 60 * 60 * 24; + break; + + default: + return (-1); + } + return (0); +} + +/* + * Convert a given disk space value with a multiplier (bytes, kilobytes, + * megabytes, gigabytes) to bytes. Return 0 on success. + */ +static int +au_spacetobytes(size_t *bytes, u_long value, char mult) +{ + if (NULL == bytes) + return (-1); + + switch(mult) { + case 'B': + case ' ': + /* Bytes */ + *bytes = (size_t)value; + break; + + case 'K': + /* Kilobytes */ + *bytes = (size_t)value * 1024; + break; + + case 'M': + /* Megabytes */ + *bytes = (size_t)value * 1024 * 1024; + break; + + case 'G': + /* Gigabytes */ + *bytes = (size_t)value * 1024 * 1024 * 1024; + break; + + default: + return (-1); + } + return (0); +} + +/* * Convert a policy to a string. Return -1 on failure, or >= 0 representing * the actual size of the string placed in the buffer (excluding terminating * nul). @@ -333,46 +410,65 @@ int getacfilesz(size_t *filesz_val) { - char *filesz, *dummy; - long long ll; + char *str; + size_t val; + char mult; + int nparsed; #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); #endif setac_locked(); - if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &filesz) < 0) { + if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); #endif return (-2); } - if (filesz == NULL) { + if (str == NULL) { #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); #endif errno = EINVAL; return (1); } - ll = strtoll(filesz, &dummy, 10); - if (*dummy != '\0') { + + /* Trim off any leading white space. */ + while (*str == ' ' || *str == '\t') + str++; + + nparsed = sscanf(str, "%lu%c", &val, &mult); + + switch (nparsed) { + case 1: + /* If no multiplier then assume 'B' (bytes). */ + mult = 'B'; + /* fall through */ + case 2: + if (au_spacetobytes(filesz_val, val, mult) == 0) + break; + /* fall through */ + default: + errno = EINVAL; #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); #endif - errno = EINVAL; return (-1); } + /* * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 * indicates no rotation size. */ - if (ll < 0 || (ll > 0 && ll < MIN_AUDIT_FILE_SIZE)) { + if (*filesz_val < 0 || (*filesz_val > 0 && + *filesz_val < MIN_AUDIT_FILE_SIZE)) { #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); #endif + filesz_val = 0L; errno = EINVAL; return (-1); } - *filesz_val = ll; #ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); #endif @@ -523,3 +619,105 @@ #endif return (0); } + +/* + * Set expiration conditions. + */ +static int +setexpirecond(time_t *age, size_t *size, u_long value, char mult) +{ + + if (isupper(mult) || ' ' == mult) + return (au_spacetobytes(size, value, mult)); + else + return (au_timetosec(age, value, mult)); +} + +/* + * Return the expire-after field from the audit control file. + */ +int +getacexpire(int *andflg, time_t *age, size_t *size) +{ + char *str; + int nparsed; + u_long val1, val2; + char mult1, mult2; + char andor[AU_LINE_MAX]; + + *age = 0L; + *size = 0LL; + *andflg = 0; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_lock(&mutex); +#endif + setac_locked(); + if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-2); + } + if (str == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (1); + } + + /* First, trim off any leading white space. */ + while (*str == ' ' || *str == '\t') + str++; + + nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, + andor, &val2, &mult2); + + switch (nparsed) { + case 1: + /* If no multiplier then assume 'B' (Bytes). */ + mult1 = 'B'; + /* fall through */ + case 2: + /* One expiration condition. */ + if (setexpirecond(age, size, val1, mult1) != 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + break; + + case 5: + /* Two expiration conditions. */ + if (setexpirecond(age, size, val1, mult1) != 0 || + setexpirecond(age, size, val2, mult2) != 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + if (strcasestr(andor, "and") != NULL) + *andflg = 1; + else if (strcasestr(andor, "or") != NULL) + *andflg = 0; + else { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + break; + + default: +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (0); +} ==== //depot/projects/trustedbsd/openbsm/man/audit_control.5#22 (text+ko) ==== @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004 Apple Inc. +.\" Copyright (c) 2004-2009 Apple Inc. .\" Copyright (c) 2006 Robert N. M. Watson .\" All rights reserved. .\" @@ -26,9 +26,9 @@ .\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" >>> TRUNCATED FOR MAIL (1000 lines) <<<