Subject: misc/4617: inetd -l option is to broad a brush
To: None <gnats-bugs@gnats.netbsd.org>
From: Paul M. Newhouse <newhouse@rockhead.com>
List: netbsd-bugs
Date: 12/01/1997 05:41:26
>Number:         4617
>Category:       misc
>Synopsis:       inetd -l option is to broad a brush
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    misc-bug-people (Misc Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Dec  1 05:50:02 1997
>Last-Modified:
>Originator:     Paul M. Newhouse
>Organization:
Rockhead Enterprises
>Release:        11/29/97 tar files
>Environment:
System: NetBSD pimin 1.3_ALPHA NetBSD 1.3_ALPHA (PIMIN) #12: Sun Nov 30 10:29:23 MST 1997 newhouse@pimin:/usr/src/sys/arch/i386/compile/PIMIN i386


>Description:
	"inetd -l" records all but denied requests, this is too much in some circumstances:
	For instance, my wife is using one of my NetBSD systems as a pop server and I'm really 
	not interested in the fact that she has set her machine to pop mail every 5 minutes.
	In a couple of days the log file is filled with nothing but, "I popped mail again".  
	An ISP might what to log all of this but, not in my case and I don't think my situation
	is all that unique.
>How-To-Repeat:
	start "inetd -l" on a system serving mail via pop3.  Start a machine that pops mail
	every 5 minutes from the mail server.  
>Fix:
	I have put together a simple solution which follows.  It causes inetd to scan the
	file "/etc/inetd.nolog".  If inetd was going to make a log entry it scans the table
	constructed from the nolog file and if it finds the host:service pair it does not
	make the log entry.

	I've tested the code which follows and it seems to work as I have described.
	Changes for inetd.c, pathnames.h and inetd.8 follow:

	*** inetd.c.ORIG	Mon Dec  1 03:18:37 1997
	--- inetd.c.NEW	Mon Dec  1 05:19:20 1997
	***************
	*** 272,277 ****
	--- 272,285 ----
	  	struct	servtab *se_next;
	  } *servtab;
	  
	+ void	bld_nologtab(void);
	+ void	free_nologtab(void);
	+ static	int	nolog_max = 0;
	+ static	struct	nolog_tab {
	+ 	char	*host;
	+ 	char	*service;
	+ 	} *nologtab = NULL, *nolog_tmp;
	+ 
	  #define NORM_TYPE	0
	  #define MUX_TYPE	1
	  #define MUXPLUS_TYPE	2
	***************
	*** 595,603 ****
	  			goto reject;
	  		}
	  		if (lflag) {
	! 			syslog(allow_severity,
	! 			    "connection from %.500s, service %s (%s)",
	! 			    eval_client(&req), service, sep->se_proto);
	  		}
	  	}
	  #endif /* LIBWRAP */
	--- 603,619 ----
	  			goto reject;
	  		}
	  		if (lflag) {
	! 			int i;
	!         	for(i=0; i<nolog_max; i++) {
	! 				if ((strcmp(nologtab[i].host, eval_client(&req)) == 0)
	! 						&& ((strcmp(nologtab[i].service, sep->se_service) == 0)
	! 						|| (nologtab[i].service == NULL)))
	! 				break;
	!         	}
	!         	if (i == nolog_max)  /* i.e. - we didn't find a nolog entry */
	! 				syslog(allow_severity,
	! 				    "connection from %.500s, service %s (%s)",
	! 				    eval_client(&req), service, sep->se_proto);
	  		}
	  	}
	  #endif /* LIBWRAP */
	***************
	*** 715,720 ****
	--- 731,737 ----
	  		syslog(LOG_ERR, "%s: %m", CONFIG);
	  		return;
	  	}
	+ 	free_nologtab();
	  	for (sep = servtab; sep; sep = sep->se_next)
	  		sep->se_checked = 0;
	  	while ((cp = getconfigent())) {
	***************
	*** 868,873 ****
	--- 885,891 ----
	  		}
	  	}
	  	endconfig();
	+ 	bld_nologtab();
	  	/*
	  	 * Purge anything not looked at above.
	  	 */
	***************
	*** 1871,1877 ****
	  }
	  
	  
	! #ifdef MULOG
	  dolog(sep, ctrl)
	  	struct servtab *sep;
	  	int		ctrl;
	--- 1889,1986 ----
	  }
	  
	  
	! int
	! alloc_nologtab(int *allocated) {
	! 	if (*allocated < ++nolog_max) {
	! 		if ((nolog_tmp = (struct nolog_tab *)realloc(nologtab,
	! 				(*allocated += 20)*sizeof(struct nolog_tab))) 
	! 				<= 0) {
	! 			/*
	! 				Log malloc failure and return
	! 			*/
	! 			syslog(LOG_ERR, "realloc of nologtab failed %d %d",
	! 					*allocated, nolog_max);
	! 			return(1);
	! 		}
	! 		nologtab = nolog_tmp;
	! 		nologtab[nolog_max-1].host    = NULL;
	! 		nologtab[nolog_max-1].service = NULL;
	! 	}
	! 	return(0);
	! }
	! 
	! void
	! bld_nologtab() {
	! 	int 	allocated = 0, i, j;
	! 	FILE	*fd;
	! 	char	*cp, *service, *host;
	! 	struct servtab *sep;
	! 
	! 	if ((fd = fopen(_PATH_INETDNOLOG, "r")) == NULL) {
	! 		if (errno != ENOENT)
	! 			syslog(LOG_ERR, "Cannot open %s [%d]\"%s\"",
	! 					_PATH_INETDNOLOG, errno, sys_errlist[errno]);
	! 		return;
	! 	}
	! 	while ((cp = nextline(fd)) != NULL) {
	! 		if (*cp == '#')
	! 			continue;
	! 		if ((host = sskip(&cp)) != NULL) {
	! 			for (j=i=0; i<nolog_max-1; i++)
	! 				if (strcmp(host, nologtab[i].host) == 0) {
	! 					j = i;
	! 					break;
	! 				}
	! 			/*
	! 				parse off each service that is not to be logged.
	! 			*/
	! 			while ((*cp != '\0') && ((service = sskip(&cp)) != NULL)) {
	! 				for (sep = servtab; sep != 0; sep = sep->se_next) {
	! 					if (strcmp(service, sep->se_service) == 0) {
	! 						if (alloc_nologtab(&allocated) != 0) {
	! 							fclose(fd);
	! 							return;
	! 						}
	! 						if (j == 0) {
	! 							j = nolog_max-1;
	! 							nologtab[j].host = malloc(strlen(host)+1);
	! 							strcpy(nologtab[j].host, host);
	! 						} else
	! 							nologtab[nolog_max-1].host = nologtab[j].host;
	! 						nologtab[nolog_max-1].service = sep->se_service;
	! 						break;
	! 					}
	! 				}
	! 				if (sep == 0)
	! 					syslog(LOG_NOTICE, "%s is an unkown service", service);
	! 			}
	! 		}
	! 	}
	! 	fclose(fd);
	! }
	! 
	! void
	! free_nologtab() {
	! 	int i, j;
	! 	char	*h, *s;
	! 
	! 	for (i=0; i<nolog_max; i++) {
	! 		h = nologtab[i].host;
	! 		s = nologtab[i].service;
	! 		for (j=i; j<nolog_max; j++) {
	! 			if (h == nologtab[j].host)
	! 				nologtab[j].host = NULL;
	! 			if (s == nologtab[j].service)
	! 				nologtab[j].service = NULL;
	! 		}
	! 		free(h);
	! 		free(s);
	! 	}
	! 	free(nologtab);
	! 	nologtab = NULL;
	! 	nolog_max = 0;
	! }
	! #ifdef	MULOG
	  dolog(sep, ctrl)
	  	struct servtab *sep;
	  	int		ctrl;
	
	
	*** pathnames.h.ORIG	Mon Dec  1 04:36:38 1997
	--- pathnames.h.NEW	Mon Dec  1 05:53:21 1997
	***************
	*** 39,41 ****
	--- 39,42 ----
	  
	  #define	_PATH_INETDCONF	"/etc/inetd.conf"
	  #define _PATH_INETDPID	"/var/run/inetd.pid"
	+ #define	_PATH_INETDNOLOG	"/etc/inetd.nolog"
	
	
	*** inetd.8.ORIG	Mon Dec  1 05:55:40 1997
	--- inetd.8.NEW	Mon Dec  1 06:15:39 1997
	***************
	*** 79,86 ****
	  Upon execution,
	  .Nm
	  reads its configuration information from configuration
	! file which, by default, is
	! .Pa /etc/inetd.conf .
	  There must be an entry for each field of the configuration
	  file, with entries for each field separated by a tab or
	  a space.  Comments are denoted by a ``#'' at the beginning
	--- 79,88 ----
	  Upon execution,
	  .Nm
	  reads its configuration information from configuration
	! files which, by default, are
	! .Pa /etc/inetd.conf
	! and
	! .Pa /etc/inetd.nolog .
	  There must be an entry for each field of the configuration
	  file, with entries for each field separated by a tab or
	  a space.  Comments are denoted by a ``#'' at the beginning
	***************
	*** 296,303 ****
	  .Tn RFC
	  from the Network Information Center.
	  .Pp
	  .Nm
	! rereads its configuration file when it receives a hangup signal,
	  .Dv SIGHUP .
	  Services may be added, deleted or modified when the configuration file
	  is reread.
	--- 298,318 ----
	  .Tn RFC
	  from the Network Information Center.
	  .Pp
	+ If 
	+ .Nm
	+ is started with the 
	+ .Op Fl l
	+ option then the nolog configuration file consists of hostnames or addresses and
	+ services which are not to be logged for that host.  Continuation lines are not 
	+ allowed.  The file format is:
	+ .Pp
	+ .Bd -unfilled -offset indent -compact
	+ host service-1 service-2 ... service-n
	+ .Ed
	+ .Pp
	+ .Pp
	  .Nm
	! rereads its configuration files when it receives a hangup signal,
	  .Dv SIGHUP .
	  Services may be added, deleted or modified when the configuration file
	  is reread.
>Audit-Trail:
>Unformatted: