Subject: bin/12112: lpd fixes
To: None <gnats-bugs@gnats.netbsd.org>
From: Feico Dillema <feico@pasta.cs.uit.no>
List: netbsd-bugs
Date: 02/02/2001 02:15:20
>Number: 12112
>Category: bin
>Synopsis: lpd does not listen to port given on commandline as manual page says
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Feb 02 02:18:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Feico Dillema <feico@pasta.cs.uit.no>
>Release: NetBSD-1.5
>Organization:
University of Tromsų, Tromsų, Norway
>Environment:
System: NetBSD drifter.dillema.net 1.5Q NetBSD 1.5Q (DRIFTER-CB) #0: Wed Jan 24 20:58:37 CET 2001 root@drifter.dillema.net:/usr/cvs/netbsd-current/sys/arch/i386/compile/DRIFTER-CB i386
Architecture: i386
Machine: i386
Description:
lpd currently always listens on the printer/tcp port, even if another
port number is given on its commandline. In addition, there is no way
(AFAIK) to specify on the client side (in /etc/printcap) how to send
printjobs to a remote machine on a different port than the standard
one. Also, lpd lacks options to let it listen to IPv4 only or to IPv4
only, which would be nice to have in certain cases.
>Description:
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
>How-To-Repeat:
Only first issue is a bug (or discrepency between man page and code),
and can simply be repeated by:
lpd 516
netstat -a will show that lpd still listens at port 515 instead.
>Fix:
I have attached a few minor patches to this report that will fix all
the ommissions mentioned in the description. It adds the -4 and -6
options to lpd, fixes the port on commandline for lpd, and the `most
drastic' change: the `rm' in /etc/printcap entries will now in addition
to just a machinename also accept portnum@machinename (so that lpd's
running at different ports can actually be used).
An alternative way to fix this is to drop the port on commandline for
lpd and fix the manpage and usage() output of lpd.
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="rmjob.diff"
--- usr.sbin/lpr/common_source/rmjob.c Fri Feb 2 10:31:37 2001
+++ usr.sbin/lpr/common_source/rmjob.c.new Thu Feb 1 16:54:10 2001
@@ -322,7 +322,7 @@
void
rmremote()
{
- char *cp, *s;
+ char *cp, *s, *rmhost;
int i, rem;
size_t len;
@@ -364,7 +364,10 @@
cp[0] = '\n';
cp[1] = '\0';
- rem = getport(RM, 0);
+ if ((rmhost = strchr(RM, '@')))
+ rem = getport(rmhost+1, atoi(RM));
+ else
+ rem = getport(RM, 0);
if (rem < 0) {
if (from != host)
printf("%s: ", host);
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="displayq.c.diff"
--- usr.sbin/lpr/common_source/displayq.c Fri Feb 2 10:31:37 2001
+++ usr.sbin/lpr/common_source/displayq.c.new Thu Feb 1 16:52:33 2001
@@ -100,7 +100,7 @@
{
struct queue *q;
int i, nitems, fd, ret;
- char *cp;
+ char *cp, *rmhost;
struct queue **queue;
struct stat statb;
FILE *fp;
@@ -254,7 +254,10 @@
(sizeof(line) - (cp - line) - 1));
}
(void)strncat(line, "\n", sizeof(line) - strlen(line) - 1);
- fd = getport(RM, 0);
+ if ((rmhost = strchr(RM, '@')))
+ fd = getport(rmhost+1, atoi(RM));
+ else
+ fd = getport(RM, 0);
if (fd < 0) {
if (from != host)
printf("%s: ", host);
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="lpd.8.diff"
--- usr.sbin/lpr/lpd/lpd.8 Fri Feb 2 10:53:05 2001
+++ usr.sbin/lpr/lpd/lpd.8.new Fri Feb 2 10:51:22 2001
@@ -110,6 +110,18 @@
runs is subject to attack over the network and it is desired that the
machine be protected from attempts to remotely fill spools and similar
attacks.
+.It Fl 4
+The
+.Fl 4
+flag forces
+.Nm
+to listen to IPv4 addresses only.
+.It Fl 6
+The
+.Fl 6
+flag forces
+.Nm
+to listen to IPv6 addresses only.
.It Fl w
The
.Fl w
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="lpd.c.diff"
--- usr.sbin/lpr/lpd/lpd.c Fri Feb 2 10:53:05 2001
+++ usr.sbin/lpr/lpd/lpd.c.new Fri Feb 2 11:07:25 2001
@@ -123,7 +123,7 @@
static void chkhost __P((struct sockaddr *));
static int ckqueue __P((char *));
static void usage __P((void));
-static int *socksetup __P((int, int));
+static int *socksetup __P((int, int, char *));
uid_t uid, euid;
int child_count;
@@ -140,7 +140,9 @@
int lfd, errs, i, f, funix, *finet;
int child_max = 32; /* more then enough to hose the system */
int options = 0;
- struct servent *sp, serv;
+ int af = PF_UNSPEC;
+ struct servent *sp;
+ char port[NI_MAXSERV] = "printer";
euid = geteuid(); /* these shouldn't be different */
uid = getuid();
@@ -169,6 +171,12 @@
case 's':
sflag++;
break;
+ case '4':
+ af=PF_INET;
+ break;
+ case '6':
+ af=PF_INET6;
+ break;
case 'w':
wait_time = atoi(optarg);
if (wait_time < 0)
@@ -192,8 +200,7 @@
if (i < 0 || i > USHRT_MAX)
errx(1, "port # %d is invalid", i);
- serv.s_port = htons(i);
- sp = &serv;
+ strcpy (port, argv[0]);
break;
case 0:
sp = getservbyname("printer", "tcp");
@@ -275,7 +282,7 @@
FD_SET(funix, &defreadfds);
listen(funix, 5);
if (!sflag)
- finet = socksetup(PF_UNSPEC, options);
+ finet = socksetup(af, options, port);
else
finet = NULL; /* pretend we couldn't open TCP socket. */
@@ -666,7 +673,7 @@
{
extern char *__progname; /* XXX */
- fprintf(stderr, "usage: %s [-dlrs] [-n maxchild] [-w maxwait] [port]\n",
+ fprintf(stderr, "usage: %s [-dlrs64] [-n maxchild] [-w maxwait] [port]\n",
__progname);
exit(1);
}
@@ -675,8 +682,9 @@
/* if af is PF_UNSPEC more than one socket may be returned */
/* the returned list is dynamically allocated, so caller needs to free it */
int *
-socksetup(af, options)
+socksetup(af, options, port)
int af, options;
+ char *port;
{
struct addrinfo hints, *res, *r;
int error, maxs, *s, *socks;
@@ -686,7 +694,7 @@
hints.ai_flags = AI_PASSIVE;
hints.ai_family = af;
hints.ai_socktype = SOCK_STREAM;
- error = getaddrinfo(NULL, "printer", &hints, &res);
+ error = getaddrinfo(NULL, port, &hints, &res);
if (error) {
syslog(LOG_ERR, "%s", gai_strerror(error));
mcleanup(0);
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="printcap.5.diff"
--- share/man/man5/printcap.5 Fri Feb 2 10:29:35 2001
+++ share/man/man5/printcap.5.new Fri Feb 2 10:28:51 2001
@@ -112,7 +112,7 @@
.Tn FORTRAN
style text files
.It "rg str" Ta Dv NULL Ta No "restricted group. Only members of group allowed access"
-.It "rm str" Ta Dv NULL Ta No "machine name for remote printer"
+.It "rm str" Ta Dv NULL Ta No "machine name for remote printer or port@machinename"
.It "rp str ``lp'' remote printer name argument"
.It "rs bool false restrict remote users to those with local accounts"
.It "rw bool false open the printer device for reading and writing"
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="printjob.c.diff"
--- usr.sbin/lpr/lpd/printjob.c Fri Feb 2 10:31:37 2001
+++ usr.sbin/lpr/lpd/printjob.c.new Fri Feb 2 11:09:30 2001
@@ -1426,10 +1426,14 @@
{
int i, n;
int resp;
+ char *rmhost;
for (i = 1; ; i = i < 256 ? i << 1 : i) {
resp = -1;
- pfd = getport(RM, 0);
+ if ((rmhost = strchr(RM, '@')))
+ pfd = getport(rmhost+1, atoi(RM));
+ else
+ pfd = getport(RM, 0);
if (pfd >= 0) {
n = snprintf(line, sizeof(line), "\2%s\n", RP);
if (write(pfd, line, n) == n &&
--BI5RvnYi6R4T2M87
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="common.c.diff"
--- usr.sbin/lpr/common_source/common.c Fri Feb 2 10:31:37 2001
+++ usr.sbin/lpr/common_source/common.c.new Thu Feb 1 16:46:49 2001
@@ -309,7 +309,7 @@
char *
checkremote()
{
- char hname[NI_MAXHOST];
+ char hname[NI_MAXHOST], *rmhost;
struct addrinfo hints, *res;
static char errbuf[128];
int error;
@@ -346,7 +346,11 @@
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
res = NULL;
- error = getaddrinfo(RM, NULL, &hints, &res);
+ if ((rmhost = strchr(RM, '@')))
+ rmhost++;
+ else
+ rmhost = RM;
+ error = getaddrinfo(rmhost, NULL, &hints, &res);
if (error || !res->ai_canonname) {
(void)snprintf(errbuf, sizeof(errbuf),
"unable to get official name for local machine %s: "
--BI5RvnYi6R4T2M87--
>Release-Note:
>Audit-Trail:
>Unformatted: