From owner-freebsd-bugs@FreeBSD.ORG Sun Apr 27 16:00:00 2014 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BA72BA66 for ; Sun, 27 Apr 2014 16:00:00 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 960C02FA for ; Sun, 27 Apr 2014 16:00:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s3RG00o2096289 for ; Sun, 27 Apr 2014 16:00:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s3RG000M096288; Sun, 27 Apr 2014 16:00:00 GMT (envelope-from gnats) Resent-Date: Sun, 27 Apr 2014 16:00:00 GMT Resent-Message-Id: <201404271600.s3RG000M096288@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ayan George Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 8CED1A4E for ; Sun, 27 Apr 2014 15:58:27 +0000 (UTC) Received: from mail-yh0-f50.google.com (mail-yh0-f50.google.com [209.85.213.50]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4C66F2EA for ; Sun, 27 Apr 2014 15:58:26 +0000 (UTC) Received: by mail-yh0-f50.google.com with SMTP id b6so2524521yha.37 for ; Sun, 27 Apr 2014 08:58:20 -0700 (PDT) Received: from localhost ([71.47.129.191]) by mx.google.com with ESMTPSA id u5sm25371251yhg.25.2014.04.27.08.58.17 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 Apr 2014 08:58:18 -0700 (PDT) Message-Id: <535d2968.zZuyMuZBy3k8HFZB%ayan@ayan.net> Date: Sun, 27 Apr 2014 15:59:36 +0000 From: Ayan George To: FreeBSD-gnats-submit@freebsd.org Subject: bin/189052: [PATCH] add -b flag to lpd X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list Reply-To: Ayan George List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Apr 2014 16:00:00 -0000 >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