Here's a patch that adds an option to the UDP source to specify the file descriptor of an already bound UDP socket, in lieu of having syslog-ng create and bind the socket. This makes it possible to run syslog-ng without the privilege required to bind to reserved UDP port numbers (such as the standard syslog port number). I exec syslog-ng with no privileges at all, except write permission to the log files. Aside from the config file processing, all the patch does is skip the call to afsocket_open_socket() if the user supplied a file descriptor, and move the settings of the nonblock and close-on-exec options from afsocket_open_socket() to afsocket_setup_socket(). -- Bryan Henderson San Jose, California diff --rec --unif syslog-ng-2.0.2+20070202/src/afinet.c syslog-ng/src/afinet.c --- syslog-ng-2.0.2+20070202/src/afinet.c 2007-02-01 23:11:48.000000000 +0000 +++ syslog-ng/src/afinet.c 2007-02-02 17:26:26.000000000 +0000 @@ -233,6 +233,15 @@ afinet_resolve_name(self->bind_addr, ip); } +void +afinet_sd_set_fd(LogDriver *s, int fd) +{ + AFSocketSourceDriver *self = (AFSocketSourceDriver *) s; + + self->user_fd = fd; + self->user_bound_socket = TRUE; +} + static gboolean afinet_sd_setup_socket(AFSocketSourceDriver *s, gint fd) { diff --rec --unif syslog-ng-2.0.2+20070202/src/afinet.h syslog-ng/src/afinet.h --- syslog-ng-2.0.2+20070202/src/afinet.h 2007-02-01 23:11:40.000000000 +0000 +++ syslog-ng/src/afinet.h 2007-02-02 17:26:26.000000000 +0000 @@ -42,6 +42,7 @@ LogDriver *afinet_sd_new(gint af, gchar *host, gint port, guint flags); void afinet_sd_set_localport(LogDriver *self, gint port, gchar *service, gchar *proto); void afinet_sd_set_localip(LogDriver *self, gchar *ip); +void afinet_sd_set_fd(LogDriver *s, int fd); #define afinet_sd_set_auth(a,b) #define afinet_sd_set_mac(a,b) --- syslog-ng-2.0.2+20070202/src/afsocket.c 2007-02-01 23:11:47.000000000 +0000 +++ syslog-ng/src/afsocket.c 2007-02-09 03:00:27.000000000 +0000 @@ -157,6 +157,9 @@ gboolean afsocket_setup_socket(gint fd, SocketOptions *sock_options, AFSocketDirection dir) { + g_fd_set_nonblock(fd, TRUE); + g_fd_set_cloexec(sock, TRUE); + if (dir & AFSOCKET_DIR_RECV) { if (sock_options->rcvbuf) @@ -183,8 +186,6 @@ else sock = socket(bind_addr->sa.sa_family, SOCK_DGRAM, 0); - g_fd_set_nonblock(sock, TRUE); - g_fd_set_cloexec(sock, TRUE); if (sock != -1) { if (g_bind(sock, bind_addr) != G_IO_STATUS_NORMAL) @@ -390,9 +391,6 @@ return TRUE; } - g_fd_set_nonblock(new_fd, TRUE); - g_fd_set_cloexec(new_fd, TRUE); - msg_verbose("Syslog connection accepted", evt_tag_str("from", g_sockaddr_format(peer_addr, buf1, sizeof(buf1))), evt_tag_str("to", g_sockaddr_format(self->bind_addr, buf2, sizeof(buf2))), @@ -492,8 +490,13 @@ { if (!self->connections) { - if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) - return self->super.optional; + if (self->user_bound_socket) + sock = self->user_fd; + else { + if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) + return self->super.optional; + } + } self->fd = -1; @@ -633,6 +636,7 @@ self->max_connections = 10; self->listen_backlog = 255; self->flags = flags; + self->user_bound_socket = FALSE; log_reader_options_defaults(&self->reader_options); } diff --rec --unif syslog-ng-2.0.2+20070202/src/afsocket.h syslog-ng/src/afsocket.h --- syslog-ng-2.0.2+20070202/src/afsocket.h 2007-02-01 23:11:47.000000000 +0000 +++ syslog-ng/src/afsocket.h 2007-02-02 17:26:26.000000000 +0000 @@ -61,6 +61,8 @@ guint source_id; LogReaderOptions reader_options; + gboolean user_bound_socket; + int user_fd; GSockAddr *bind_addr; gint max_connections; gint num_connections; diff --rec --unif syslog-ng-2.0.2+20070202/src/cfg-grammar.y syslog-ng/src/cfg-grammar.y --- syslog-ng-2.0.2+20070202/src/cfg-grammar.y 2007-02-01 23:11:47.000000000 +0000 +++ syslog-ng/src/cfg-grammar.y 2007-02-02 17:26:26.000000000 +0000 @@ -94,7 +94,7 @@ /* socket related options */ %token KW_KEEP_ALIVE KW_MAX_CONNECTIONS -%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT +%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT KW_FD %token KW_IP_TTL KW_SO_BROADCAST KW_IP_TOS KW_SO_SNDBUF KW_SO_RCVBUF KW_SO_KEEPALIVE /* misc options */ @@ -371,6 +371,7 @@ : source_afinet_option | KW_LOCALPORT '(' string ')' { afinet_sd_set_localport(last_driver, 0, $3, "udp"); free($3); } | KW_PORT '(' string ')' { afinet_sd_set_localport(last_driver, 0, $3, "udp"); free($3); } + | KW_FD '(' NUMBER ')' { afinet_sd_set_fd(last_driver, $3); } ; source_afinet_option @@ -904,4 +905,4 @@ last_reader_options = NULL; last_writer_options = NULL; last_template = NULL; -} \ No newline at end of file +} diff --rec --unif syslog-ng-2.0.2+20070202/src/cfg-lex.l syslog-ng/src/cfg-lex.l --- syslog-ng-2.0.2+20070202/src/cfg-lex.l 2007-02-01 23:11:47.000000000 +0000 +++ syslog-ng/src/cfg-lex.l 2007-02-02 17:26:26.000000000 +0000 @@ -119,6 +119,7 @@ { "localport", KW_LOCALPORT }, { "port", KW_PORT }, { "destport", KW_DESTPORT }, + { "fd", KW_FD }, { "ip_ttl", KW_IP_TTL }, { "ip_tos", KW_IP_TOS }, { "so_broadcast", KW_SO_BROADCAST },