4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
24 * private interfaces for auditd plugins and auditd.
27 #include <bsm/audit.h>
28 #include <bsm/audit_record.h>
29 #include <bsm/audit_uevents.h>
30 #include <bsm/libbsm.h>
40 #include <sys/types.h>
44 #include "audit_plugin.h"
46 static char auditwarn
[] = "/etc/security/audit_warn";
47 static pthread_mutex_t syslog_lock
;
52 (void) pthread_mutex_init(&syslog_lock
, NULL
);
56 * audit_syslog() -- generate syslog messages from threads that use
57 * different severity, facility code, and application names.
59 * syslog(3C) is thread safe, but the set openlog() / syslog() /
62 * Assumption: the app_name and facility code are paired, i.e.,
63 * if the facility code for this call is the same as for the
64 * the previous, the app_name hasn't changed.
67 __audit_syslog(const char *app_name
, int flags
, int facility
, int severity
,
70 static pthread_once_t once_control
= PTHREAD_ONCE_INIT
;
71 static int logopen
= 0;
72 static int prev_facility
= -1;
74 (void) pthread_once(&once_control
, init_syslog_mutex
);
76 (void) pthread_mutex_lock(&syslog_lock
);
77 if (prev_facility
!= facility
) {
80 openlog(app_name
, flags
, facility
);
81 syslog(severity
, "%s", message
);
82 (void) pthread_mutex_unlock(&syslog_lock
);
84 syslog(severity
, "%s", message
);
85 (void) pthread_mutex_unlock(&syslog_lock
);
90 * __audit_dowarn - invoke the shell script auditwarn to notify the
91 * adminstrator about a given problem.
93 * option - what the problem is
94 * text - when used with options soft and hard: which file was being
95 * used when the filesystem filled up
96 * when used with the plugin option: error detail
97 * count - used with various options: how many times auditwarn has
98 * been called for this problem since it was last cleared.
101 __audit_dowarn(char *option
, char *text
, int count
)
109 if ((pid
= fork1()) == -1) {
110 __audit_syslog("auditd", LOG_PID
| LOG_ODELAY
| LOG_CONS
,
111 LOG_DAEMON
, LOG_ALERT
, gettext("audit_warn fork failed\n"));
115 (void) waitpid(pid
, &st
, 0);
118 (void) snprintf(countstr
, 5, "%d", count
);
122 if (strcmp(option
, "soft") == 0 || strcmp(option
, "hard") == 0)
123 (void) execl(auditwarn
, auditwarn
, option
, text
, 0);
125 else if (strcmp(option
, "allhard") == 0)
126 (void) execl(auditwarn
, auditwarn
, option
, countstr
, 0);
127 else if (strcmp(option
, "plugin") == 0)
128 (void) execl(auditwarn
, auditwarn
, option
, text
, countstr
, 0);
130 (void) execl(auditwarn
, auditwarn
, option
, 0);
134 if (strcmp(option
, "soft") == 0)
135 (void) snprintf(warnstring
, 80,
136 gettext("soft limit in %s.\n"), text
);
137 else if (strcmp(option
, "hard") == 0)
138 (void) snprintf(warnstring
, 80,
139 gettext("hard limit in %s.\n"), text
);
140 else if (strcmp(option
, "allhard") == 0)
141 (void) sprintf(warnstring
,
142 gettext("All audit filesystems are full.\n"));
144 (void) snprintf(warnstring
, 80,
145 gettext("error %s.\n"), option
);
147 __audit_syslog("auditd", LOG_PID
| LOG_ODELAY
| LOG_CONS
, LOG_AUTH
,
148 LOG_ALERT
, (const char *)warnstring
);
154 * __audit_dowarn2 - invoke the shell script auditwarn to notify the
155 * adminstrator about a given problem.
157 * option - what the problem is
158 * name - entity reporting the problem (ie, plugin name)
159 * error - error string
160 * text - when used with options soft and hard: which file was being
161 * used when the filesystem filled up
162 * when used with the plugin option: error detail
163 * count - used with various options: how many times auditwarn has
164 * been called for this problem since it was last cleared.
167 __audit_dowarn2(char *option
, char *name
, char *error
, char *text
, int count
)
173 char empty
[4] = "...";
176 if ((pid
= fork()) == -1) {
177 __audit_syslog("auditd", LOG_PID
| LOG_ODELAY
| LOG_CONS
,
178 LOG_DAEMON
, LOG_ALERT
, gettext("audit_warn fork failed\n"));
182 (void) waitpid(pid
, &st
, 0);
185 (void) snprintf(countstr
, 5, "%d", count
);
186 if ((text
== NULL
) || (*text
== '\0'))
188 if ((name
== NULL
) || (*name
== '\0'))
191 (void) execl(auditwarn
, auditwarn
, option
, name
, error
, text
,
197 (void) snprintf(warnstring
, 80,
198 gettext("%s plugin error: %s\n"), name
, text
);
200 __audit_syslog("auditd", LOG_PID
| LOG_ODELAY
| LOG_CONS
, LOG_AUTH
,
201 LOG_ALERT
, (const char *)warnstring
);
207 * logpost - post the new audit log file name.
209 * Entry name = active audit.log file name
210 * NULL, if checking writability (auditd),
211 * changing audit log files, error, or exiting (binfile).
214 * 1 = system error -- errno
215 * audit_warn called with the specific error
219 __logpost(char *name
)
223 if (unlink(BINFILE_FILE
) != 0 &&
227 __audit_dowarn("tmpfile", strerror(errno
), 0);
231 if (name
== NULL
|| *name
== '\0') {
232 /* audit_binfile not active, no file pointer */
235 if (symlink(name
, BINFILE_FILE
) != 0) {
238 __audit_dowarn("tmpfile", strerror(errno
), 0);
247 * debug use - open a file for auditd and its plugins for debug
250 __auditd_debug_file_open() {
251 static FILE *fp
= NULL
;
255 if ((fp
= fopen("/var/audit/dump", "aF")) == NULL
)
256 (void) fprintf(stderr
, "failed to open debug file: %s\n",