Subject: bin/2771: lpd no network listen patch (third try)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <daw@panix.com>
List: netbsd-bugs
Date: 09/20/1996 16:26:36
>Number: 2771
>Category: bin
>Synopsis: patch no add no network listen option to lpd
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Sep 20 13:35:01 1996
>Last-Modified:
>Originator: Nathaniel D. Daw
>Organization:
Piermont Information Systems
>Release: netbsd current as of today (1.2 beta)
>Environment:
System: NetBSD daw.dialup.access.net 1.2_BETA NetBSD 1.2_BETA (NAT2) #21: Fri Aug 2 10:04:22 EDT 1996 nat@dialup227.cc.columbia.edu:/usr/src/sys/arch/i386/compile/NAT2 i386
>Description:
this is my third try at sending this pr -- I believe its
predecessors didn't get through, but if they did I apologize.
lpd is a little fast and free with accepting connections over
the network. It uses insecure host-based authentication, and,
in many environments (such as my own) it is only used for
local spooling anyway, making its network receive feature at
best superfluous and at worst a potential security hole. I
attach a simple patch to add a -s option (modeled after the
recently committed syslogd -s option) that causes lpd to run
as usual but only accept jobs over unix domain sockets, not
over the network. This option is appropriate for those who
require local print spooling but wish to limit their network
exposure.
>How-To-Repeat:
run lpd and do a netstat -a -finet and you will see that it is
listening on the network.
>Fix:
The following patch is trivial (about six lines of code)
... the reason it is so long is merely that a block of code
was reindented. lpd already had the capacity of running
without a network socket (used just in case the call to socket()
failed); all that is necessary is to recognize the option and
force the behavior.
these patches are for usr.sbin/lpr/lpd.c and usr.sbin/lpr/lpd.8
*** lpd.c.orig Thu Apr 25 07:39:54 1996
--- lpd.c Thu Sep 5 00:29:51 1996
***************
*** 98,103 ****
--- 98,104 ----
#include "extern.h"
int lflag; /* log requests flag */
+ int sflag; /* secure (no inet) flag */
int from_remote; /* from remote socket */
static void reapchild __P((int));
***************
*** 122,127 ****
--- 123,129 ----
euid = geteuid(); /* these shouldn't be different */
uid = getuid();
options = 0;
+ sflag = 0;
gethostname(host, sizeof(host));
name = argv[0];
***************
*** 135,140 ****
--- 137,145 ----
case 'l':
lflag++;
break;
+ case 's':
+ sflag++;
+ break;
}
}
***************
*** 200,228 ****
FD_ZERO(&defreadfds);
FD_SET(funix, &defreadfds);
listen(funix, 5);
! finet = socket(AF_INET, SOCK_STREAM, 0);
! if (finet >= 0) {
! struct servent *sp;
!
! if (options & SO_DEBUG)
! if (setsockopt(finet, SOL_SOCKET, SO_DEBUG, 0, 0) < 0) {
! syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
mcleanup(0);
}
! sp = getservbyname("printer", "tcp");
! if (sp == NULL) {
! syslog(LOG_ERR, "printer/tcp: unknown service");
! mcleanup(0);
! }
! memset(&sin, 0, sizeof(sin));
! sin.sin_family = AF_INET;
! sin.sin_port = sp->s_port;
! if (bind(finet, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
! syslog(LOG_ERR, "bind: %m");
! mcleanup(0);
}
- FD_SET(finet, &defreadfds);
- listen(finet, 5);
}
/*
* Main loop: accept, do a request, continue.
--- 205,239 ----
FD_ZERO(&defreadfds);
FD_SET(funix, &defreadfds);
listen(funix, 5);
! if (!sflag) {
! finet = socket(AF_INET, SOCK_STREAM, 0);
! if (finet >= 0) {
! struct servent *sp;
!
! if (options & SO_DEBUG)
! if (setsockopt(finet, SOL_SOCKET,
! SO_DEBUG, 0, 0) < 0) {
! syslog(LOG_ERR,
! "setsockopt (SO_DEBUG): %m");
! mcleanup(0);
! }
! sp = getservbyname("printer", "tcp");
! if (sp == NULL) {
! syslog(LOG_ERR,
! "printer/tcp: unknown service");
mcleanup(0);
}
! memset(&sin, 0, sizeof(sin));
! sin.sin_family = AF_INET;
! sin.sin_port = sp->s_port;
! if (bind(finet, (struct sockaddr *)&sin,
! sizeof(sin)) < 0) {
! syslog(LOG_ERR, "bind: %m");
! mcleanup(0);
! }
! FD_SET(finet, &defreadfds);
! listen(finet, 5);
}
}
/*
* Main loop: accept, do a request, continue.
***************
*** 261,267 ****
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
(void) close(funix);
! (void) close(finet);
dup2(s, 1);
(void) close(s);
if (domain == AF_INET) {
--- 272,279 ----
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
(void) close(funix);
! if (!sflag)
! (void) close(finet);
dup2(s, 1);
(void) close(s);
if (domain == AF_INET) {
*** lpd.8.orig Mon Dec 11 15:57:19 1995
--- lpd.8 Thu Sep 5 00:15:48 1996
***************
*** 68,73 ****
--- 68,84 ----
.Nm lpd
to log valid requests received from the network. This can be useful
for debugging purposes.
+ .It Fl s
+ The
+ .Fl s
+ flag selects ``secure'' mode, in which
+ .Nm lpd
+ does not listen on a TCP socket but only takes commands from a UNIX
+ domain socket. This is valuable when the machine on which
+ .Nm lpd
+ 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 Ar "port#"
The Internet port number used to rendezvous
with other processes is normally obtained with
>Audit-Trail:
>Unformatted: