1 /***************************************************************************
2  * LPRng - An Extended Print Spooler System
3  *
4  * Copyright 1988-2003, Patrick Powell, San Diego, CA
5  *     papowell@lprng.com
6  * See LICENSE for conditions of use.
7  *
8  ***************************************************************************/
9 
10 #include "lp.h"
11 #include "child.h"
12 #include "fileopen.h"
13 #include "errorcodes.h"
14 #include "initialize.h"
15 #include "linksupport.h"
16 #include "lpd_logger.h"
17 #include "getqueue.h"
18 #include "getopt.h"
19 #include "proctitle.h"
20 #include "lockfile.h"
21 #include "lpd_worker.h"
22 #include "lpd_jobs.h"
23 #include "lpd_dispatch.h"
24 #include "user_auth.h"
25 
26 /* force local definitions */
27 #undef EXTERN
28 #undef DEFINE
29 #undef DEFS
30 
31 #define EXTERN
32 #define DEFINE(X) X
33 #define DEFS
34 
35 #include "lpd.h"
36 
37  char* Lpd_listen_port_arg;	/* command line listen port value */
38 #ifdef IPP_STUBS
39  char* Ipp_listen_port_arg;	/* command line listen port value */
40 #endif /* not IPP_STUBS */
41  char* Lpd_port_arg;	/* command line port value */
42  char* Lpd_socket_arg; /* command line unix socket value */
43 
44 #if HAVE_TCPD_H
45 #include <tcpd.h>
46  int allow_severity = LOG_INFO;
47  int deny_severity = LOG_WARNING;
48 #endif
49 
50 
51 /**** ENDINCLUDE ****/
52 
53 /***************************************************************************
54  * main()
55  * - top level of LPD Lite.  This is a cannonical method of handling
56  *   input.  Note that we assume that the LPD daemon will handle all
57  *   of the dirty work associated with formatting, printing, etc.
58  *
59  * 1. get the debug level from command line arguments
60  * 2. set signal handlers for cleanup
61  * 3. get the Host computer Name and user Name
62  * 4. scan command line arguments
63  * 5. check command line arguments for consistency
64  *
65  ****************************************************************************/
66 
67 	static char *malloc_area;
68 
main(int argc,char * argv[],char * envp[])69 int main(int argc, char *argv[], char *envp[])
70 {
71 	int sock = 0;		/* socket for listen */
72 	pid_t pid;			/* pid */
73 	fd_set defreadfds, readfds;	/* for select() */
74 	int max_socks = 0;		/* maximum number of sockets */
75 	int lockfd;	/* the lock file descriptor */
76 	int err;
77  	time_t last_time;	/* time that last Start_all was done */
78 	time_t server_started_time;	/* time servers were started */
79 	plp_status_t status;
80 	int max_servers;
81 	int start_fd = 0;
82 	pid_t start_pid = 0, logger_process_pid = 0;
83 	int request_pipe[2], status_pipe[2];
84 	pid_t last_fork_pid_value;
85 	struct line_list args;
86 	int first_scan = 1;
87 	int unix_sock = 0;
88 #ifdef IPP_STUBS
89 	int ipp_sock = 0;
90 #endif /* not IPP_STUBS */
91 	int fd_available;
92 
93 	Init_line_list( &args );
94 	Is_server = 1;	/* we are the LPD server */
95 	Logger_fd = -1;
96 
97 #ifndef NODEBUG
98 	Debug = 0;
99 #endif
100 	if(DEBUGL3){
101 		int n;
102 		LOGDEBUG("lpd: argc %d", argc );
103 		for( n = 0; n < argc; ++n ){
104 			LOGDEBUG(" [%d] '%s'", n, argv[n] );
105 		}
106 		LOGDEBUG("lpd: env" );
107 		for( n = 0; envp[n]; ++n ){
108 			LOGDEBUG(" [%d] '%s'", n, envp[n] );
109 		}
110 	}
111 
112 	/* set signal handlers */
113 	(void) plp_signal(SIGHUP,  (plp_sigfunc_t)Reinit);
114 	(void) plp_signal(SIGINT, cleanup_INT);
115 	(void) plp_signal(SIGQUIT, cleanup_QUIT);
116 	(void) plp_signal(SIGTERM, cleanup_TERM);
117 	(void) signal(SIGUSR1, SIG_IGN);
118 	(void) signal(SIGUSR2, SIG_IGN);
119 	(void) signal(SIGCHLD, SIG_DFL);
120 	(void) signal(SIGPIPE, SIG_IGN);
121 
122 	/*
123 	the next bit of insanity is caused by the interaction of signal(2) and execve(2)
124 	man signal(2):
125 
126 	 When a process which has installed signal handlers forks, the child pro-
127 	 cess inherits the signals.  All caught signals may be reset to their de-
128 	 fault action by a call to the execve(2) function; ignored signals remain
129 	 ignored.
130 
131 
132 	man execve(2):
133 
134 	 Signals set to be ignored in the calling process are set to be ignored in
135 					   ^^^^^^^
136 					   signal(SIGCHLD, SIG_IGN)  <- in the acroread code???
137 
138 	 the new process. Signals which are set to be caught in the calling pro-
139 	 cess image are set to default action in the new process image.  Blocked
140 	 signals remain blocked regardless of changes to the signal action.  The
141 	 signal stack is reset to be undefined (see sigaction(2) for more informa-
142 	 tion).
143 
144 
145 	^&*(*&^!!! &*())&*&*!!!  and again, I say, &*()(&*!!!
146 
147 	This means that if you fork/execve a child,  then you better make sure
148 	that you set up its signal/mask stuff correctly.
149 
150     So if somebody blocks all signals and then starts up LPD,  it will not work
151 	correctly.
152 
153 	*/
154 
155 	{ plp_block_mask oblock; plp_unblock_all_signals( &oblock ); }
156 
157 
158 	Get_parms(argc, argv);      /* scan input args */
159 
160 	Initialize(argc, argv, envp, 'D' );
161 	DEBUG1("Get_parms: UID_root %ld, OriginalRUID %ld", (long)UID_root, (long)OriginalRUID);
162 
163 	if( UID_root && (OriginalRUID != ROOTUID) ){
164 		fatal(LOG_ERR, "lpd installed SETUID root and started by user %ld! Possible hacker attack", (long)OriginalRUID);
165 	}
166 
167 	Setup_configuration();
168 
169 	/* get the maximum number of servers allowed */
170 	max_servers = Get_max_servers();
171 	if(DEBUGL1){
172 		int max_file_descriptors = Get_max_fd();
173 		DEBUG1( "lpd: maximum servers %d, maximum file descriptors %d ",
174 			max_servers, max_file_descriptors );
175 	}
176 
177 	if( Lockfile_DYN == 0 ){
178 		logerr_die(LOG_INFO, _("No LPD lockfile specified!") );
179 	}
180 
181 	/* chdir to the root directory */
182 	if( chdir( "/" ) == -1 ){
183 		Errorcode = JABORT;
184 		logerr_die(LOG_ERR, "cannot chdir to /");
185 	}
186 	pid = Get_lpd_pid();
187 #if defined(__CYGWIN__)
188 	if( (pid > 0) && ( kill(pid,0) || (errno != ESRCH) )) {
189 		DIEMSG( _("Another print spooler active, possibly lpd process '%ld'"),
190   				(long)pid );
191 	}
192 	lockfd = Lock_lpd_pid();
193 	if( lockfd < 0 ){
194 		DIEMSG( _("cannot open or lock lockfile - %s"), Errormsg(errno) );
195 	}
196 	Set_lpd_pid( lockfd );
197 	close( lockfd );
198 	lockfd = -1;
199 #else
200 	lockfd = Lock_lpd_pid();
201 	if( lockfd < 0 ){
202 		DIEMSG( _("Another print spooler active, possibly lpd process '%ld'"),
203   				(long)pid );
204 	}
205 	Set_lpd_pid( lockfd );
206 #endif
207 
208 	{
209 		char *s;
210 		s = Lpd_listen_port_arg;
211 		if( ISNULL(s) ) s = Lpd_listen_port_DYN;
212 		if( ISNULL(s) ) s = Lpd_port_DYN;
213 		if( !ISNULL(s) && safestrcasecmp( s,"off") && strtol(s,0,0) ){
214 			sock = Link_listen(s);
215 			DEBUG1("lpd: listening socket fd %d",sock);
216 			if( sock < 0 ){
217 				Errorcode = 1;
218 				DIEMSG("Cannot bind to lpd port '%s'", s);
219 			}
220 			if( sock >= max_socks ) max_socks = sock;
221 		}
222 
223 #ifdef IPP_STUBS
224 		s = Ipp_listen_port_arg;
225 		if( ISNULL(s) ) s = Ipp_listen_port_DYN;
226 		if( !ISNULL(s) && safestrcasecmp( s,"off") && strtol(s,0,0) ){
227 			ipp_sock = Link_listen(s);
228 			DEBUG1("lpd: listening socket fd %d",ipp_sock);
229 			if( ipp_sock < 0 ){
230 				Errorcode = 1;
231 				DIEMSG("Cannot bind to lpd port '%s'", s);
232 			}
233 			if( ipp_sock >= max_socks ) max_socks = ipp_sock;
234 		}
235 
236 #endif /* not IPP_STUBS */
237 		s = Lpd_socket_arg;
238 		if( ISNULL(s) ) s = Unix_socket_path_DYN;
239 		if( !ISNULL(s) && safestrcasecmp( s,"off") ){
240 			unix_sock = Unix_link_listen(s);
241 			DEBUG1("lpd: unix listening socket fd %d, path '%s'",unix_sock, s);
242 			if( unix_sock < 0 ){
243 				Errorcode = 1;
244 				DIEMSG("Cannot bind to UNIX socket '%s'", s );
245 			}
246 			if( unix_sock >= max_socks ) max_socks = unix_sock;
247 		}
248 	}
249 
250 	/* setting nonblocking on the listening fd
251 	 * will prevent a problem with terminations of connections
252 	 * before ACCEPT has completed
253 	 *  1. user connects, does the 3 Way Handshake
254 	 *  2. before accept() is done,  a RST packet is sent
255 	 *  3. a select() will succeed, but the accept() will hang
256 	 *  4. if the non-blocking mode is used, then the select will
257 	 *     succeed and the accept() will fail
258 	 */
259 	Set_nonblock_io(sock);
260 
261 	/*
262 	 * At this point you are the server for the LPD port
263 	 * you need to fork to allow the regular user to continue
264 	 * you put the child in its separate process group as well
265 	 */
266 	if( (pid = dofork(1)) < 0 ){
267 		logerr_die(LOG_ERR, _("lpd: main() dofork failed") );
268 	} else if( pid ){
269 		if( Foreground_LPD ){
270 			while( (pid = plp_waitpid( pid, &status, 0)) > 0 ){
271 				DEBUG1( "lpd: process %ld, status '%s'",
272 					(long)pid, Decode_status(&status));
273 			}
274 		}
275 		Errorcode = 0;
276 		exit(0);
277 	}
278 
279 	/* set up the log file and standard environment - do not
280 	   fool around with anything but fd 0,1,2 which should be safe
281 		as we made sure that the fd 0,1,2 existed.
282     */
283 
284 	Setup_log( Logfile_LPD );
285 
286 	Name = "Waiting";
287 	setproctitle( "lpd %s", Name  );
288 
289 	/*
290 	 * Write the PID into the lockfile
291 	 */
292 
293 #if defined(__CYGWIN__)
294 	lockfd = Lock_lpd_pid();
295 	if( lockfd < 0 ) {
296 	   DIEMSG( "Can't open lockfile for writing" );
297 	}
298 	Set_lpd_pid( lockfd );
299 	close( lockfd );
300 	lockfd = -1;
301 #else
302 	Set_lpd_pid( lockfd );
303 #endif
304 
305 
306 	if( Drop_root_DYN ){
307 		Full_daemon_perms();
308 	}
309 
310 	/* establish the pipes for low level processes to use */
311 	if( pipe( request_pipe ) == -1 ){
312 		logerr_die(LOG_ERR, _("lpd: pipe call failed") );
313 	}
314 	Max_open(request_pipe[0]); Max_open(request_pipe[1]);
315 	DEBUG2( "lpd: fd request_pipe(%d,%d)",request_pipe[0],request_pipe[1]);
316 	Lpd_request = request_pipe[1];
317 	Set_nonblock_io( Lpd_request );
318 
319 	Logger_fd = -1;
320 	logger_process_pid = -1;
321 	if( Logger_destination_DYN ){
322 		if( pipe( status_pipe ) == -1 ){
323 			logerr_die(LOG_ERR, _("lpd: pipe call failed") );
324 		}
325 		Max_open(status_pipe[0]); Max_open(status_pipe[1]);
326 		Logger_fd = status_pipe[1];
327 		DEBUG2( "lpd: fd status_pipe(%d,%d)",status_pipe[0],status_pipe[1]);
328 		logger_process_pid = Start_logger( status_pipe[0] );
329 		if( logger_process_pid < 0 ){
330 			logerr_die(LOG_ERR, _("lpd: cannot start initial logger process") );
331 		}
332 	}
333 
334 	/* open a connection to logger */
335 	setmessage(0,LPD,"Starting");
336 
337 	/*
338 	 * set up the select parameters
339 	 */
340 
341 	FD_ZERO( &defreadfds );
342 	if( sock > 0 ) FD_SET( sock, &defreadfds );
343 	if( unix_sock > 0 ) FD_SET( unix_sock, &defreadfds );
344 #ifdef IPP_STUBS
345 	if( ipp_sock > 0 ) FD_SET( ipp_sock, &defreadfds );
346 #endif /* not IPP_STUBS */
347 	FD_SET( request_pipe[0], &defreadfds );
348 
349 	/*
350 	 * start waiting for connections from processes
351 	 */
352 
353 	last_time = time( (void *)0 );
354  	server_started_time = 0;
355 
356 	start_pid = last_fork_pid_value = Start_all(first_scan, &start_fd );
357 	Fork_error( last_fork_pid_value );
358 	if( start_pid > 0 ){
359 		first_scan = 0;
360 	}
361 
362 	malloc_area = sbrk(0);
363 
364 #ifdef DMALLOC
365 	DEBUG1( "lpd: LOOP START - sbrk 0x%lx", (long)malloc_area );
366 	{
367 		extern int dmalloc_outfile_fd;
368 		char buffer[128];
369 		plp_snprintf(buffer,sizeof(buffer), "lpd: LOOP START - sbrk 0x%lx\n", (long)malloc_area );
370 		Write_fd_str(dmalloc_outfile_fd, buffer );
371 		dmalloc_log_unfreed();
372 	}
373 #endif
374 
375 
376 	do{
377 		struct timeval timeval, *timeout;
378 		time_t this_time = time( (void *)0 );
379 		int elapsed_time;
380 
381 #ifdef DMALLOC
382 		/* check for memory leaks */
383 		{
384 			char *s = sbrk(0);
385 			int n = s - malloc_area;
386 			DEBUG1("lpd: LOOP - sbrk 0x%lx", (long)s );
387 			if( n > 1024 ){
388 				extern int dmalloc_outfile_fd;
389 				char buffer[128];
390 				plp_snprintf(buffer,sizeof(buffer), "lpd: LOOP sbrk reports 0x%lx, or %d more memory\n", (long)s, n );
391 				Write_fd_str(dmalloc_outfile_fd, buffer );
392 				dmalloc_log_unfreed();
393 				DEBUG1( "lpd: LOOP sbrk reports 0x%lx, or %d more memory", (long)s, n );
394 				malloc_area += n;
395 			}
396 		}
397 #endif
398 
399 		/* set up the timeout values */
400 
401 		timeout = 0;
402 		memset(&timeval, 0, sizeof(timeval));
403 		if(DEBUGL3){ int fd; fd = dup(0); LOGDEBUG("lpd: next fd %d",fd); close(fd); };
404 
405 		DEBUG2( "lpd: Poll_time %d, Force_poll %d, start_pid %ld, start_fd %d, Started_server %d",
406 			Poll_time_DYN, Force_poll_DYN, (long)start_pid, start_fd, Started_server );
407 
408 		if(DEBUGL1)Dump_line_list("lpd - Servers_line_list",&Servers_line_list );
409 
410 		/*
411 		 * collect zombies.  If one exits, you can set last_fork_pid_value
412 		 * to 0, as you may now be able to start a process
413 		 */
414 
415 		while( (pid = plp_waitpid( -1, &status, WNOHANG)) > 0 ){
416 			DEBUG1( "lpd: process %d, status '%s'",
417 				pid, Decode_status(&status));
418 			if( pid == logger_process_pid ){
419 				/* ARGH! the logger process died */
420 				logger_process_pid = -1;
421 			}
422 			if( pid == start_pid ){
423 				start_pid = -1;
424 			}
425 			last_fork_pid_value = 0;
426 		}
427 
428 		/*
429 		 * if the Logger process dies, then you have real problems,
430 		 * so you need to start it up.
431 		 */
432 		if( last_fork_pid_value >= 0 && Logger_fd > 0 && logger_process_pid <= 0 ){
433 			DEBUG1( "lpd: restarting logger process");
434 			last_fork_pid_value = logger_process_pid = Start_logger( status_pipe[0] );
435 			Fork_error( last_fork_pid_value );
436 			DEBUG1("lpd: logger_process_pid %d", logger_process_pid );
437 		}
438 
439 		/* you really do not want to start up more proceses until you can
440 		 */
441 		if( last_fork_pid_value < 0 ){
442 			goto waitloop;
443 		}
444 
445 		/*
446 		 * Check to see if you need to rescan the spool queues
447 		 *  - you have done all of the work in the Servers_line_list
448 		 *    started by the last scan
449 		 *  - it is time to do a new scan
450 		 */
451 
452 		elapsed_time = (this_time - last_time);
453 		if( Poll_time_DYN > 0 && start_pid <= 0 ){
454 			int doit, scanned_queue_count;
455 			DEBUG1("lpd: checking for scan, start_fd %d, start_pid %ld, Poll_time_DYN %d, elapsed_time %d, Started_server %d, Force_poll %d",
456 				start_fd, (long)start_pid, Poll_time_DYN, elapsed_time, Started_server, Force_poll_DYN );
457 			if( elapsed_time >= Poll_time_DYN ){
458 				for( scanned_queue_count = doit = 0;
459 					scanned_queue_count == 0 && doit < Servers_line_list.count; ++doit ){
460 					char *s = Servers_line_list.list[doit];
461 					if( s && cval(s) == '.' ) ++scanned_queue_count;
462 				}
463 				DEBUG1( "lpd: timeout checking for scan,  scanned_queue_count %d", scanned_queue_count);
464 				if( scanned_queue_count == 0
465 					&& ( Started_server || Force_poll_DYN ) ){
466 					last_fork_pid_value = start_pid = Start_all(first_scan, &start_fd );
467 					Fork_error( last_fork_pid_value );
468 					DEBUG1( "lpd: restarting poll, start_pid %ld, start_fd %d", (long)start_pid, start_fd);
469 					if( start_fd > 0 ){
470 						first_scan = 0;
471 						Started_server = 0;
472 						last_time = this_time;
473 					} else {
474 						/* argh! process exhaustion */
475 						goto waitloop;
476 					}
477 				}
478 			} else {
479 				/* oops... need to wait longer */
480 				timeout = &timeval;
481 				timeval.tv_sec = Poll_time_DYN - elapsed_time;
482 			}
483 		}
484 
485 		/*
486 		 * check to see if there are any spool queues that require
487 		 * service. This is the case when
488 		 *  - time since last startup was non-zero
489 		 *  - Servers_line_list has an entry
490 		 *  OR you have had a forced startup request
491 		 */
492 		if( Servers_line_list.count ){
493 			int number_of_servers = Countpid();
494 			int server_processes_started = 0;
495 			int doit;
496 			char *server_to_start = 0;
497 			int forced_start = 0;
498 			elapsed_time = this_time - server_started_time;
499 			/* find the first entry WITHOUT a '.' as first character */
500 			if(DEBUGL1)Dump_line_list("lpd: Servers_line_list", &Servers_line_list );
501 			for( forced_start = doit = 0; !forced_start && doit < Servers_line_list.count; ++doit ){
502 				server_to_start = Servers_line_list.list[doit];
503 				if( server_to_start && cval(server_to_start) != '.' ){
504 					forced_start = 1;
505 					break;
506 				}
507 				server_to_start = 0;
508 			}
509 
510 #ifdef DMALLOC
511 			/* check for memory leaks */
512 			{
513 				char *s = sbrk(0);
514 				int n = s - malloc_area;
515 				DEBUG1("lpd: BEFORE POLL SERVICE - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count );
516 				if( n > 1024 ){
517 					extern int dmalloc_outfile_fd;
518 					char buffer[128];
519 					plp_snprintf(buffer,sizeof(buffer), "lpd: BEFORE POLL SERVICE sbrk reports 0x%lx, or %d more memory\n", (long)s, n );
520 					Write_fd_str(dmalloc_outfile_fd, buffer );
521 					dmalloc_log_unfreed();
522 					DEBUG1( "lpd: BEFORE POLL SERVICE sbrk reports 0x%lx, or %d more memory", (long)s, n );
523 					malloc_area += n;
524 				}
525 			}
526 #endif
527 
528 			while( (elapsed_time > Poll_start_interval_DYN || forced_start )
529 				&& Servers_line_list.count > 0 && server_processes_started < Poll_servers_started_DYN
530 				&& number_of_servers + server_processes_started < max_servers-4 ){
531 				DEBUG1("lpd: elapsed time %d, server_started_time %d, max_servers %d, number_of_servers %d, started %d",
532 					(int)elapsed_time, (int)server_started_time, max_servers, number_of_servers, server_processes_started );
533 
534 				/* find the first entry WITHOUT a '.' as first character */
535 				for( forced_start = doit = 0; doit < Servers_line_list.count; ++doit ){
536 					server_to_start = Servers_line_list.list[doit];
537 					if( server_to_start && cval(server_to_start) != '.' ){
538 						forced_start = 1;
539 						break;
540 					}
541 					server_to_start = 0;
542 				}
543 				/* Ok, then settle for the first entry */
544 				if( !server_to_start ){
545 					doit = 0;
546 					server_to_start = Servers_line_list.list[doit];
547 					if( cval(server_to_start) == '.' ) ++server_to_start;
548 				}
549 				if( !ISNULL(server_to_start) ){
550 					server_started_time = this_time;
551 					DEBUG1("lpd: starting server '%s'", server_to_start );
552 					Free_line_list(&args);
553 					Set_str_value(&args,PRINTER,server_to_start);
554 					last_fork_pid_value = pid = Start_worker( "queue", Service_queue, &args, 0 );
555 					Fork_error( last_fork_pid_value );
556 					Free_line_list(&args);
557 					if( pid > 0 ){
558 						Remove_line_list( &Servers_line_list, doit );
559 						Started_server = 1;
560 						server_started_time = this_time;
561 						if( forced_start ){
562 							++number_of_servers;
563 						} else {
564 							++server_processes_started;
565 						}
566 					} else {
567 						/* argh! process exhaustion */
568 						goto waitloop;
569 					}
570 				} else {
571 					/* empty line... */
572 					Remove_line_list( &Servers_line_list, doit );
573 				}
574 			}
575 
576 #ifdef DMALLOC
577 			/* check for memory leaks */
578 			{
579 				char *s = sbrk(0);
580 				int n = s - malloc_area;
581 				DEBUG1("lpd: AFTER POLL SERVICE - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count );
582 				if( n > 1024 ){
583 					extern int dmalloc_outfile_fd;
584 					char buffer[128];
585 					plp_snprintf(buffer,sizeof(buffer), "lpd: AFTER POLL SERVICE sbrk reports 0x%lx, or %d more memory\n", (long)s, n );
586 					Write_fd_str(dmalloc_outfile_fd, buffer );
587 					dmalloc_log_unfreed();
588 					DEBUG1( "lpd: AFTER POLL SERVICE sbrk reports 0x%lx, or %d more memory", (long)s, n );
589 					malloc_area += n;
590 				}
591 			}
592 #endif
593 
594 		}
595 		/* we see if we have any work to do
596 		 * and then schedule a timeout if necessary to start a process
597 		 * NOTE: if the Poll_start_interval value is 0,
598 		 * then we will wait until a process exits
599 		 */
600 		if( Servers_line_list.count > 0 && Poll_start_interval_DYN ){
601 			int time_left;
602 			elapsed_time = this_time - server_started_time;
603 			time_left = Poll_start_interval_DYN - elapsed_time;
604 			if( time_left < 0 ) time_left = 0;
605 			timeout = &timeval;
606 			if( timeval.tv_sec == 0 || timeval.tv_sec > time_left  ){
607 				timeval.tv_sec = time_left;
608 			}
609 		}
610 
611  waitloop:
612 		/*
613 		 * the place where we actually do some waiting
614 		 */
615 
616 
617 		DEBUG1("lpd: Started_server %d, last_fork_pid_value %ld, active servers %d, max %d",
618 			Started_server, (long)last_fork_pid_value, Countpid(), max_servers );
619 		/* do not accept incoming call if no worker available */
620 		readfds = defreadfds;
621 		if( Countpid() >= max_servers || last_fork_pid_value < 0 ){
622 			DEBUG1( "lpd: not accepting requests" );
623 			if( sock > 0 ) FD_CLR( sock, &readfds );
624 			if( unix_sock > 0 ) FD_CLR( unix_sock, &readfds );
625 #ifdef IPP_STUBS
626 			if( ipp_sock > 0 ) FD_CLR( ipp_sock, &readfds );
627 #endif /* not IPP_STUBS */
628 			timeval.tv_sec = 10;
629 			timeout = &timeval;
630 		}
631 
632 		if( request_pipe[0] >= max_socks ){
633 			max_socks = request_pipe[0]+1;
634 		}
635 		if( start_fd > 0 ){
636 			FD_SET( start_fd, &readfds );
637 			if( start_fd >= max_socks ){
638 				max_socks = start_fd+1;
639 			}
640 		}
641 
642 		DEBUG1( "lpd: starting select timeout '%s', %d sec, max_socks %d",
643 		timeout?"yes":"no", (int)(timeout?timeout->tv_sec:0), max_socks );
644 		if(DEBUGL2){
645 			int i;
646 			for(i=0; i < max_socks; ++i ){
647 				if( FD_ISSET( i, &readfds ) ){
648 					LOGDEBUG( "lpd: waiting for fd %d to be readable", i );
649 				}
650 			}
651 		}
652 		Setup_waitpid_break();
653 		errno = 0;
654 		fd_available = select( max_socks,
655 			&readfds, NULL, NULL, timeout );
656 		err = errno;
657 		Setup_waitpid();
658 		if(DEBUGL1){
659 			int i;
660 			LOGDEBUG( "lpd: select returned %d, error '%s'",
661 				fd_available, Errormsg(err) );
662 			for(i=0; fd_available > 0 && i < max_socks; ++i ){
663 				if( FD_ISSET( i, &readfds ) ){
664 					LOGDEBUG( "lpd: fd %d readable", i );
665 				}
666 			}
667 		}
668 		/* if we got a SIGHUP then we reread configuration */
669 		if( Reread_config || !Use_info_cache_DYN ){
670 			DEBUG1( "lpd: rereading configuration" );
671 			/* we need to force the LPD logger to use new printcap information */
672 			if( Reread_config ){
673 				if( logger_process_pid > 0 ) kill( logger_process_pid, SIGINT );
674 				setmessage(0,LPD,"Restart");
675 				Reread_config = 0;
676 			}
677 			Setup_configuration();
678 		}
679 		/* mark this as a timeout */
680 		if( fd_available < 0 ){
681 			if( err != EINTR ){
682 				errno = err;
683 				logerr_die(LOG_ERR, _("lpd: select error!"));
684 				break;
685 			}
686 			continue;
687 		} else if( fd_available == 0 ){
688 			DEBUG1( "lpd: signal or time out, last_fork_pid_value %d", last_fork_pid_value );
689 			/* we try to fork now */
690 			if( last_fork_pid_value < 0 ) last_fork_pid_value = 1;
691 			continue;
692 		}
693 		if( sock > 0 && FD_ISSET( sock, &readfds ) ){
694 			DEBUG1("lpd: accept on LPD socket");
695 			Accept_connection( sock );
696 		}
697 		if( unix_sock > 0 && FD_ISSET( unix_sock, &readfds ) ){
698 			DEBUG1("lpd: accept on UNIX socket");
699 			Accept_connection( unix_sock );
700 		}
701 #ifdef IPP_STUBS
702 		if( ipp_sock > 0 && FD_ISSET( ipp_sock, &readfds ) ){
703 			DEBUG1("lpd: accept on IPP socket");
704 			Accept_connection( ipp_sock );
705 		}
706 #endif /* not IPP_STUBS */
707 		if( FD_ISSET( request_pipe[0], &readfds )
708 			&& Read_server_status( request_pipe[0] ) == 0 ){
709 			Errorcode = JABORT;
710 			logerr_die(LOG_ERR, _("lpd: Lpd_request pipe EOF! cannot happen") );
711 		}
712 		if( start_fd > 0 && FD_ISSET( start_fd, &readfds ) ){
713 			start_fd = Read_server_status( start_fd );
714 		}
715 	}while( 1 );
716 	Free_line_list(&args);
717 	cleanup(0);
718 }
719 
720 /***************************************************************************
721  * Setup_log( char *logfile, int sock )
722  * Purpose: to set up a standard error logging environment
723  * saveme will prevent STDIN from being clobbered
724  *   1.  dup 'sock' to fd 0, close sock
725  *   2.  opens /dev/null on fd 1
726  *   3.  If logfile is "-" or NULL, output file is alread opened
727  *   4.  Open logfile; if unable to, then open /dev/null for output
728  ***************************************************************************/
Setup_log(char * logfile)729 static void Setup_log(char *logfile )
730 {
731 	struct stat statb;
732 
733 	close(0); close(1);
734 	if (open("/dev/null", O_RDONLY, 0) != 0) {
735 	    logerr_die(LOG_ERR, _("Setup_log: open /dev/null failed"));
736 	}
737 	if (open("/dev/null", O_WRONLY, 0) != 1) {
738 	    logerr_die(LOG_ERR, _("Setup_log: open /dev/null failed"));
739 	}
740 
741     /*
742      * open logfile; if it is "-", use STDERR; if Foreground is set, use stderr
743      */
744 	if( fstat(2,&statb) == -1 && dup2(1,2) == -1 ){
745 		logerr_die(LOG_ERR, _("Setup_log: dup2(%d,%d) failed"), 1, 2);
746 	}
747     if( logfile == 0 ){
748 		if( !Foreground_LPD && dup2(1,2) == -1 ){
749 			logerr_die(LOG_ERR, _("Setup_log: dup2(%d,%d) failed"), 1, 2);
750 		}
751 	} else if( safestrcmp(logfile, "-") ){
752 		close(2);
753 		if( Checkwrite(logfile, &statb, O_WRONLY|O_APPEND, 0, 0) != 2) {
754 			logerr_die(LOG_ERR, _("Setup_log: open %s failed"), logfile );
755 		}
756 	}
757 }
758 
759 /***************************************************************************
760  * Reinit()
761  * Reinitialize the database/printcap/permissions information
762  * 1. free any allocated memory
763  ***************************************************************************/
764 
Reinit(void)765 static void Reinit(void)
766 {
767 	Reread_config = 1;
768 	(void) plp_signal (SIGHUP,  (plp_sigfunc_t)Reinit);
769 }
770 
771 
772 /***************************************************************************
773  * Get_lpd_pid() and Set_lpd_pid()
774  * Get and set the LPD pid into the LPD status file
775  ***************************************************************************/
776 
Get_lpd_pid(void)777 int Get_lpd_pid(void)
778 {
779 	pid_t pid;
780 	char *path;
781 
782 	path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ );
783 	pid = Read_pid_from_file( path );
784 	if( path ) free(path); path = 0;
785 	return(pid);
786 }
787 
Set_lpd_pid(int lockfd)788 static void Set_lpd_pid(int lockfd)
789 {
790 	/* we write our PID */
791 	if( ftruncate( lockfd, 0 ) ){
792 		logerr_die(LOG_ERR, _("lpd: Cannot truncate lock file") );
793 	}
794 	Server_pid = getpid();
795 	DEBUG1( "lpd: writing lockfile fd %d with pid '%ld'",lockfd, (long)Server_pid );
796 	Write_pid( lockfd, Server_pid, (char *)0 );
797 }
798 
Lock_lpd_pid(void)799 int Lock_lpd_pid(void)
800 {
801 	int lockfd;
802 	char *path;
803 	struct stat statb;
804 	int euid = geteuid();
805 
806 	path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ );
807 	To_euid_root();
808 	lockfd = Checkwrite( path, &statb, O_RDWR, 1, 0 );
809 	if( lockfd < 0 ){
810 		logerr_die(LOG_ERR, _("lpd: Cannot open lock file '%s'"), path );
811 	}
812 #if !defined(__CYGWIN__)
813 	fchown( lockfd, DaemonUID, DaemonGID );
814 	fchmod( lockfd, (statb.st_mode & ~0777) | 0644 );
815 #endif
816 	To_euid(euid);
817 	if( Do_lock( lockfd, 0 ) < 0 ){
818 		close( lockfd );
819 		lockfd = -1;
820 	}
821 	return(lockfd);
822 }
823 
Read_server_status(int fd)824 int Read_server_status( int fd )
825 {
826 	int status, count, found, n;
827 	char buffer[LINEBUFFER];
828 	char *name;
829 	fd_set readfds;	/* for select() */
830 	struct timeval timeval;
831 	struct line_list l;
832 
833 	buffer[0] = 0;
834 	errno = 0;
835 
836 	DEBUG1( "Read_server_status: starting" );
837 
838 	Init_line_list(&l);
839 	while(1){
840 		FD_ZERO( &readfds );
841 		FD_SET( fd, &readfds );
842 		memset(&timeval,0, sizeof(timeval));
843 		status = select( fd+1,
844 			&readfds, NULL, NULL, &timeval );
845 		DEBUG1( "Read_server_status: select status %d", status);
846 		if( status == 0 ){
847 			break;
848 		} else if( status < 0 ){
849 			close(fd);
850 			fd = 0;
851 			break;
852 		}
853 		status = ok_read(fd,buffer,sizeof(buffer)-1);
854 		DEBUG1( "Read_server_status: read status %d", status );
855 		if( status <= 0 ){
856 			close(fd);
857 			fd = -1;
858 			break;
859 		}
860 		buffer[status] = 0;
861 		DEBUG1( "Read_server_status: read status %d '%s'", status, buffer );
862 		/* we split up read line and record information */
863 		Split(&l,buffer,Whitespace,0,0,0,0,0,0);
864 		if(DEBUGL1)Dump_line_list("Read_server_status - input", &l );
865 		for( count = 0; count < l.count; ++count ){
866 			name = l.list[count];
867 			if( ISNULL(name) ) continue;
868 			found = 0;
869 			for( n = 0;!found && n < Servers_line_list.count; ++n ){
870 				found = !safestrcasecmp( Servers_line_list.list[n], name);
871 			}
872 			if( !found ){
873 				Add_line_list(&Servers_line_list,name,0,0,0);
874 			}
875 			Started_server = 1;
876 		}
877 		Free_line_list(&l);
878 	}
879 	Free_line_list(&l);
880 
881 #ifdef DMALLOC
882 	{
883 		char *s = sbrk(0);
884 		int n = s - malloc_area;
885 		DEBUG1("lpd: READ_SERVER_STATUS - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count );
886 		if( n > 1024 ){
887 			extern int dmalloc_outfile_fd;
888 			char buffer[128];
889 			plp_snprintf(buffer,sizeof(buffer), "lpd: READ_SERVER_STATSUS sbrk reports 0x%lx, or %d more memory\n", (long)s, n );
890 			Write_fd_str(dmalloc_outfile_fd, buffer );
891 			dmalloc_log_unfreed();
892 			DEBUG1( "lpd: READ_SERVER_STATUS sbrk reports 0x%lx, or %d more memory", (long)s, n );
893 			malloc_area += n;
894 		}
895 	}
896 #endif
897 
898 	if(DEBUGL2)Dump_line_list("Read_server_status - waiting for start",
899 			&Servers_line_list );
900 	return(fd);
901 }
902 
903 /***************************************************************************
904  * void Get_parms(int argc, char *argv[])
905  * 1. Scan the argument list and get the flags
906  * 2. Check for duplicate information
907  ***************************************************************************/
908 
usage(void)909 static void usage(void)
910 {
911 	FPRINTF( STDERR,
912 _("usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP destination port]\n"
913 " Options\n"
914 " -D dbg      - set debug level and flags\n"
915 " -F          - run in foreground, log to STDERR\n"
916 " -L logfile  - append log information to logfile\n"
917 " -V          - show version info\n"
918 " -p port     - TCP/IP listen port, 'off' disables TCP/IP listening port (lpd_listen_port)\n"
919 " -P path     - UNIX socket path, 'off' disables UNIX listening socket (unix_socket_path)\n"
920 " -R port     - remote LPD server port (lpd_port)\n"), Name );
921 	{
922 	char buffer[128];
923 	FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) );
924 	}
925 	Parse_debug("=",-1);
926 	FPRINTF( STDERR, "%s\n", Version );
927 	exit(1);
928 }
929 
930 static const char LPD_optstr[] 	/* LPD options */
931  = "D:FL:VX:p:P:" ;
932 
Get_parms(int argc,char * argv[])933 static void Get_parms(int argc, char *argv[] )
934 {
935 	int option, verbose = 0;
936 
937 	while ((option = Getopt (argc, argv, LPD_optstr )) != EOF){
938 		switch (option) {
939 		case 'D': Parse_debug(Optarg, 1); break;
940 		case 'F': Foreground_LPD = 1; break;
941 		case 'L': Logfile_LPD = Optarg; break;
942 		case 'V': ++verbose; break;
943         case 'X': Worker_LPD = Optarg; break;
944 		case 'p': Lpd_listen_port_arg = Optarg; break;
945 		case 'P': Lpd_socket_arg = Optarg; break;
946 		default: usage(); break;
947 		}
948 	}
949 	if( Optind != argc ){
950 		usage();
951 	}
952 	if( verbose ) {
953 		FPRINTF( STDERR, "%s\n", Version );
954 		if( verbose > 1 ) Printlist( Copyright, 1 );
955 		exit(0);
956 	}
957 }
958 
959 
960 /*
961  * Accept_connection
962  *   - accept the connection and fork the child to handle it
963  */
Accept_connection(int sock)964 static void Accept_connection( int sock )
965 {
966 	struct line_list args;
967 	struct sockaddr sinaddr;
968 	int newsock, err;
969 	pid_t pid;
970 	socklen_t len;
971 	Init_line_list(&args);
972 	len = sizeof( sinaddr );
973 	newsock = accept( sock, &sinaddr, &len );
974 	err = errno;
975 	DEBUG1("Accept_connection: connection fd %d", newsock );
976 	if( newsock > 0 ){
977 #if defined(TCPWRAPPERS)
978 /*
979 * libwrap/tcp_wrappers:
980 * draht@suse.de, Mon Jan 28 2002
981 */
982 			struct request_info wrap_req;
983 
984 			request_init(&wrap_req, RQ_DAEMON, "lpd" , RQ_FILE, newsock, NULL);
985 			fromhost(&wrap_req);
986 			openlog("lpd", LOG_PID, LOG_LPR); /* we syslog(3) initialized, no closelog(). */
987 			if (hosts_access(&wrap_req)) {
988 				/* We accept. */
989 				syslog(LOG_INFO, "connection from %s", eval_client(&wrap_req));
990 			} else {
991 				syslog(LOG_WARNING, "connection refused from %s", eval_client(&wrap_req));
992 				close( newsock );
993 				return;
994 			}
995 #endif
996 
997 		pid = Start_worker( "server", Service_connection, &args, newsock );
998 		if( pid < 0 ){
999 			logerr(LOG_INFO, _("lpd: fork() failed") );
1000 			/* this was written with an impossible condition, why?
1001 			    safefprintf(newsock, "\002%s\n", _("Server load too high"));
1002 			 */
1003 		} else {
1004 			DEBUG1( "lpd: listener pid %ld running", (long)pid );
1005 		}
1006 		close( newsock );
1007 		Free_line_list(&args);
1008 	} else {
1009 		errno = err;
1010 		logerr(LOG_INFO, _("lpd: accept on listening socket failed") );
1011 	}
1012 }
1013 
1014 /*
1015  * int Start_all( int first_scan, int *start_fd )
1016  * returns the pid of the process doing the scanning
1017  */
1018 
Start_all(int first_scan,int * start_fd)1019 static pid_t Start_all( int first_scan, int *start_fd )
1020 {
1021 	struct line_list args;
1022 	int p[2];
1023 	pid_t pid;
1024 
1025 	Init_line_list(&args);
1026 
1027 	DEBUG1( "Start_all: first_scan %d", first_scan );
1028 	if( pipe(p) == -1 ){
1029 		logerr_die(LOG_INFO, _("Start_all: pipe failed!") );
1030 	}
1031 	Max_open(p[0]); Max_open(p[1]);
1032 	DEBUG1( "Start_all: fd pipe(%d,%d)",p[0],p[1]);
1033 
1034 	Set_str_value(&args,CALL,"all");
1035 	Set_decimal_value(&args,FIRST_SCAN,first_scan);
1036 
1037 	pid = Start_worker( "all", Service_all, &args, p[1]);
1038 	close(p[1]);
1039 	if( pid < 0 ){
1040 		close( p[0] );
1041 		p[0] = -1;
1042 	}
1043 	DEBUG1("Start_all: pid %ld, fd %d", (long)pid, p[0] );
1044 	if( start_fd ) *start_fd = p[0];
1045 	return(pid);
1046 }
1047 
sigchld_handler(int signo UNUSED)1048 plp_signal_t sigchld_handler (int signo UNUSED)
1049 {
1050 	signal( SIGCHLD, SIG_DFL );
1051 	write(Lpd_request,"\n", 1);
1052 }
1053 
Setup_waitpid(void)1054 static void Setup_waitpid (void)
1055 {
1056 	signal( SIGCHLD, SIG_DFL );
1057 }
1058 
Setup_waitpid_break(void)1059 static void Setup_waitpid_break (void)
1060 {
1061 	(void) plp_signal_break(SIGCHLD, sigchld_handler);
1062 }
1063 
Fork_error(pid_t last_fork_pid_value)1064 static void Fork_error( pid_t last_fork_pid_value )
1065 {
1066 	DEBUG1("Fork_error: %ld", (long)last_fork_pid_value );
1067 	if( last_fork_pid_value < 0 ){
1068 		logmsg(LOG_CRIT, "LPD: fork failed! LPD not accepting any requests");
1069 	}
1070 }
1071