Page MenuHomeFreeBSD

D41364.id125717.diff
No OneTemporary

D41364.id125717.diff

diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -187,23 +187,15 @@
#endif
/*
- * List of peers and sockets for binding.
+ * Sockets used for logging; monitored by kevent().
*/
-struct peer {
- const char *pe_name;
- const char *pe_serv;
- mode_t pe_mode;
- STAILQ_ENTRY(peer) next;
-};
-static STAILQ_HEAD(, peer) pqueue = STAILQ_HEAD_INITIALIZER(pqueue);
-
struct socklist {
+ int sl_socket;
+ const char *sl_name;
struct addrinfo sl_ai;
#define sl_sa sl_ai.ai_addr
#define sl_salen sl_ai.ai_addrlen
#define sl_family sl_ai.ai_family
- int sl_socket;
- struct peer *sl_peer;
int (*sl_recv)(struct socklist *);
STAILQ_ENTRY(socklist) next;
};
@@ -422,8 +414,7 @@
struct iovlist;
static bool allowaddr(char *);
-static int addpeer(struct peer *);
-static int addsock(struct addrinfo *, struct socklist *);
+static void addsock(const char *, const char *, mode_t);
static void cfline(const char *, const char *, const char *, const char *);
static const char *cvthname(struct sockaddr *);
static void deadq_enter(pid_t, const char *);
@@ -442,7 +433,7 @@
const char *, const char *, const char *, const char *, int);
static void log_deadchild(pid_t, int, const char *);
static void markit(void);
-static int socksetup(struct peer *);
+static struct socklist *socksetup(struct addrinfo *, const char *, mode_t);
static int socklist_recv_file(struct socklist *);
static int socklist_recv_sock(struct socklist *);
static int skip_message(const char *, const char *, int);
@@ -492,41 +483,181 @@
f->f_file = -1;
}
-static int
-addpeer(struct peer *pe0)
+static struct socklist *
+socksetup(struct addrinfo *ai, const char *name, mode_t mode)
{
- struct peer *pe;
+ struct socklist *sl;
+ int (*sl_recv)(struct socklist *);
+ int s, optval = 1;
- pe = calloc(1, sizeof(*pe));
- if (pe == NULL)
- err(1, "malloc failed");
- *pe = *pe0;
- STAILQ_INSERT_TAIL(&pqueue, pe, next);
+ if (ai->ai_family != AF_LOCAL && SecureMode > 1) {
+ /* Only AF_LOCAL in secure mode. */
+ return (NULL);
+ }
+ if (family != AF_UNSPEC && ai->ai_family != AF_LOCAL &&
+ ai->ai_family != family)
+ return (NULL);
- return (0);
+ s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (s < 0) {
+ logerror("socket");
+ return (NULL);
+ }
+ if (ai->ai_family == AF_INET6) {
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &optval,
+ sizeof(int)) < 0) {
+ logerror("setsockopt(IPV6_V6ONLY)");
+ close(s);
+ return (NULL);
+ }
+ }
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval,
+ sizeof(int)) < 0) {
+ logerror("setsockopt(SO_REUSEADDR)");
+ close(s);
+ return (NULL);
+ }
+
+ /*
+ * Bind INET and UNIX-domain sockets.
+ *
+ * A UNIX-domain socket is always bound to a pathname
+ * regardless of -N flag.
+ *
+ * For INET sockets, RFC 3164 recommends that client
+ * side message should come from the privileged syslogd port.
+ *
+ * If the system administrator chooses not to obey
+ * this, we can skip the bind() step so that the
+ * system will choose a port for us.
+ */
+ if (ai->ai_family == AF_LOCAL)
+ unlink(name);
+ if (ai->ai_family == AF_LOCAL || NoBind == 0 || name != NULL) {
+ if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) {
+ logerror("bind");
+ close(s);
+ return (NULL);
+ }
+ if (ai->ai_family == AF_LOCAL || SecureMode == 0)
+ increase_rcvbuf(s);
+ }
+ if (ai->ai_family == AF_LOCAL && chmod(name, mode) < 0) {
+ dprintf("chmod %s: %s\n", name, strerror(errno));
+ close(s);
+ return (NULL);
+ }
+ dprintf("new socket fd is %d\n", s);
+ if (ai->ai_socktype != SOCK_DGRAM) {
+ listen(s, 5);
+ }
+ sl_recv = socklist_recv_sock;
+ if (SecureMode && (ai->ai_family == AF_INET ||
+ ai->ai_family == AF_INET6)) {
+ dprintf("shutdown\n");
+ /* Forbid communication in secure mode. */
+ if (shutdown(s, SHUT_RD) < 0 && errno != ENOTCONN) {
+ logerror("shutdown");
+ if (!Debug)
+ die(0);
+ }
+ sl_recv = NULL;
+ } else {
+ dprintf("listening on socket\n");
+ }
+ dprintf("sending on socket\n");
+ /* Copy *ai->ai_addr to the tail of struct socklist if any. */
+ sl = calloc(1, sizeof(*sl) + ai->ai_addrlen);
+ if (sl == NULL)
+ err(1, "malloc failed");
+ sl->sl_socket = s;
+ sl->sl_name = name;
+ sl->sl_recv = sl_recv;
+ (void)memcpy(&sl->sl_ai, ai, sizeof(*ai));
+ if (ai->ai_addrlen > 0) {
+ (void)memcpy((sl + 1), ai->ai_addr, ai->ai_addrlen);
+ sl->sl_sa = (struct sockaddr *)(sl + 1);
+ } else {
+ sl->sl_sa = NULL;
+ }
+ return (sl);
}
-static int
-addsock(struct addrinfo *ai, struct socklist *sl0)
+/*
+ * We have to handle this case for backwards compatibility:
+ * If there are two (or more) colons but no '[' and ']',
+ * assume this is an inet6 address without a service.
+ */
+#define fixaddr_inet6(name, serv) \
+do { \
+ char *cp; \
+ if (name != NULL) { \
+ if (name[0] == '[' && \
+ (cp = strchr(name + 1, ']')) != NULL) { \
+ name = &name[1]; \
+ *cp = '\0'; \
+ if (cp[1] == ':' && cp[2] != '\0') \
+ serv = cp + 2; \
+ } else { \
+ cp = strchr(name, ':'); \
+ if (cp != NULL && strchr(cp + 1, ':') == NULL) {\
+ *cp = '\0'; \
+ if (cp[1] != '\0') \
+ serv = cp + 1; \
+ if (cp == name) \
+ name = NULL; \
+ } \
+ } \
+ } \
+} while (0)
+
+static void
+addsock(const char *name, const char *serv, mode_t mode)
{
+ struct addrinfo hints = { }, *res, *res0;
struct socklist *sl;
+ int error;
+ char *msgbuf;
+
+ fixaddr_inet6(name, serv);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = AI_PASSIVE;
+ if (name != NULL)
+ dprintf("Trying peer: %s\n", name);
+ if (serv == NULL)
+ serv = "syslog";
+ error = getaddrinfo(name, serv, &hints, &res0);
+ if (error) {
+ asprintf(&msgbuf, "getaddrinfo failed for %s%s: %s",
+ name == NULL ? "" : name, serv,
+ gai_strerror(error));
+ errno = 0;
+ if (msgbuf == NULL)
+ logerror(gai_strerror(error));
+ else
+ logerror(msgbuf);
+ free(msgbuf);
+ die(0);
+ }
+ for (res = res0; res != NULL; res = res->ai_next) {
+ sl = socksetup(res, name, mode);
+ if (sl == NULL)
+ continue;
+ STAILQ_INSERT_TAIL(&shead, sl, next);
+ }
+ freeaddrinfo(res0);
+}
- /* Copy *ai->ai_addr to the tail of struct socklist if any. */
- sl = calloc(1, sizeof(*sl) + ((ai != NULL) ? ai->ai_addrlen : 0));
+static void
+addfile(int fd)
+{
+ struct socklist *sl = calloc(1, sizeof(*sl));
if (sl == NULL)
err(1, "malloc failed");
- *sl = *sl0;
- if (ai != NULL) {
- memcpy(&sl->sl_ai, ai, sizeof(*ai));
- if (ai->ai_addrlen > 0) {
- memcpy((sl + 1), ai->ai_addr, ai->ai_addrlen);
- sl->sl_sa = (struct sockaddr *)(sl + 1);
- } else
- sl->sl_sa = NULL;
- }
+ sl->sl_socket = fd;
+ sl->sl_recv = socklist_recv_file;
STAILQ_INSERT_TAIL(&shead, sl, next);
-
- return (0);
}
int
@@ -535,7 +666,6 @@
struct timespec ts = { }, *tsp = &ts;
struct kevent ev;
struct socklist *sl;
- struct peer *pe;
sigset_t sigset = { };
pid_t ppid = -1, spid;
int ch, kq, error;
@@ -582,18 +712,12 @@
}
if (p == NULL) {
/* A hostname or filename only. */
- addpeer(&(struct peer){
- .pe_name = optarg,
- .pe_serv = "syslog"
- });
+ addsock(optarg, "syslog", 0);
} else {
/* The case of "name:service". */
*p++ = '\0';
- addpeer(&(struct peer){
- .pe_serv = p,
- .pe_name = (strlen(optarg) == 0) ?
- NULL : optarg,
- });
+ addsock(strlen(optarg) == 0 ? NULL : optarg,
+ p, 0);
}
break;
case 'c':
@@ -651,13 +775,11 @@
} else
errx(1, "invalid mode %s, exiting",
optarg);
- } else
+ } else {
errx(1, "invalid filename %s, exiting",
optarg);
- addpeer(&(struct peer){
- .pe_name = name,
- .pe_mode = mode
- });
+ }
+ addsock(name, NULL, mode);
break;
}
case 'M': /* max length of forwarded message */
@@ -719,30 +841,17 @@
if (error < 0) {
dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
} else {
- addsock(NULL, &(struct socklist){
- .sl_socket = error,
- .sl_recv = socklist_recv_file,
- });
+ addfile(error);
}
/* Listen by default: *:514 if no -b flag. */
if (bflag == 0)
- addpeer(&(struct peer){
- .pe_serv = "syslog"
- });
+ addsock(NULL, "syslog", 0);
/* Listen by default: /var/run/log if no -p flag. */
if (pflag == 0)
- addpeer(&(struct peer){
- .pe_name = _PATH_LOG,
- .pe_mode = DEFFILEMODE,
- });
+ addsock(_PATH_LOG, NULL, DEFFILEMODE);
/* Listen by default: /var/run/logpriv if no -S flag. */
if (Sflag == 0)
- addpeer(&(struct peer){
- .pe_name = _PATH_LOG_PRIV,
- .pe_mode = S_IRUSR | S_IWUSR,
- });
- STAILQ_FOREACH(pe, &pqueue, next)
- socksetup(pe);
+ addsock(_PATH_LOG_PRIV, NULL, S_IRUSR | S_IWUSR);
pfh = pidfile_open(PidFile, 0600, &spid);
if (pfh == NULL) {
@@ -2312,7 +2421,7 @@
}
STAILQ_FOREACH(sl, &shead, next) {
if (sl->sl_sa != NULL && sl->sl_family == AF_LOCAL)
- unlink(sl->sl_peer->pe_name);
+ unlink(sl->sl_name);
}
pidfile_remove(pfh);
@@ -3677,161 +3786,6 @@
logerror(buf);
}
-static int
-socksetup(struct peer *pe)
-{
- struct addrinfo hints, *res, *res0;
- int error;
- char *cp;
- int (*sl_recv)(struct socklist *);
- /*
- * We have to handle this case for backwards compatibility:
- * If there are two (or more) colons but no '[' and ']',
- * assume this is an inet6 address without a service.
- */
- if (pe->pe_name != NULL) {
- if (pe->pe_name[0] == '[' &&
- (cp = strchr(pe->pe_name + 1, ']')) != NULL) {
- pe->pe_name = &pe->pe_name[1];
- *cp = '\0';
- if (cp[1] == ':' && cp[2] != '\0')
- pe->pe_serv = cp + 2;
- } else {
- cp = strchr(pe->pe_name, ':');
- if (cp != NULL && strchr(cp + 1, ':') == NULL) {
- *cp = '\0';
- if (cp[1] != '\0')
- pe->pe_serv = cp + 1;
- if (cp == pe->pe_name)
- pe->pe_name = NULL;
- }
- }
- }
- hints = (struct addrinfo){
- .ai_family = AF_UNSPEC,
- .ai_socktype = SOCK_DGRAM,
- .ai_flags = AI_PASSIVE
- };
- if (pe->pe_name != NULL)
- dprintf("Trying peer: %s\n", pe->pe_name);
- if (pe->pe_serv == NULL)
- pe->pe_serv = "syslog";
- error = getaddrinfo(pe->pe_name, pe->pe_serv, &hints, &res0);
- if (error) {
- char *msgbuf;
-
- asprintf(&msgbuf, "getaddrinfo failed for %s%s: %s",
- pe->pe_name == NULL ? "" : pe->pe_name, pe->pe_serv,
- gai_strerror(error));
- errno = 0;
- if (msgbuf == NULL)
- logerror(gai_strerror(error));
- else
- logerror(msgbuf);
- free(msgbuf);
- die(0);
- }
- for (res = res0; res != NULL; res = res->ai_next) {
- int s;
-
- if (res->ai_family != AF_LOCAL &&
- SecureMode > 1) {
- /* Only AF_LOCAL in secure mode. */
- continue;
- }
- if (family != AF_UNSPEC &&
- res->ai_family != AF_LOCAL && res->ai_family != family)
- continue;
-
- s = socket(res->ai_family, res->ai_socktype,
- res->ai_protocol);
- if (s < 0) {
- logerror("socket");
- error++;
- continue;
- }
- if (res->ai_family == AF_INET6) {
- if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
- &(int){1}, sizeof(int)) < 0) {
- logerror("setsockopt(IPV6_V6ONLY)");
- close(s);
- error++;
- continue;
- }
- }
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- &(int){1}, sizeof(int)) < 0) {
- logerror("setsockopt(SO_REUSEADDR)");
- close(s);
- error++;
- continue;
- }
-
- /*
- * Bind INET and UNIX-domain sockets.
- *
- * A UNIX-domain socket is always bound to a pathname
- * regardless of -N flag.
- *
- * For INET sockets, RFC 3164 recommends that client
- * side message should come from the privileged syslogd port.
- *
- * If the system administrator chooses not to obey
- * this, we can skip the bind() step so that the
- * system will choose a port for us.
- */
- if (res->ai_family == AF_LOCAL)
- unlink(pe->pe_name);
- if (res->ai_family == AF_LOCAL ||
- NoBind == 0 || pe->pe_name != NULL) {
- if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
- logerror("bind");
- close(s);
- error++;
- continue;
- }
- if (res->ai_family == AF_LOCAL ||
- SecureMode == 0)
- increase_rcvbuf(s);
- }
- if (res->ai_family == AF_LOCAL &&
- chmod(pe->pe_name, pe->pe_mode) < 0) {
- dprintf("chmod %s: %s\n", pe->pe_name,
- strerror(errno));
- close(s);
- error++;
- continue;
- }
- dprintf("new socket fd is %d\n", s);
- if (res->ai_socktype != SOCK_DGRAM) {
- listen(s, 5);
- }
- sl_recv = socklist_recv_sock;
- if (SecureMode && (res->ai_family == AF_INET ||
- res->ai_family == AF_INET6)) {
- dprintf("shutdown\n");
- /* Forbid communication in secure mode. */
- if (shutdown(s, SHUT_RD) < 0 &&
- errno != ENOTCONN) {
- logerror("shutdown");
- if (!Debug)
- die(0);
- }
- sl_recv = NULL;
- } else
- dprintf("listening on socket\n");
- dprintf("sending on socket\n");
- addsock(res, &(struct socklist){
- .sl_socket = s,
- .sl_peer = pe,
- .sl_recv = sl_recv
- });
- }
- freeaddrinfo(res0);
-
- return(error);
-}
-
static void
increase_rcvbuf(int fd)
{

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 6:53 AM (45 m, 22 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31895219
Default Alt Text
D41364.id125717.diff (12 KB)

Event Timeline