| Summary: | Add -b flag to lpd | ||
|---|---|---|---|
| Product: | Base System | Reporter: | ayan |
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed Duplicate to bin/189053. |
FreeBSD does not allow users to specify which interfaces lpd listens on. Other BSD systems support the -b flag which allows users to specify interfaces by address or hostname. The attached patch implements that functionality. Though the implementation is slightly different from the OpenBSD version, the OpenBSD man page section on the -b flag will apply. Fix: --=_535d2968.C0MYINDQnjnMBjhJbHvnzMZh7I/to232P0ALuEGVO9Sdb8o/ Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="lpd.patch" --=_535d2968.C0MYINDQnjnMBjhJbHvnzMZh7I/to232P0ALuEGVO9Sdb8o/----1uQuAzjBR3p9vkYKDUiChNtKuycPUahWzqCLqYsKYL070H2K Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c index 4aa49ca..3b9da79 100644 --- a/usr.sbin/lpr/lpd/lpd.c +++ b/usr.sbin/lpr/lpd/lpd.c @@ -112,7 +112,7 @@ static void startup(void); static void chkhost(struct sockaddr *_f, int _ch_opts); static int ckqueue(struct printer *_pp); static void fhosterr(int _ch_opts, char *_sysmsg, char *_usermsg); -static int *socksetup(int _af, int _debuglvl); +static int *socksetup(int af, size_t blist_size, char *blist[blist_size], int debuglvl); static void usage(void); /* XXX from libc/net/rcmd.c */ @@ -144,14 +144,29 @@ main(int argc, char **argv) socket_debug = 0; gethostname(local_host, sizeof(local_host)); + char **blist = NULL; + size_t blist_size = 0; + progname = "lpd"; if (euid != 0) errx(EX_NOPERM,"must run as root"); errs = 0; - while ((i = getopt(argc, argv, "cdlpswW46")) != -1) + while ((i = getopt(argc, argv, "b:cdlpswW46")) != -1) switch (i) { + case 'b': + /* add bind address to list. */ + blist_size++; + blist = realloc(blist, sizeof (char *) * blist_size); + + if (blist == NULL) + errx(EX_SOFTWARE, "Could not allocate memory for bind list."); + + blist[blist_size-1] = optarg; + fprintf(stderr,"made it.\n"); + break; + case 'c': /* log all kinds of connection-errors to syslog */ ch_options |= LPD_LOGCONNERR; @@ -204,7 +219,6 @@ main(int argc, char **argv) * listed here to "reserve" them, because the option-letters * are used by either NetBSD or OpenBSD (as of July 2001). */ - case 'b': /* set bind-addr */ case 'n': /* set max num of children */ case 'r': /* allow 'of' for remote ptrs */ /* ...[not needed in freebsd] */ @@ -220,12 +234,13 @@ main(int argc, char **argv) usage(); if (argc == 1) { - if ((i = atoi(argv[0])) == 0) + int requested_port = atoi(argv[0]); + if (requested_port == 0) usage(); - if (i < 0 || i > USHRT_MAX) - errx(EX_USAGE, "port # %d is invalid", i); + if (requested_port < 0 || i > USHRT_MAX) + errx(EX_USAGE, "port # %d is invalid", requested_port); - serv.s_port = htons(i); + serv.s_port = htons(requested_port); sp = &serv; argc--; } else { @@ -339,7 +354,11 @@ main(int argc, char **argv) FD_SET(funix, &defreadfds); listen(funix, 5); if (sflag == 0) { - finet = socksetup(family, socket_debug); + finet = socksetup(family, blist_size, blist, socket_debug); + + /* Now we're done with blist. */ + if (blist) + free(blist); } else finet = NULL; /* pretend we couldn't open TCP socket. */ if (finet) { @@ -855,7 +874,7 @@ fhosterr(int ch_opts, char *sysmsg, char *usermsg) /* if af is PF_UNSPEC more than one socket may be returned */ /* the returned list is dynamically allocated, so caller needs to free it */ static int * -socksetup(int af, int debuglvl) +socksetup(int af, size_t blist_size, char *blist[blist_size], int debuglvl) { struct addrinfo hints, *res, *r; int error, maxs, *s, *socks; @@ -865,58 +884,67 @@ socksetup(int af, int debuglvl) hints.ai_flags = AI_PASSIVE; hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; - error = getaddrinfo(NULL, "printer", &hints, &res); - if (error) { - syslog(LOG_ERR, "%s", gai_strerror(error)); - mcleanup(0); - } - /* Count max number of sockets we may open */ - for (maxs = 0, r = res; r; r = r->ai_next, maxs++) - ; - socks = malloc((maxs + 1) * sizeof(int)); - if (!socks) { - syslog(LOG_ERR, "couldn't allocate memory for sockets"); - mcleanup(0); + if (blist_size == 0 || blist == NULL) { + blist_size = 1; + blist = (char *[]){ "0.0.0.0" }; } - *socks = 0; /* num of sockets counter at start of array */ - s = socks + 1; - for (r = res; r; r = r->ai_next) { - *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); - if (*s < 0) { - syslog(LOG_DEBUG, "socket(): %m"); - continue; + for (size_t baddr = 0; baddr < blist_size; baddr++ ) { + error = getaddrinfo(blist[baddr], "printer", &hints, &res); + if (error) { + syslog(LOG_ERR, "%s", gai_strerror(error)); + mcleanup(0); } - if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) - < 0) { - syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m"); - close(*s); - continue; + + /* Count max number of sockets we may open */ + for (maxs = 0, r = res; r; r = r->ai_next, maxs++) + ; + socks = malloc((maxs + 1) * sizeof(int)); + if (!socks) { + syslog(LOG_ERR, "couldn't allocate memory for sockets"); + mcleanup(0); } - if (debuglvl) - if (setsockopt(*s, SOL_SOCKET, SO_DEBUG, &debuglvl, - sizeof(debuglvl)) < 0) { - syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); + + *socks = 0; /* num of sockets counter at start of array */ + s = socks + 1; + + for (r = res; r; r = r->ai_next) { + *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); + if (*s < 0) { + syslog(LOG_DEBUG, "socket(): %m"); + continue; + } + if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) + < 0) { + syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m"); close(*s); continue; } - if (r->ai_family == AF_INET6) { - if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, - &on, sizeof(on)) < 0) { - syslog(LOG_ERR, - "setsockopt (IPV6_V6ONLY): %m"); + if (debuglvl) + if (setsockopt(*s, SOL_SOCKET, SO_DEBUG, &debuglvl, + sizeof(debuglvl)) < 0) { + syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); + close(*s); + continue; + } + if (r->ai_family == AF_INET6) { + if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, + &on, sizeof(on)) < 0) { + syslog(LOG_ERR, + "setsockopt (IPV6_V6ONLY): %m"); + close(*s); + continue; + } + } + if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) { + syslog(LOG_DEBUG, "bind(): %m"); close(*s); continue; } + (*socks)++; + s++; } - if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) { - syslog(LOG_DEBUG, "bind(): %m"); - close(*s); - continue; - } - (*socks)++; - s++; } if (res) How-To-Repeat: Run lpd with the -b flag. Nothing happens.