2 * audispd-builtins.c - some common builtin plugins
3 * Copyright (c) 2007,2010,2013 Red Hat Inc., Durham, North Carolina.
6 * This software may be freely redistributed and/or modified under the
7 * terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2, or (at your option) any
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Steve Grubb <sgrubb@redhat.com>
35 #include "audispd-pconfig.h"
36 #include "audispd-builtins.h"
39 static volatile int sock = -1, conn = -1;
40 static int syslog_started = 0, priority;
41 static char *path = NULL;
44 static void init_af_unix(const plugin_conf_t *conf);
45 static void init_syslog(const plugin_conf_t *conf);
48 void start_builtin(plugin_conf_t *conf)
50 if (strcasecmp("builtin_af_unix", conf->path) == 0) {
51 conf->type = S_AF_UNIX;
53 } else if (strcasecmp("builtin_syslog", conf->path) == 0) {
54 conf->type = S_SYSLOG;
57 syslog(LOG_ERR, "Unknown builtin %s", conf->path);
60 void stop_builtin(plugin_conf_t *conf)
62 if (conf->type == S_AF_UNIX)
64 else if (conf->type == S_SYSLOG)
67 syslog(LOG_ERR, "Unknown builtin %s", conf->path);
70 static void af_unix_accept(int fd)
75 conn = accept(fd, NULL, NULL);
76 } while (conn < 0 && errno == EINTR);
78 // De-register since this is intended to be one listener
81 cmd = fcntl(conn, F_GETFD);
82 fcntl(conn, F_SETFD, cmd|FD_CLOEXEC);
85 static int create_af_unix_socket(const char *path, int mode)
87 struct sockaddr_un addr;
91 sock = socket(PF_UNIX, SOCK_STREAM, 0);
93 syslog(LOG_ERR, "Couldn't open af_unix socket (%s)",
97 memset(&addr, 0, sizeof(addr));
98 addr.sun_family = AF_UNIX;
99 strcpy(&addr.sun_path[0], path);
101 rc = bind(sock, (const struct sockaddr *)&addr, len);
103 syslog(LOG_ERR, "Couldn't bind af_unix socket (%s)",
109 rc = chmod(path, mode);
111 syslog(LOG_ERR, "Couldn't chmod %s to %04o (%s)",
112 path, mode, strerror(errno));
118 // Put socket in nonblock mode
119 cmd = fcntl(sock, F_GETFL);
120 fcntl(sock, F_SETFL, cmd|FNDELAY);
122 // don't leak the descriptor
123 cmd = fcntl(sock, F_GETFD);
124 fcntl(sock, F_SETFD, cmd|FD_CLOEXEC);
126 // Make socket listening...won't block
127 (void)listen(sock, 5);
129 // Register socket with poll
130 add_event(sock, af_unix_accept);
134 static void init_af_unix(const plugin_conf_t *conf)
136 int i = 1, mode = -1;
140 while (conf->args[i]) {
143 // is all nums - do mode
144 base = conf->args[i];
146 if (!isdigit(*base)) {
154 mode = strtoul(conf->args[i], NULL, 8);
156 syslog(LOG_ERR, "Error converting %s (%s)",
157 conf->args[i], strerror(errno));
161 rc = chmod(path, mode);
164 "Couldn't chmod %s to %04o (%s)",
172 // else check for '/'
173 base = strchr(conf->args[i], '/');
177 char *dir = strdup(conf->args[i]);
182 unlink(conf->args[i]);
183 if (create_af_unix_socket(
184 conf->args[i], mode)<0) {
188 path = strdup(conf->args[i]);
191 syslog(LOG_ERR, "Couldn't open %s (%s)",
192 base, strerror(errno));
195 syslog(LOG_ERR, "Malformed path %s",
204 syslog(LOG_INFO, "af_unix plugin initialized");
207 void send_af_unix_string(const char *s, unsigned int len)
215 rc = write(conn, s, len);
216 } while (rc < 0 && errno == EINTR);
217 if (rc < 0 && errno == EPIPE) {
220 add_event(sock, af_unix_accept);
225 void send_af_unix_binary(event_t *e)
234 vec[0].iov_base = &e->hdr;
235 vec[0].iov_len = sizeof(struct audit_dispatcher_header);
236 vec[1].iov_base = e->data;
237 vec[1].iov_len = MAX_AUDIT_MESSAGE_LENGTH;
239 rc = writev(conn, vec, 2);
240 } while (rc < 0 && errno == EINTR);
241 if (rc < 0 && errno == EPIPE) {
244 add_event(sock, af_unix_accept);
249 void destroy_af_unix(void)
266 static void init_syslog(const plugin_conf_t *conf)
268 int i, facility = LOG_USER;
271 for (i = 1; i<3; i++) {
273 if (strcasecmp(conf->args[i], "LOG_DEBUG") == 0)
274 priority = LOG_DEBUG;
275 else if (strcasecmp(conf->args[i], "LOG_INFO") == 0)
277 else if (strcasecmp(conf->args[i], "LOG_NOTICE") == 0)
278 priority = LOG_NOTICE;
279 else if (strcasecmp(conf->args[i], "LOG_WARNING") == 0)
280 priority = LOG_WARNING;
281 else if (strcasecmp(conf->args[i], "LOG_ERR") == 0)
283 else if (strcasecmp(conf->args[i], "LOG_CRIT") == 0)
285 else if (strcasecmp(conf->args[i], "LOG_ALERT") == 0)
286 priority = LOG_ALERT;
287 else if (strcasecmp(conf->args[i], "LOG_EMERG") == 0)
288 priority = LOG_EMERG;
289 else if (strcasecmp(conf->args[i], "LOG_LOCAL0") == 0)
290 facility = LOG_LOCAL0;
291 else if (strcasecmp(conf->args[i], "LOG_LOCAL1") == 0)
292 facility = LOG_LOCAL1;
293 else if (strcasecmp(conf->args[i], "LOG_LOCAL2") == 0)
294 facility = LOG_LOCAL2;
295 else if (strcasecmp(conf->args[i], "LOG_LOCAL3") == 0)
296 facility = LOG_LOCAL3;
297 else if (strcasecmp(conf->args[i], "LOG_LOCAL4") == 0)
298 facility = LOG_LOCAL4;
299 else if (strcasecmp(conf->args[i], "LOG_LOCAL5") == 0)
300 facility = LOG_LOCAL5;
301 else if (strcasecmp(conf->args[i], "LOG_LOCAL6") == 0)
302 facility = LOG_LOCAL6;
303 else if (strcasecmp(conf->args[i], "LOG_LOCAL7") == 0)
304 facility = LOG_LOCAL7;
307 "Unknown log priority/facility %s",
314 syslog(LOG_INFO, "syslog plugin initialized");
315 if (facility != LOG_USER)
316 openlog("audispd", 0, facility);
320 void send_syslog(const char *s)
323 syslog(priority, "%s", s);
326 void destroy_syslog(void)