From 835110044bd970518e10b28348ce6619818ce363 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 18 May 2008 18:35:35 +0200 Subject: Remove obsolete patches and files and move ulogd to repository top-level directory --- ulogd/ulogd.c | 826 ---------------------------------------------------------- 1 file changed, 826 deletions(-) delete mode 100644 ulogd/ulogd.c (limited to 'ulogd/ulogd.c') diff --git a/ulogd/ulogd.c b/ulogd/ulogd.c deleted file mode 100644 index 5707ef8..0000000 --- a/ulogd/ulogd.c +++ /dev/null @@ -1,826 +0,0 @@ -/* ulogd, Version $LastChangedRevision$ - * - * $Id$ - * - * userspace logging daemon for the iptables ULOG target - * of the linux 2.4 netfilter subsystem. - * - * (C) 2000-2003 by Harald Welte - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - * - * Modifications: - * 14 Jun 2001 Martin Josefsson - * - added SIGHUP handler for logfile cycling - * - * 10 Feb 2002 Alessandro Bono - * - added support for non-fork mode - * - added support for logging to stdout - * - * 09 Sep 2003 Magnus Boden - * - added support for more flexible multi-section conffile - * - * 20 Apr 2004 Nicolas Pougetoux - * - added suppurt for seteuid() - */ - -#define ULOGD_VERSION "1.23" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Size of the socket recevive memory. Should be at least the same size as the - * 'nlbufsiz' module loadtime parameter of ipt_ULOG.o - * If you have _big_ in-kernel queues, you may have to increase this number. ( - * --qthreshold 100 * 1500 bytes/packet = 150kB */ -#define ULOGD_RMEM_DEFAULT 131071 - -/* Size of the receive buffer for the netlink socket. Should be at least of - * RMEM_DEFAULT size. */ -#define ULOGD_BUFSIZE_DEFAULT 150000 - -#ifdef DEBUG -#define DEBUGP(format, args...) fprintf(stderr, format, ## args) -#else -#define DEBUGP(format, args...) -#endif - -/* default config parameters, if not changed in configfile */ -#ifndef ULOGD_LOGFILE_DEFAULT -#define ULOGD_LOGFILE_DEFAULT "/var/log/ulogd.log" -#endif -#ifndef ULOGD_NLGROUP_DEFAULT -#define ULOGD_NLGROUP_DEFAULT 32 -#endif - -/* where to look for the config file */ -#ifndef ULOGD_CONFIGFILE -#define ULOGD_CONFIGFILE "/etc/ulogd.conf" -#endif - -/* global variables */ -static struct ipulog_handle *libulog_h; /* our libipulog handle */ -static unsigned char* libulog_buf; /* the receive buffer */ -static FILE *logfile = NULL; /* logfile pointer */ -static char *ulogd_configfile = ULOGD_CONFIGFILE; - -/* linked list for all registered interpreters */ -static ulog_interpreter_t *ulogd_interpreters; - -/* linked list for all registered output targets */ -static ulog_output_t *ulogd_outputs; - -/*********************************************************************** - * INTERPRETER AND KEY HASH FUNCTIONS (new in 0.9) - ***********************************************************************/ - -/* We keep hashtables of interpreters and registered keys. The hash-tables - * are allocated dynamically at program load time. You may control the - * allocation granularity of both hashes (i.e. the amount of hashtable - * entries are allocated at one time) through modification of the constants - * INTERH_ALLOC_GRAN and KEYH_ALLOC_GRAN - */ - -/* allocation granularith */ -#define INTERH_ALLOC_GRAN 5 - -/* hashtable for all registered interpreters */ -static ulog_interpreter_t **ulogd_interh; - -/* current hashtable size */ -static unsigned int ulogd_interh_ids_alloc; - -/* total number of registered ids */ -static unsigned int ulogd_interh_ids; - -/* allocate a new interpreter id and write it into the interpreter struct */ -static unsigned int interh_allocid(ulog_interpreter_t *ip) -{ - unsigned int id; - - id = ++ulogd_interh_ids; - - if (id >= ulogd_interh_ids_alloc) { - if (!ulogd_interh) - ulogd_interh = (ulog_interpreter_t **) - malloc(INTERH_ALLOC_GRAN * - sizeof(ulog_interpreter_t)); - else - ulogd_interh = (ulog_interpreter_t **) - realloc(ulogd_interh, - (INTERH_ALLOC_GRAN + - ulogd_interh_ids_alloc) * - sizeof(ulog_interpreter_t)); - - ulogd_interh_ids_alloc += INTERH_ALLOC_GRAN; - } - - ip->id = id; - ulogd_interh[id] = ip; - return id; -} - -/* get interpreter id by name */ -unsigned int interh_getid(const char *name) -{ - unsigned int i; - for (i = 1; i <= ulogd_interh_ids; i++) - if (!strcmp(name, (ulogd_interh[i])->name)) - return i; - - return 0; -} - -#ifdef DEBUG -/* dump out the contents of the interpreter hash */ -static void interh_dump(void) -{ - unsigned int i; - - for (i = 1; i <= ulogd_interh_ids; i++) - ulogd_log(ULOGD_DEBUG, "ulogd_interh[%d] = %s\n", - i, (ulogd_interh[i])->name); - -} -#endif - -/* key hash allocation granularity */ -#define KEYH_ALLOC_GRAN 20 - -/* hash table for key ids */ -struct ulogd_keyh_entry *ulogd_keyh; - -/* current size of the hashtable */ -static unsigned int ulogd_keyh_ids_alloc; - -/* total number of registered keys */ -static unsigned int ulogd_keyh_ids; - -/* allocate a new key_id */ -static unsigned int keyh_allocid(ulog_interpreter_t *ip, unsigned int offset, - const char *name) -{ - unsigned int id; - - id = ++ulogd_keyh_ids; - - if (id >= ulogd_keyh_ids_alloc) { - if (!ulogd_keyh) { - ulogd_keyh = (struct ulogd_keyh_entry *) - malloc(KEYH_ALLOC_GRAN * - sizeof(struct ulogd_keyh_entry)); - if (!ulogd_keyh) { - ulogd_log(ULOGD_ERROR, "OOM!\n"); - return 0; - } - } else { - ulogd_keyh = (struct ulogd_keyh_entry *) - realloc(ulogd_keyh, (KEYH_ALLOC_GRAN - +ulogd_keyh_ids_alloc) * - sizeof(struct ulogd_keyh_entry)); - - if (!ulogd_keyh) { - ulogd_log(ULOGD_ERROR, "OOM!\n"); - return 0; - } - } - - ulogd_keyh_ids_alloc += KEYH_ALLOC_GRAN; - } - - ulogd_keyh[id].interp = ip; - ulogd_keyh[id].offset = offset; - ulogd_keyh[id].name = name; - - return id; -} - -#ifdef DEBUG -/* dump the keyhash to standard output */ -static void keyh_dump(void) -{ - unsigned int i; - - printf("dumping keyh\n"); - for (i = 1; i <= ulogd_keyh_ids; i++) - printf("ulogd_keyh[%lu] = %s:%u\n", i, - ulogd_keyh[i].interp->name, ulogd_keyh[i].offset); -} -#endif - -/* get keyid by name */ -unsigned int keyh_getid(const char *name) -{ - unsigned int i; - for (i = 1; i <= ulogd_keyh_ids; i++) - if (!strcmp(name, ulogd_keyh[i].name)) - return i; - - return 0; -} - -/* get key name by keyid */ -char *keyh_getname(unsigned int id) -{ - if (id > ulogd_keyh_ids) { - ulogd_log(ULOGD_NOTICE, - "keyh_getname called with invalid id%u\n", id); - return NULL; - } - - return ulogd_keyh[id].interp->name; -} - -/* get result for given key id. does not check if result valid */ -ulog_iret_t *keyh_getres(unsigned int id) -{ - ulog_iret_t *ret; - - if (id > ulogd_keyh_ids) { - ulogd_log(ULOGD_NOTICE, - "keyh_getres called with invalid id %d\n", id); - return NULL; - } - - ret = &ulogd_keyh[id].interp->result[ulogd_keyh[id].offset]; - - return ret; -} - -/*********************************************************************** - * INTERPRETER MANAGEMENT - ***********************************************************************/ - -/* try to lookup a registered interpreter for a given name */ -static ulog_interpreter_t *find_interpreter(const char *name) -{ - unsigned int id; - - id = interh_getid(name); - if (!id) - return NULL; - - return ulogd_interh[id]; -} - -/* the function called by all interpreter plugins for registering their - * target. */ -void register_interpreter(ulog_interpreter_t *me) -{ - unsigned int i; - - /* check if we already have an interpreter with this name */ - if (find_interpreter(me->name)) { - ulogd_log(ULOGD_NOTICE, - "interpreter `%s' already registered\n", me->name); - return; - } - - ulogd_log(ULOGD_INFO, "registering interpreter `%s'\n", me->name); - - /* allocate a new interpreter id for it */ - if (!interh_allocid(me)) { - ulogd_log(ULOGD_ERROR, "unable to obtain interh_id for " - "interpreter '%s'\n", me->name); - return; - } - - /* - allocate one keyh_id for each result of this interpreter - * - link the elements to each other */ - for (i = 0; i < me->key_num; i++) { - if (!keyh_allocid(me, i, me->result[i].key)) { - ulogd_log(ULOGD_ERROR, "unable to obtain keyh_id " - "for interpreter %s, key %d", me->name, - me->result[i].key); - continue; - } - if (i != me->key_num - 1) - me->result[i].next = &me->result[i+1]; - } - - /* all work done, we can prepend the new interpreter to the list */ - if (ulogd_interpreters) - me->result[me->key_num - 1].next = - &ulogd_interpreters->result[0]; - me->next = ulogd_interpreters; - ulogd_interpreters = me; -} - -/*********************************************************************** - * OUTPUT MANAGEMENT - ***********************************************************************/ - -/* try to lookup a registered output plugin for a given name */ -static ulog_output_t *find_output(const char *name) -{ - ulog_output_t *ptr; - - for (ptr = ulogd_outputs; ptr; ptr = ptr->next) { - if (strcmp(name, ptr->name) == 0) - return ptr; - } - - return NULL; -} - -/* the function called by all output plugins for registering themselves */ -void register_output(ulog_output_t *me) -{ - if (find_output(me->name)) { - ulogd_log(ULOGD_NOTICE, "output `%s' already registered\n", - me->name); - exit(EXIT_FAILURE); - } - ulogd_log(ULOGD_INFO, "registering output `%s'\n", me->name); - me->next = ulogd_outputs; - ulogd_outputs = me; -} - -/*********************************************************************** - * MAIN PROGRAM - ***********************************************************************/ - -static FILE syslog_dummy; - -static inline int ulogd2syslog_level(int level) -{ - int syslog_level = LOG_WARNING; - - switch (level) { - case ULOGD_DEBUG: - syslog_level = LOG_DEBUG; - break; - case ULOGD_INFO: - syslog_level = LOG_INFO; - break; - case ULOGD_NOTICE: - syslog_level = LOG_NOTICE; - break; - case ULOGD_ERROR: - syslog_level = LOG_ERR; - break; - case ULOGD_FATAL: - syslog_level = LOG_CRIT; - break; - } - return syslog_level; -} -/* propagate results to all registered output plugins */ -static void propagate_results(ulog_iret_t *ret) -{ - ulog_output_t *p; - - for (p = ulogd_outputs; p; p = p->next) { - (*p->output)(ret); - } -} - -/* clean results (set all values to 0 and free pointers) */ -static void clean_results(ulog_iret_t *ret) -{ - ulog_iret_t *r; - - for (r = ret; r; r = r->next) { - if (r->flags & ULOGD_RETF_FREE) { - free(r->value.ptr); - r->value.ptr = NULL; - } - memset(&r->value, 0, sizeof(r->value)); - r->flags &= ~ULOGD_RETF_VALID; - } -} - -/* call all registered interpreters and hand the results over to - * propagate_results */ -static void handle_packet(ulog_packet_msg_t *pkt) -{ - ulog_iret_t *ret; - ulog_iret_t *allret = NULL; - ulog_interpreter_t *ip; - - unsigned int i,j; - - /* If there are no interpreters registered yet, - * ignore this packet */ - if (!ulogd_interh_ids) { - ulogd_log(ULOGD_NOTICE, - "packet received, but no interpreters found\n"); - return; - } - - for (i = 1; i <= ulogd_interh_ids; i++) { - ip = ulogd_interh[i]; - /* call interpreter */ - if ((ret = ((ip)->interp)(ip, pkt))) { - /* create references for result linked-list */ - for (j = 0; j < ip->key_num; j++) { - if (IS_VALID(ip->result[j])) { - ip->result[j].cur_next = allret; - allret = &ip->result[j]; - } - } - } - } - propagate_results(allret); - clean_results(ulogd_interpreters->result); -} - -/* plugin loader to dlopen() a plugins */ -static int load_plugin(char *file) -{ - if (!dlopen(file, RTLD_NOW)) { - ulogd_log(ULOGD_ERROR, "load_plugins: '%s': %s\n", file, - dlerror()); - return 1; - } - return 0; -} - -/* open the logfile */ -static int logfile_open(const char *name) -{ - if (!strcmp(name, "syslog")) { - openlog("ulogd", LOG_PID, LOG_DAEMON); - logfile = &syslog_dummy; - } else if (!strcmp(name,"stdout")) - logfile = stdout; - else { - logfile = fopen(name, "a"); - if (!logfile) { - fprintf(stderr, "ERROR: can't open logfile %s: %s\n", - name, strerror(errno)); - exit(2); - } - } - ulogd_log(ULOGD_INFO, "ulogd Version %s starting\n", ULOGD_VERSION); - return 0; -} - -/* wrapper to handle conffile error codes */ -static int parse_conffile(const char *section, config_entry_t *ce) -{ - int err; - - err = config_parse_file(section, ce); - - switch(err) { - case 0: - return 0; - break; - case -ERROPEN: - ulogd_log(ULOGD_ERROR, - "unable to open configfile: %s\n", - ulogd_configfile); - break; - case -ERRMAND: - ulogd_log(ULOGD_ERROR, - "mandatory option \"%s\" not found\n", - config_errce->key); - break; - case -ERRMULT: - ulogd_log(ULOGD_ERROR, - "option \"%s\" occurred more than once\n", - config_errce->key); - break; - case -ERRUNKN: - ulogd_log(ULOGD_ERROR, - "unknown config key \"%s\"\n", - config_errce->key); - break; - case -ERRSECTION: - ulogd_log(ULOGD_ERROR, - "section \"%s\" not found\n", section); - break; - } - return 1; - -} - -/* configuration directives of the main program */ -static config_entry_t logf_ce = { NULL, "logfile", CONFIG_TYPE_STRING, - CONFIG_OPT_NONE, 0, - { string: ULOGD_LOGFILE_DEFAULT } }; - -static config_entry_t bufsiz_ce = { &logf_ce, "bufsize", CONFIG_TYPE_INT, - CONFIG_OPT_NONE, 0, - { value: ULOGD_BUFSIZE_DEFAULT } }; - -static config_entry_t plugin_ce = { &bufsiz_ce, "plugin", CONFIG_TYPE_CALLBACK, - CONFIG_OPT_MULTI, 0, - { parser: &load_plugin } }; - -static config_entry_t nlgroup_ce = { &plugin_ce, "nlgroup", CONFIG_TYPE_INT, - CONFIG_OPT_NONE, 0, - { value: ULOGD_NLGROUP_DEFAULT } }; - -static config_entry_t loglevel_ce = { &nlgroup_ce, "loglevel", CONFIG_TYPE_INT, - CONFIG_OPT_NONE, 0, - { value: ULOGD_NOTICE } }; -static config_entry_t rmem_ce = { &loglevel_ce, "rmem", CONFIG_TYPE_INT, - CONFIG_OPT_NONE, 0, - { value: ULOGD_RMEM_DEFAULT } }; - -/* log message to the logfile */ -void __ulogd_log(int level, char *file, int line, const char *format, ...) -{ - char *timestr; - va_list ap; - time_t tm; - FILE *outfd; - - /* log only messages which have level at least as high as loglevel */ - if (level < loglevel_ce.u.value) - return; - - if (logfile == &syslog_dummy) { - /* FIXME: this omit's the 'file' string */ - va_start(ap, format); - vsyslog(ulogd2syslog_level(level), format, ap); - va_end(ap); - } else { - if (logfile) - outfd = logfile; - else - outfd = stderr; - - va_start(ap, format); - - tm = time(NULL); - timestr = ctime(&tm); - timestr[strlen(timestr)-1] = '\0'; - fprintf(outfd, "%s <%1.1d> %s:%d ", timestr, level, file, line); - - vfprintf(outfd, format, ap); - va_end(ap); - - /* flush glibc's buffer */ - fflush(outfd); - } -} - -static void sigterm_handler(int signal) -{ - ulog_output_t *p; - - ulogd_log(ULOGD_NOTICE, "sigterm received, exiting\n"); - - ipulog_destroy_handle(libulog_h); - free(libulog_buf); - - for (p = ulogd_outputs; p; p = p->next) { - if (p->fini) - (*p->fini)(); - } - - if (logfile != stdout && logfile != &syslog_dummy) - fclose(logfile); - - exit(0); -} - -static void sighup_handler(int signal) -{ - ulog_output_t *p; - - if (logfile != stdout && logfile != &syslog_dummy) { - fclose(logfile); - logfile = fopen(logf_ce.u.string, "a"); - if (!logfile) - sigterm_handler(signal); - } - - ulogd_log(ULOGD_NOTICE, "sighup received, calling plugin handlers\n"); - - for (p = ulogd_outputs; p; p = p->next) { - if (p->signal) - (*p->signal)(SIGHUP); - } -} - -static void print_usage(void) -{ - /* FIXME */ - printf("ulogd Version %s\n", ULOGD_VERSION); - printf("Copyright (C) 2000-2005 Harald Welte " - "\n"); - printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n"); - printf("Parameters:\n"); - printf("\t-h --help\tThis help page\n"); - printf("\t-V --version\tPrint version information\n"); - printf("\t-d --daemon\tDaemonize (fork into background)\n"); - printf("\t-c --configfile\tUse alternative Configfile\n"); - printf("\t-u --uid\tChange UID/GID\n"); -} - -static struct option opts[] = { - { "version", 0, NULL, 'V' }, - { "daemon", 0, NULL, 'd' }, - { "help", 0, NULL, 'h' }, - { "configfile", 1, NULL, 'c'}, - { "uid", 1, NULL, 'u' }, - { 0 } -}; - -int main(int argc, char* argv[]) -{ - int len; - int argch; - int daemonize = 0; - int change_uid = 0; - char *user = NULL; - struct passwd *pw; - uid_t uid = 0; - gid_t gid = 0; - ulog_packet_msg_t *upkt; - ulog_output_t *p; - - - while ((argch = getopt_long(argc, argv, "c:dh::Vu:", opts, NULL)) != -1) { - switch (argch) { - default: - case '?': - if (isprint(optopt)) - fprintf(stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); - - print_usage(); - exit(1); - break; - case 'h': - print_usage(); - exit(0); - break; - case 'd': - daemonize = 1; - break; - case 'V': - printf("ulogd Version %s\n", ULOGD_VERSION); - printf("Copyright (C) 2000-2005 Harald Welte " - "\n"); - exit(0); - break; - case 'c': - ulogd_configfile = optarg; - break; - case 'u': - change_uid = 1; - user = strdup(optarg); - pw = getpwnam(user); - if (!pw) { - printf("Unknown user %s.\n", user); - free(user); - exit(1); - } - uid = pw->pw_uid; - gid = pw->pw_gid; - break; - } - } - - if (config_register_file(ulogd_configfile)) { - ulogd_log(ULOGD_FATAL, "error registering configfile \"%s\"\n", - ulogd_configfile); - exit(1); - } - - /* parse config file */ - if (parse_conffile("global", &rmem_ce)) { - ulogd_log(ULOGD_FATAL, "parse_conffile\n"); - exit(1); - } - - /* allocate a receive buffer */ - libulog_buf = (unsigned char *) malloc(bufsiz_ce.u.value); - - if (!libulog_buf) { - ulogd_log(ULOGD_FATAL, "unable to allocate receive buffer" - "of %d bytes\n", bufsiz_ce.u.value); - ipulog_perror(NULL); - exit(1); - } - - /* create ipulog handle */ - libulog_h = ipulog_create_handle(ipulog_group2gmask(nlgroup_ce.u.value), - rmem_ce.u.value); - - if (!libulog_h) { - /* if some error occurrs, print it to stderr */ - ulogd_log(ULOGD_FATAL, "unable to create ipulogd handle\n"); - ipulog_perror(NULL); - exit(1); - } - - - if (change_uid) { - ulogd_log(ULOGD_NOTICE, "Changing UID / GID\n"); - if (setgid(gid)) { - ulogd_log(ULOGD_FATAL, "can't set GID\n"); - ipulog_perror(NULL); - exit(1); - } - if (setegid(gid)) { - ulogd_log(ULOGD_FATAL, "can't sett effective GID\n"); - ipulog_perror(NULL); - exit(1); - } - if (initgroups(user, gid)) { - ulogd_log(ULOGD_FATAL, "can't set user secondary GID\n"); - ipulog_perror(NULL); - exit(1); - } - if (setuid(uid)) { - ulogd_log(ULOGD_FATAL, "can't set UID\n"); - ipulog_perror(NULL); - exit(1); - } - if (seteuid(uid)) { - ulogd_log(ULOGD_FATAL, "can't set effective UID\n"); - ipulog_perror(NULL); - exit(1); - } - } - - logfile_open(logf_ce.u.string); - - for (p = ulogd_outputs; p; p = p->next) { - if (p->init) - (*p->init)(); - } - -#ifdef DEBUG - /* dump key and interpreter hash */ - interh_dump(); - keyh_dump(); -#endif - if (daemonize){ - if (fork()) { - exit(0); - } - if (logfile != stdout) - fclose(stdout); - fclose(stderr); - fclose(stdin); - setsid(); - } - - /* send SIGINT to the term handler, since they hit CTRL-C */ - signal(SIGINT, &sigterm_handler); - signal(SIGHUP, &sighup_handler); - signal(SIGTERM, &sigterm_handler); - - ulogd_log(ULOGD_INFO, - "initialization finished, entering main loop\n"); - - /* endless loop receiving packets and handling them over to - * handle_packet */ - while ((len = ipulog_read(libulog_h, libulog_buf, - bufsiz_ce.u.value, 1))) { - - if (len <= 0) { - /* this is not supposed to happen */ - ulogd_log(ULOGD_ERROR, "ipulog_read == %d! " - "ipulog_errno == %d, errno = %d\n", - len, ipulog_errno, errno); - } else { - while ((upkt = ipulog_get_packet(libulog_h, - libulog_buf, len))) { - DEBUGP("==> packet received\n"); - handle_packet(upkt); - } - } - } - - /* hackish, but result is the same */ - sigterm_handler(SIGTERM); - return(0); -} -- cgit v1.2.3