static int create_af_unix_socket(const char *path, int mode) { struct sockaddr_un addr; socklen_t len; int rc, cmd; sock = socket(PF_UNIX, SOCK_STREAM, 0); if (sock < 0) { syslog(LOG_ERR, "Couldn't open af_unix socket (%s)", strerror(errno)); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(&addr.sun_path[0], path); len = sizeof(addr); rc = bind(sock, (const struct sockaddr *)&addr, len); if (rc < 0) { syslog(LOG_ERR, "Couldn't bind af_unix socket (%s)", strerror(errno)); destroy_af_unix(); return -1; } if (mode != -1) { rc = chmod(path, mode); if (rc < 0) { syslog(LOG_ERR, "Couldn't chmod %s to %04o (%s)", path, mode, strerror(errno)); destroy_af_unix(); return -1; } } // Put socket in nonblock mode cmd = fcntl(sock, F_GETFL); fcntl(sock, F_SETFL, cmd|FNDELAY); // don't leak the descriptor cmd = fcntl(sock, F_GETFD); fcntl(sock, F_SETFD, cmd|FD_CLOEXEC); // Make socket listening...won't block (void)listen(sock, 5); // Register socket with poll add_event(sock, af_unix_accept); return 0; }
void stop_builtin(plugin_conf_t *conf) { if (conf->type == S_AF_UNIX) destroy_af_unix(); else if (conf->type == S_SYSLOG) destroy_syslog(); else syslog(LOG_ERR, "Unknown builtin %s", conf->path); }
static void init_af_unix(const plugin_conf_t *conf) { int i = 1, mode = -1; char *base = NULL; // while args while (conf->args[i]) { int rc, bad = 0; // is all nums - do mode base = conf->args[i]; while (*base) { if (!isdigit(*base)) { bad = 1; break; } base++; } if (!bad) { errno = 0; mode = strtoul(conf->args[i], NULL, 8); if (errno) { syslog(LOG_ERR, "Error converting %s (%s)", conf->args[i], strerror(errno)); mode = -1; bad = 1; } else if (path) { rc = chmod(path, mode); if (rc < 0) { syslog(LOG_ERR, "Couldn't chmod %s to %04o (%s)", conf->args[i], mode, strerror(errno)); destroy_af_unix(); return; } } } else { // else check for '/' base = strchr(conf->args[i], '/'); if (base) { // get dirname DIR *d; char *dir = strdup(conf->args[i]); base = dirname(dir); d = opendir(base); if (d) { closedir(d); unlink(conf->args[i]); if (create_af_unix_socket( conf->args[i], mode)<0) { free(dir); return; } path = strdup(conf->args[i]); bad = 0; } else syslog(LOG_ERR, "Couldn't open %s (%s)", base, strerror(errno)); free(dir); } else syslog(LOG_ERR, "Malformed path %s", conf->args[i]); } if (bad) { destroy_af_unix(); return; } i++; } syslog(LOG_INFO, "af_unix plugin initialized"); }
int main(int argc, char *argv[]) { lnode *conf; struct sigaction sa; int i; #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 4; } #endif set_aumessage_mode(MSG_SYSLOG, DBG_YES); /* Register sighandlers */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); /* Ignore all signals by default */ sa.sa_handler = SIG_IGN; for (i=1; i<NSIG; i++) sigaction(i, &sa, NULL); /* Set handler for the ones we care about */ sa.sa_handler = term_handler; sigaction(SIGTERM, &sa, NULL); sa.sa_handler = hup_handler; sigaction(SIGHUP, &sa, NULL); sa.sa_handler = alarm_handler; sigaction(SIGALRM, &sa, NULL); sa.sa_handler = child_handler; sigaction(SIGCHLD, &sa, NULL); /* move stdin to its own fd */ if (argc == 3 && strcmp(argv[1], "--input") == 0) audit_fd = open(argv[2], O_RDONLY); else audit_fd = dup(0); if (audit_fd < 0) { syslog(LOG_ERR, "Failed setting up input, exiting"); return 1; } /* Make all descriptors point to dev null */ i = open("/dev/null", O_RDWR); if (i >= 0) { if (dup2(0, i) < 0 || dup2(1, i) < 0 || dup2(2, i) < 0) { syslog(LOG_ERR, "Failed duping /dev/null %s, exiting", strerror(errno)); return 1; } close(i); } else { syslog(LOG_ERR, "Failed opening /dev/null %s, exiting", strerror(errno)); return 1; } if (fcntl(audit_fd, F_SETFD, FD_CLOEXEC) < 0) { syslog(LOG_ERR, "Failed protecting input %s, exiting", strerror(errno)); return 1; } /* init the daemon's config */ if (load_config(&daemon_config, config_file)) return 6; load_plugin_conf(&plugin_conf); /* if no plugins - exit */ if (plist_count(&plugin_conf) == 0) { syslog(LOG_ERR, "No plugins found, exiting"); return 0; } /* Plugins are started with the auditd priority */ i = start_plugins(&plugin_conf); /* Now boost priority to make sure we are getting time slices */ if (daemon_config.priority_boost != 0) { errno = 0; (void) nice((int)-daemon_config.priority_boost); if (errno) { syslog(LOG_ERR, "Cannot change priority (%s)", strerror(errno)); /* Stay alive as this is better than stopping */ } } /* Let the queue initialize */ init_queue(daemon_config.q_depth); syslog(LOG_NOTICE, "audispd initialized with q_depth=%d and %d active plugins", daemon_config.q_depth, i); /* Tell it to poll the audit fd */ if (add_event(audit_fd, process_inbound_event) < 0) { syslog(LOG_ERR, "Cannot add event, exiting"); return 1; } /* Create inbound thread */ pthread_create(&inbound_thread, NULL, inbound_thread_main, NULL); /* Start event loop */ while (event_loop()) { hup = 0; reconfigure(); } /* Tell plugins we are going down */ signal_plugins(SIGTERM); /* Cleanup builtin plugins */ destroy_af_unix(); destroy_syslog(); /* Give it 5 seconds to clear the queue */ alarm(5); pthread_join(inbound_thread, NULL); /* Release configs */ plist_first(&plugin_conf); conf = plist_get_cur(&plugin_conf); while (conf) { free_pconfig(conf->p); conf = plist_next(&plugin_conf); } plist_clear(&plugin_conf); /* Cleanup the queue */ destroy_queue(); free_config(&daemon_config); return 0; }