Date: Sun, 27 Apr 2014 15:59:36 +0000 From: Ayan George <ayan@ayan.net> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/189052: [PATCH] add -b flag to lpd Message-ID: <535d2968.zZuyMuZBy3k8HFZB%ayan@ayan.net> Resent-Message-ID: <201404271600.s3RG000M096288@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 189052 >Category: bin >Synopsis: Add -b flag to lpd >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Apr 27 16:00:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Ayan George >Release: FreeBSD 11.0-CURRENT amd64 >Organization: >Environment: System: FreeBSD jade.ayan.net 11.0-CURRENT FreeBSD 11.0-CURRENT #11 1cb4e21(master): Fri Apr 18 06:38:05 UTC 2014 root@jade.ayan.net:/usr/obj/usr/src/sys/GENERIC amd64 >Description: 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. >How-To-Repeat: Run lpd with the -b flag. Nothing happens. >Fix: --=_535d2968.C0MYINDQnjnMBjhJbHvnzMZh7I/to232P0ALuEGVO9Sdb8o/ Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="lpd.patch" 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) --=_535d2968.C0MYINDQnjnMBjhJbHvnzMZh7I/to232P0ALuEGVO9Sdb8o/-- >Release-Note: >Audit-Trail: >Unformatted: This is a multi-part message in MIME format. --=_535d2968.C0MYINDQnjnMBjhJbHvnzMZh7I/to232P0ALuEGVO9Sdb8o/ Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?535d2968.zZuyMuZBy3k8HFZB%ayan>