diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/afsocket.c syslog-ng-2.0.5+byte/src/afsocket.c --- syslog-ng-2.0.5/src/afsocket.c 2007-07-22 14:13:46.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/afsocket.c 2007-09-20 20:40:39.000000000 +0100 @@ -406,8 +406,10 @@ GSockAddr *peer_addr; gchar buf1[256], buf2[256]; gint new_fd; gboolean res; + struct ucred creds; + socklen_t creds_len = sizeof(creds); if (g_accept(self->fd, &new_fd, &peer_addr) != G_IO_STATUS_NORMAL) { msg_error("Error accepting new connection", @@ -423,8 +425,16 @@ g_fd_set_nonblock(new_fd, TRUE); g_fd_set_cloexec(new_fd, TRUE); + if (getsockopt(new_fd, SOL_SOCKET, SO_PEERCRED, &creds, &creds_len) == 0 + && creds_len == sizeof(creds)) + { + peer_addr->creds.pid = creds.pid; + peer_addr->creds.uid = creds.uid; + peer_addr->creds.gid = creds.gid; + } + 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))), NULL); diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/cfg-grammar.y syslog-ng-2.0.5+byte/src/cfg-grammar.y --- syslog-ng-2.0.5/src/cfg-grammar.y 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/cfg-grammar.y 2007-09-21 16:32:56.000000000 +0100 @@ -106,9 +106,9 @@ /* misc options */ %token KW_USE_TIME_RECVD /* filter items*/ -%token KW_FACILITY KW_LEVEL KW_HOST KW_MATCH KW_NETMASK +%token KW_FACILITY KW_LEVEL KW_HOST KW_MATCH KW_NETMASK KW_UID KW_GID KW_PID /* yes/no switches */ %token KW_YES KW_NO @@ -803,9 +803,12 @@ | KW_PROGRAM '(' string ')' { $$ = filter_prog_new($3); free($3); } | KW_HOST '(' string ')' { $$ = filter_host_new($3); free($3); } | KW_MATCH '(' string ')' { $$ = filter_match_new($3); free($3); } | KW_FILTER '(' string ')' { $$ = filter_call_new($3, configuration); free($3); } - | KW_NETMASK '(' string ')' { $$ = filter_netmask_new($3); free($3); } + | KW_UID '(' NUMBER ')' { $$ = filter_uid_new($3); } + | KW_GID '(' NUMBER ')' { $$ = filter_gid_new($3); } + | KW_GROUP '(' NUMBER ')' { $$ = filter_group_new($3); } + | KW_PID '(' ')' { $$ = filter_pid_new(); } ; filter_fac_list : filter_fac filter_fac_list { $$ = $1 | $2; } @@ -907,5 +910,5 @@ last_driver = NULL; last_reader_options = NULL; last_writer_options = NULL; last_template = NULL; -} \ No newline at end of file +} diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/cfg-lex.l syslog-ng-2.0.5+byte/src/cfg-lex.l --- syslog-ng-2.0.5/src/cfg-lex.l 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/cfg-lex.l 2007-09-21 16:32:35.000000000 +0100 @@ -164,8 +164,11 @@ { "program", KW_PROGRAM }, { "host", KW_HOST }, { "match", KW_MATCH }, { "netmask", KW_NETMASK }, + { "uid", KW_UID }, + { "gid", KW_GID }, + { "pid", KW_PID }, /* on/off switches */ { "yes", KW_YES }, { "on", KW_YES }, diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/filter.c syslog-ng-2.0.5+byte/src/filter.c --- syslog-ng-2.0.5/src/filter.c 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/filter.c 2007-09-21 16:32:05.000000000 +0100 @@ -28,8 +28,11 @@ #include #include #include +#include +#include +#include static void log_filter_rule_free(LogFilterRule *self); gboolean @@ -493,4 +496,122 @@ self->address.s_addr &= self->netmask.s_addr; self->super.eval = filter_netmask_eval; return &self->super; } + +typedef struct _FilterUid +{ + FilterExprNode super; + uid_t uid; +} FilterUid; + +static gboolean +filter_uid_eval(FilterExprNode *s, LogMessage *msg) +{ + FilterUid *self = (FilterUid *) s; + return (msg->saddr->creds.pid && msg->saddr->creds.uid == self->uid) ^ self->super.comp; +} + +FilterExprNode * +filter_uid_new(guint32 uid) +{ + FilterUid *self = g_new0(FilterUid, 1); + + self->super.eval = filter_uid_eval; + self->uid = uid; + self->super.type = "uid"; + return &self->super; +} + +typedef struct _FilterGid +{ + FilterExprNode super; + gid_t gid; +} FilterGid; + +static gboolean +filter_gid_eval(FilterExprNode *s, LogMessage *msg) +{ + FilterGid *self = (FilterGid *) s; + return (msg->saddr->creds.pid && msg->saddr->creds.gid == self->gid) ^ self->super.comp; +} + +FilterExprNode * +filter_gid_new(guint32 gid) +{ + FilterGid *self = g_new0(FilterGid, 1); + + self->super.eval = filter_gid_eval; + self->gid = gid; + self->super.type = "gid"; + return &self->super; +} + +typedef struct _FilterGroup +{ + FilterExprNode super; + gid_t gid; +} FilterGroup; + +static gboolean +filter_group_eval(FilterExprNode *s, LogMessage *msg) +{ + FilterGroup *self = (FilterGroup *) s; + if (msg->saddr->creds.pid) + { + struct passwd *pwd = getpwuid(msg->saddr->creds.uid); + struct group *grp = getgrgid(self->gid); + int i; + if (pwd != NULL && grp != NULL) + for (i = 0; i >= 0 && grp->gr_mem[i] != NULL; i++) + if (!strcmp(pwd->pw_name, grp->gr_mem[i])) + return 1 ^ self->super.comp; + } + return 0 ^ self->super.comp; +} + +FilterExprNode * +filter_group_new(guint32 gid) +{ + FilterGroup *self = g_new0(FilterGroup, 1); + + self->super.eval = filter_group_eval; + self->gid = gid; + self->super.type = "group"; + return &self->super; +} + +typedef struct _FilterPid +{ + FilterExprNode super; +} FilterPid; + +static gboolean +filter_pid_eval(FilterExprNode *s, LogMessage *msg) +{ + FilterGroup *self = (FilterGroup *) s; + if (msg->saddr->creds.pid) + if (msg->msg.len) + { + gchar *start, *end; + + start = strchr(msg->msg.str, '['); + if (start) + { + start++; + end = strchr(msg->msg.str, ']'); + if (end) + return (msg->saddr->creds.pid == atol(start)) ^ self->super.comp; + } + } + return 0 ^ self->super.comp; +} + +FilterExprNode * +filter_pid_new() +{ + FilterPid *self = g_new0(FilterPid, 1); + + self->super.eval = filter_pid_eval; + self->super.type = "pid"; + return &self->super; +} diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/filter.h syslog-ng-2.0.5+byte/src/filter.h --- syslog-ng-2.0.5/src/filter.h 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/filter.h 2007-09-21 16:33:37.000000000 +0100 @@ -53,8 +53,12 @@ FilterExprNode *filter_host_new(gchar *host); FilterExprNode *filter_match_new(gchar *re); FilterExprNode *filter_call_new(gchar *rule, struct _GlobalConfig *cfg); FilterExprNode *filter_netmask_new(gchar *cidr); +FilterExprNode *filter_uid_new(guint32 uid); +FilterExprNode *filter_gid_new(guint32 gid); +FilterExprNode *filter_group_new(guint32 gid); +FilterExprNode *filter_pid_new(); typedef struct _LogFilterRule { gint ref_cnt; diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/gsockaddr.c syslog-ng-2.0.5+byte/src/gsockaddr.c --- syslog-ng-2.0.5/src/gsockaddr.c 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/gsockaddr.c 2007-09-20 20:59:30.000000000 +0100 @@ -278,8 +278,9 @@ { gint refcnt; guint32 flags; GSockAddrFuncs *sa_funcs; + struct ucred creds; int salen; struct sockaddr_in sin; } GSockAddrInet; @@ -355,8 +356,11 @@ addr->sin.sin_family = AF_INET; addr->sin.sin_port = htons(port); addr->sin.sin_addr = ina; addr->sa_funcs = &inet_sockaddr_funcs; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; } return (GSockAddr *) addr; } @@ -381,8 +385,11 @@ addr->flags = 0; addr->salen = sizeof(struct sockaddr_in); addr->sin = *sin; addr->sa_funcs = &inet_sockaddr_funcs; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; return (GSockAddr *) addr; } @@ -396,8 +403,9 @@ { gint refcnt; guint32 flags; GSockAddrFuncs *sa_funcs; + struct ucred creds; int salen; struct sockaddr_in sin; gpointer options; guint options_length; @@ -462,15 +470,17 @@ addr->sin.sin_family = AF_INET; inet_aton(ip, &addr->sin.sin_addr); addr->sin.sin_port = 0; addr->sa_funcs = &inet_range_sockaddr_funcs; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; if (max_port > min_port) { addr->last_port = (rand() % (max_port - min_port)) + min_port; } addr->min_port = min_port; addr->max_port = max_port; - return (GSockAddr *) addr; } @@ -486,8 +496,9 @@ { gint refcnt; guint32 flags; GSockAddrFuncs *sa_funcs; + struct ucred creds; int salen; struct sockaddr_in6 sin6; } GSockAddrInet6; @@ -549,8 +560,11 @@ addr->sin6.sin6_family = AF_INET6; inet_pton(AF_INET6, ip, &addr->sin6.sin6_addr); addr->sin6.sin6_port = htons(port); addr->sa_funcs = &inet6_sockaddr_funcs; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; return (GSockAddr *) addr; } @@ -576,8 +590,11 @@ addr->flags = 0; addr->salen = sizeof(struct sockaddr_in6); addr->sin6 = *sin6; addr->sa_funcs = &inet6_sockaddr_funcs; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; return (GSockAddr *) addr; } @@ -595,8 +612,9 @@ { gint refcnt; guint32 flags; GSockAddrFuncs *sa_funcs; + struct ucred creds; int salen; struct sockaddr_un saun; } GSockAddrUnix; @@ -642,8 +660,11 @@ { addr->saun.sun_path[0] = 0; addr->salen = 2; } + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; return (GSockAddr *) addr; } /*+ @@ -668,8 +689,11 @@ addr->flags = 0; addr->sa_funcs = &unix_sockaddr_funcs; addr->salen = sunlen; addr->saun = *saun; + addr->creds.pid = 0; + addr->creds.uid = -1; + addr->creds.gid = -1; return (GSockAddr *) addr; } /*+ private function to prepare a bind on AF_UNIX sockets, e.g. unlink @@ -696,10 +720,15 @@ g_sockaddr_unix_format(GSockAddr *addr, gchar *text, gulong n) { GSockAddrUnix *unix_addr = (GSockAddrUnix *) addr; - g_snprintf(text, n, "AF_UNIX(%s)", - unix_addr->salen > sizeof(unix_addr->saun.sun_family) && unix_addr->saun.sun_path[0] ? unix_addr->saun.sun_path - : "anonymous"); + if (addr->creds.pid != 0) + g_snprintf(text, n, "AF_UNIX(%s %u:%u:%u)", + unix_addr->salen > sizeof(unix_addr->saun.sun_family) && unix_addr->saun.sun_path[0] ? unix_addr->saun.sun_path + : "anonymous", addr->creds.pid, addr->creds.uid, addr->creds.gid); + else + g_snprintf(text, n, "AF_UNIX(%s)", + unix_addr->salen > sizeof(unix_addr->saun.sun_family) && unix_addr->saun.sun_path[0] ? unix_addr->saun.sun_path + : "anonymous"); return text; } diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/gsockaddr.h syslog-ng-2.0.5+byte/src/gsockaddr.h --- syslog-ng-2.0.5/src/gsockaddr.h 2007-05-21 18:21:07.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/gsockaddr.h 2007-09-20 20:57:18.000000000 +0100 @@ -41,8 +41,9 @@ { gint refcnt; guint32 flags; GSockAddrFuncs *sa_funcs; + struct ucred creds; int salen; struct sockaddr sa; } GSockAddr; diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/macros.c syslog-ng-2.0.5+byte/src/macros.c --- syslog-ng-2.0.5/src/macros.c 2007-07-22 14:12:30.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/macros.c 2007-09-20 21:36:41.000000000 +0100 @@ -30,8 +30,11 @@ #include "filter.h" #include #include +#include +#include +#include struct macro_def { char *name; @@ -99,8 +102,14 @@ { "FULLHOST_FROM", M_FULLHOST_FROM }, { "HOST", M_HOST }, { "FULLHOST", M_FULLHOST }, + { "FROM_PID", M_FROM_PID }, + { "FROM_UID", M_FROM_UID }, + { "FROM_GID", M_FROM_GID }, + { "FROM_USER", M_FROM_USER }, + { "FROM_GROUP", M_FROM_GROUP }, + { "PROGRAM", M_PROGRAM }, { "PID", M_PID }, { "MSG", M_MESSAGE }, { "MSGONLY", M_MSGONLY }, @@ -260,8 +269,55 @@ } } break; } + case M_FROM_PID: + { + /* from pid */ + if (msg->saddr->creds.pid != 0) + { + g_string_sprintfa(result, "%u", msg->saddr->creds.pid); + } + break; + } + case M_FROM_UID: + { + /* from uid */ + if (msg->saddr->creds.pid != 0) + { + g_string_sprintfa(result, "%u", msg->saddr->creds.uid); + } + break; + } + case M_FROM_GID: + { + /* from gid */ + if (msg->saddr->creds.pid != 0) + g_string_sprintfa(result, "%u", msg->saddr->creds.gid); + break; + } + case M_FROM_USER: + { + /* from user */ + if (msg->saddr->creds.pid != 0) + { + struct passwd *pwd = getpwuid(msg->saddr->creds.uid); + if (pwd != NULL) + g_string_sprintfa(result, "%s", pwd->pw_name); + } + break; + } + case M_FROM_GROUP: + { + /* from group */ + if (msg->saddr->creds.pid != 0) + { + struct group *grp = getgrgid(msg->saddr->creds.gid); + if (grp != NULL) + g_string_sprintfa(result, "%s", grp->gr_name); + } + break; + } case M_DATE: case M_FULLDATE: case M_ISODATE: case M_STAMP: diff -X syslog-ng-2.0.5+byte/diff.ignore -U4 -r syslog-ng-2.0.5/src/macros.h syslog-ng-2.0.5+byte/src/macros.h --- syslog-ng-2.0.5/src/macros.h 2007-07-22 14:12:30.000000000 +0100 +++ syslog-ng-2.0.5+byte/src/macros.h 2007-09-20 21:30:04.000000000 +0100 @@ -97,8 +97,14 @@ M_HOST_FROM, M_PROGRAM, M_PID, + M_FROM_PID, + M_FROM_UID, + M_FROM_GID, + M_FROM_USER, + M_FROM_GROUP, + M_MESSAGE, M_MSGONLY, M_SOURCE_IP, M_MAX,