diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2004-07-03 05:32:20 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2004-07-03 05:32:20 +0000 |
commit | 17455e35333964280196c227b7aaeb327277ab8e (patch) | |
tree | 1da1711fbc637a603d34f8d23516ce2cfd4a47ea /usr.sbin | |
parent | 86b123ea9d78c8ce8975c78ef99af41d132ed364 (diff) |
support @hostname:port syntax in syslog.conf, prompted by msf@ at c2k4;
ok henning@ anil@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/syslogd/privsep.c | 53 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslog.conf.5 | 5 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslogd.c | 42 | ||||
-rw-r--r-- | usr.sbin/syslogd/syslogd.h | 5 |
4 files changed, 70 insertions, 35 deletions
diff --git a/usr.sbin/syslogd/privsep.c b/usr.sbin/syslogd/privsep.c index c4bb5ed8864..64e912655fe 100644 --- a/usr.sbin/syslogd/privsep.c +++ b/usr.sbin/syslogd/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.18 2004/04/09 20:13:25 canacar Exp $ */ +/* $OpenBSD: privsep.c,v 1.19 2004/07/03 05:32:18 djm Exp $ */ /* * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org> @@ -66,7 +66,7 @@ enum cmd_types { PRIV_OPEN_UTMP, /* open utmp for reading only */ PRIV_OPEN_CONFIG, /* open config file for reading only */ PRIV_CONFIG_MODIFIED, /* check if config file has been modified */ - PRIV_GETHOSTBYNAME, /* resolve hostname into numerical address */ + PRIV_GETHOSTSERV, /* resolve host/service names */ PRIV_GETHOSTBYADDR, /* resolve numeric address into hostname */ PRIV_DONE_CONFIG_PARSE /* signal that the initial config parse is done */ }; @@ -98,11 +98,13 @@ int priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[]) { int i, fd, socks[2], cmd, addr_len, addr_af, result, restart; - size_t path_len, hostname_len; + size_t path_len, hostname_len, servname_len; char path[MAXPATHLEN], hostname[MAXHOSTNAMELEN]; + char servname[MAXHOSTNAMELEN]; struct stat cf_stat; struct hostent *hp; struct passwd *pw; + struct addrinfo hints, *res0; for (i = 1; i < _NSIG; i++) signal(i, SIG_DFL); @@ -275,21 +277,34 @@ priv_init(char *conf, int numeric, int lockfd, int nullfd, char *argv[]) increase_state(STATE_RUNNING); break; - case PRIV_GETHOSTBYNAME: - dprintf("[priv]: msg PRIV_GETHOSTBYNAME received\n"); - /* Expecting: length, hostname */ + case PRIV_GETHOSTSERV: + dprintf("[priv]: msg PRIV_GETHOSTSERV received\n"); + /* Expecting: len, hostname, len, servname */ must_read(socks[0], &hostname_len, sizeof(size_t)); if (hostname_len == 0 || hostname_len > sizeof(hostname)) _exit(0); must_read(socks[0], &hostname, hostname_len); hostname[hostname_len - 1] = '\0'; - hp = gethostbyname(hostname); - if (hp == NULL) { + + must_read(socks[0], &servname_len, sizeof(size_t)); + if (servname_len == 0 || servname_len > sizeof(servname)) + _exit(0); + must_read(socks[0], &servname, servname_len); + servname[servname_len - 1] = '\0'; + + memset(&hints, '\0', sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + i = getaddrinfo(hostname, servname, &hints, &res0); + if (i != 0 || res0 == NULL) { addr_len = 0; must_write(socks[0], &addr_len, sizeof(int)); } else { - must_write(socks[0], &hp->h_length, sizeof(int)); - must_write(socks[0], hp->h_addr, hp->h_length); + /* Just send the first address */ + i = res0->ai_addrlen; + must_write(socks[0], &i, sizeof(int)); + must_write(socks[0], res0->ai_addr, i); + freeaddrinfo(res0); } break; @@ -541,14 +556,15 @@ priv_config_parse_done(void) must_write(priv_fd, &cmd, sizeof(int)); } -/* Resolve hostname into address. Response is placed into addr, and +/* Name/service to address translation. Response is placed into addr, and * the length is returned (zero on error) */ int -priv_gethostbyname(char *host, char *addr, size_t addr_len) +priv_gethostserv(char *host, char *serv, struct sockaddr *addr, + size_t addr_len) { - char hostcpy[MAXHOSTNAMELEN]; + char hostcpy[MAXHOSTNAMELEN], servcpy[MAXHOSTNAMELEN]; int cmd, ret_len; - size_t hostname_len; + size_t hostname_len, servname_len; if (priv_fd < 0) errx(1, "%s: called from privileged portion", __func__); @@ -556,11 +572,16 @@ priv_gethostbyname(char *host, char *addr, size_t addr_len) if (strlcpy(hostcpy, host, sizeof hostcpy) >= sizeof(hostcpy)) errx(1, "%s: overflow attempt in hostname", __func__); hostname_len = strlen(hostcpy) + 1; + if (strlcpy(servcpy, serv, sizeof servcpy) >= sizeof(servcpy)) + errx(1, "%s: overflow attempt in servname", __func__); + servname_len = strlen(servcpy) + 1; - cmd = PRIV_GETHOSTBYNAME; + cmd = PRIV_GETHOSTSERV; must_write(priv_fd, &cmd, sizeof(int)); must_write(priv_fd, &hostname_len, sizeof(size_t)); must_write(priv_fd, hostcpy, hostname_len); + must_write(priv_fd, &servname_len, sizeof(size_t)); + must_write(priv_fd, servcpy, servname_len); /* Expect back an integer size, and then a string of that length */ must_read(priv_fd, &ret_len, sizeof(int)); @@ -574,7 +595,9 @@ priv_gethostbyname(char *host, char *addr, size_t addr_len) errx(1, "%s: overflow attempt in return", __func__); /* Read the resolved address and make sure we got all of it */ + memset(addr, '\0', addr_len); must_read(priv_fd, addr, ret_len); + return ret_len; } diff --git a/usr.sbin/syslogd/syslog.conf.5 b/usr.sbin/syslogd/syslog.conf.5 index a82f5a5bcc6..f3fa650cf1b 100644 --- a/usr.sbin/syslogd/syslog.conf.5 +++ b/usr.sbin/syslogd/syslog.conf.5 @@ -26,7 +26,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)syslog.conf.5 8.1 (Berkeley) 6/9/93 -.\" $OpenBSD: syslog.conf.5,v 1.18 2004/06/07 18:37:38 jmc Exp $ +.\" $OpenBSD: syslog.conf.5,v 1.19 2004/07/03 05:32:18 djm Exp $ .\" $NetBSD: syslog.conf.5,v 1.4 1996/01/02 17:41:46 perry Exp $ .\" .Dd June 9, 1993 @@ -211,6 +211,9 @@ sign). Selected messages are forwarded to the .Xr syslogd program on the named host. +A port number may be optionally specified using the +.Ar host:port +syntax. .It A comma separated list of users. Selected messages are written to those users diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index a993a1830b1..d59364e5cc9 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syslogd.c,v 1.80 2004/06/25 19:10:54 djm Exp $ */ +/* $OpenBSD: syslogd.c,v 1.81 2004/07/03 05:32:18 djm Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -39,7 +39,7 @@ static const char copyright[] = #if 0 static const char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94"; #else -static const char rcsid[] = "$OpenBSD: syslogd.c,v 1.80 2004/06/25 19:10:54 djm Exp $"; +static const char rcsid[] = "$OpenBSD: syslogd.c,v 1.81 2004/07/03 05:32:18 djm Exp $"; #endif #endif /* not lint */ @@ -142,7 +142,7 @@ struct filed { char f_uname[MAXUNAMES][UT_NAMESIZE+1]; struct { char f_hname[MAXHOSTNAMELEN]; - struct sockaddr_in f_addr; + struct sockaddr_storage f_addr; } f_forw; /* forwarding address */ char f_fname[MAXPATHLEN]; struct { @@ -262,7 +262,7 @@ void domark(int); void markit(void); void fprintlog(struct filed *, int, char *); void init(void); -void logerror(char *); +void logerror(const char *); void logmsg(int, char *, char *, int); void printline(char *, char *); void printsys(char *); @@ -851,7 +851,7 @@ fprintlog(struct filed *f, int flags, char *msg) l = strlen(line); if (sendto(pfd[PFD_INET].fd, line, l, 0, (struct sockaddr *)&f->f_un.f_forw.f_addr, - sizeof(f->f_un.f_forw.f_addr)) != l) { + f->f_un.f_forw.f_addr.ss_len) != l) { f->f_type = F_UNUSED; logerror("sendto"); } @@ -1051,7 +1051,7 @@ doinit(int signo) * Print syslogd errors some place. */ void -logerror(char *type) +logerror(const char *type) { char buf[100]; @@ -1246,7 +1246,8 @@ cfline(char *line, struct filed *f, char *prog) { int i, pri, addr_len; size_t rb_len; - char *bp, *p, *q; + char *bp, *p, *q, *cp; + const char *errstr; char buf[MAXLINE], ebuf[100]; char addr[MAXHOSTNAMELEN]; struct filed *xf; @@ -1343,20 +1344,25 @@ cfline(char *line, struct filed *f, char *prog) case '@': if (!InetInuse) break; - (void)strlcpy(f->f_un.f_forw.f_hname, ++p, - sizeof(f->f_un.f_forw.f_hname)); - addr_len = priv_gethostbyname(f->f_un.f_forw.f_hname, - addr, sizeof addr); - if (addr_len < 1) { - logerror((char *)hstrerror(h_errno)); + if ((cp = strrchr(++p, ':')) != NULL) + *cp++ = '\0'; + if ((strlcpy(f->f_un.f_forw.f_hname, p, + sizeof(f->f_un.f_forw.f_hname)) >= + sizeof(f->f_un.f_forw.f_hname))) { + snprintf(ebuf, sizeof(ebuf), "hostname too long \"%s\"", + p); + logerror(ebuf); break; } - memset(&f->f_un.f_forw.f_addr, 0, + addr_len = priv_gethostserv(f->f_un.f_forw.f_hname, + cp == NULL ? "syslog" : cp, + (struct sockaddr*)&f->f_un.f_forw.f_addr, sizeof(f->f_un.f_forw.f_addr)); - f->f_un.f_forw.f_addr.sin_len = sizeof(f->f_un.f_forw.f_addr); - f->f_un.f_forw.f_addr.sin_family = AF_INET; - f->f_un.f_forw.f_addr.sin_port = LogPort; - memmove(&f->f_un.f_forw.f_addr.sin_addr, addr, addr_len); + if (addr_len < 1) { + snprintf(ebuf, sizeof(ebuf), "bad hostname \"%s\"", p); + logerror(ebuf); + break; + } f->f_type = F_FORW; break; diff --git a/usr.sbin/syslogd/syslogd.h b/usr.sbin/syslogd/syslogd.h index ed58afbb981..ca8f89d2bad 100644 --- a/usr.sbin/syslogd/syslogd.h +++ b/usr.sbin/syslogd/syslogd.h @@ -14,6 +14,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/types.h> +#include <sys/socket.h> + /* Privilege separation */ int priv_init(char *, int, int, int, char **); int priv_open_tty(const char *); @@ -22,7 +25,7 @@ FILE *priv_open_utmp(void); FILE *priv_open_config(void); void priv_config_parse_done(void); int priv_config_modified(void); -int priv_gethostbyname(char *, char *, size_t); +int priv_gethostserv(char *, char *, struct sockaddr *, size_t); int priv_gethostbyaddr(char *, int, int, char *, size_t); /* Terminal message */ |