xref: /illumos-gate/usr/src/cmd/listen/nlps_serv.c (revision 2a8bcb4e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate /*
24113f4232Sakaplan  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25113f4232Sakaplan  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
28113f4232Sakaplan /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
29113f4232Sakaplan /*	  All Rights Reserved  	*/
30113f4232Sakaplan 
317c478bd9Sstevel@tonic-gate /* system include files	*/
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <fcntl.h>
347c478bd9Sstevel@tonic-gate #include <signal.h>
357c478bd9Sstevel@tonic-gate #include <stdio.h>
367c478bd9Sstevel@tonic-gate #include <unistd.h>
377c478bd9Sstevel@tonic-gate #include <string.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
397c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
407c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
417c478bd9Sstevel@tonic-gate #include <sys/param.h>
427c478bd9Sstevel@tonic-gate #include <sys/types.h>
437c478bd9Sstevel@tonic-gate #include <sys/stat.h>
447c478bd9Sstevel@tonic-gate #include <sys/mkdev.h>
457c478bd9Sstevel@tonic-gate #include <values.h>
467c478bd9Sstevel@tonic-gate #include <ctype.h>
477c478bd9Sstevel@tonic-gate #include <pwd.h>
487c478bd9Sstevel@tonic-gate #include <grp.h>
497c478bd9Sstevel@tonic-gate #include <sys/poll.h>
507c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
517c478bd9Sstevel@tonic-gate #include <utmpx.h>
527c478bd9Sstevel@tonic-gate #include <sac.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /* listener include files */
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate #include "lsparam.h"		/* listener parameters		*/
587c478bd9Sstevel@tonic-gate #include "lsfiles.h"		/* listener files info		*/
597c478bd9Sstevel@tonic-gate #include "lserror.h"		/* listener error codes		*/
607c478bd9Sstevel@tonic-gate #include "lsnlsmsg.h"		/* NLPS listener protocol	*/
617c478bd9Sstevel@tonic-gate #include "lssmbmsg.h"		/* MS_NET identifier		*/
627c478bd9Sstevel@tonic-gate #include "lsdbf.h"		/* data base file stuff		*/
637c478bd9Sstevel@tonic-gate #include "listen.h"
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate /* global variables */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate FILE *Logfp;		/* file pointer for nlps_server's log file	*/
687c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
697c478bd9Sstevel@tonic-gate FILE *Debugfp;		/* debugging output				*/
707c478bd9Sstevel@tonic-gate #endif
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate int Dbf_entries;	/* number of private addresses in dbf file */
737c478bd9Sstevel@tonic-gate dbf_t	*Dbfhead;
747c478bd9Sstevel@tonic-gate dbf_t	*Newdbf;
757c478bd9Sstevel@tonic-gate char	*New_cmd_lines;
767c478bd9Sstevel@tonic-gate char	*Server_cmd_lines;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate extern int t_errno;
797c478bd9Sstevel@tonic-gate 
80*2a8bcb4eSToomas Soome /*
817c478bd9Sstevel@tonic-gate  * These global symbols are used for logging.
827c478bd9Sstevel@tonic-gate  * Pid, NLPS_proc, and Lastmsg are significant here; the others aren't used.
837c478bd9Sstevel@tonic-gate  */
847c478bd9Sstevel@tonic-gate int	NLPS_proc = 1;
857c478bd9Sstevel@tonic-gate pid_t	Pid;
867c478bd9Sstevel@tonic-gate char	Lastmsg[BUFSIZ];
877c478bd9Sstevel@tonic-gate char	*Netspec = NULL;
887c478bd9Sstevel@tonic-gate int	Splflag = 0;
897c478bd9Sstevel@tonic-gate int	Logmax = 0;
907c478bd9Sstevel@tonic-gate char	*Mytag = NULL;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate char	msgbuf[BUFSIZ];
937c478bd9Sstevel@tonic-gate char	Altbasedir[BUFSIZ];
947c478bd9Sstevel@tonic-gate char	Basedir[BUFSIZ];
957c478bd9Sstevel@tonic-gate extern	char *getenv();
967c478bd9Sstevel@tonic-gate 
97113f4232Sakaplan static void nls_reply(int code, char *text);
98113f4232Sakaplan static void nullfix(void);
99113f4232Sakaplan 
100113f4232Sakaplan int
main(int argc,char ** argv)101113f4232Sakaplan main(int argc, char **argv)
1027c478bd9Sstevel@tonic-gate {
1037c478bd9Sstevel@tonic-gate 	extern int read_dbf();
1047c478bd9Sstevel@tonic-gate 	char *provider;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	provider = getenv("PMTAG");
1077c478bd9Sstevel@tonic-gate 	sprintf(Altbasedir, "%s/%s/", ALTDIR, provider);
1087c478bd9Sstevel@tonic-gate 	sprintf(Basedir, "%s/%s/", BASEDIR, provider);
1097c478bd9Sstevel@tonic-gate 	sprintf(msgbuf, "%s/%s", Altbasedir, LOGNAME);
1107c478bd9Sstevel@tonic-gate 	if (!(Logfp = fopen(msgbuf, "a+")))  {
111*2a8bcb4eSToomas Soome 		(void)exit(1);
1127c478bd9Sstevel@tonic-gate 	}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
1157c478bd9Sstevel@tonic-gate 	sprintf(msgbuf, "%s/%s", Altbasedir, PDEBUGNAME);
1167c478bd9Sstevel@tonic-gate 	if (!(Debugfp = fopen(msgbuf, "a")))  {
1177c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Unable to open DEBUG file");
118*2a8bcb4eSToomas Soome 		(void)exit(1);
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate #endif
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	/*
1237c478bd9Sstevel@tonic-gate 	 * re-sync TLI structures after we were exec'ed from listener
1247c478bd9Sstevel@tonic-gate 	 */
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	if (t_sync(0) == -1) {
1277c478bd9Sstevel@tonic-gate 		DEBUG((9,"t_sync failed, t_errno %d", t_errno));
1287c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Resynchronization of TLI failed");
1297c478bd9Sstevel@tonic-gate 		(void)exit(1);
1307c478bd9Sstevel@tonic-gate 	}
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	nlps_server();
1337c478bd9Sstevel@tonic-gate 	return(0);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate /*
137*2a8bcb4eSToomas Soome  *  nlps_server:
1387c478bd9Sstevel@tonic-gate  */
1397c478bd9Sstevel@tonic-gate 
140113f4232Sakaplan int
nlps_server()1417c478bd9Sstevel@tonic-gate nlps_server()
1427c478bd9Sstevel@tonic-gate {
143113f4232Sakaplan 	int size;
1447c478bd9Sstevel@tonic-gate 	char buf[RCVBUFSZ];
1457c478bd9Sstevel@tonic-gate 	char **argv;
146113f4232Sakaplan 	char *bp = buf;
147113f4232Sakaplan 	dbf_t *dbp;
1487c478bd9Sstevel@tonic-gate 	dbf_t *getdbfentry();
1497c478bd9Sstevel@tonic-gate 	extern char **mkdbfargv();
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	Pid = getpid();
1527c478bd9Sstevel@tonic-gate 	DEBUG((9,"in nlps_server (NLPS/SMB message), pid %ld", Pid));
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	if ((size = getrequest(bp)) <= 0)  {
1557c478bd9Sstevel@tonic-gate 		logmessage("NLPS: No/bad service request received");
1567c478bd9Sstevel@tonic-gate 		return(-1);
1577c478bd9Sstevel@tonic-gate 	}
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	if (size < 0)  {
1607c478bd9Sstevel@tonic-gate 		DEBUG((7,"nlps_server(): Error returned from getrequest()" ));
1617c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Error returned from getrequest()");
1627c478bd9Sstevel@tonic-gate 		return(-1);
1637c478bd9Sstevel@tonic-gate 	}
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	/*
1667c478bd9Sstevel@tonic-gate 	 * if message is NLPS protocol...
1677c478bd9Sstevel@tonic-gate 	 */
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if ((!strncmp(bp,NLPSIDSTR,NLPSIDSZ))  && 	/* NLPS request	*/
1707c478bd9Sstevel@tonic-gate 	    (*(bp + NLPSIDSZ) == NLPSSEPCHAR)) {
1717c478bd9Sstevel@tonic-gate 		nls_service(bp, size);
172*2a8bcb4eSToomas Soome 		(void)sleep(10);	/* if returned to here, then
1737c478bd9Sstevel@tonic-gate 				 * must sleep for a short period of time to
1747c478bd9Sstevel@tonic-gate 				 * insure that the client received any possible
1757c478bd9Sstevel@tonic-gate 				 * exit response message from the listener.
1767c478bd9Sstevel@tonic-gate 					 */
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	/*
1797c478bd9Sstevel@tonic-gate 	 * else if message is for the MS-NET file server...
1807c478bd9Sstevel@tonic-gate 	 */
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	} else if ( (*bp == (char)0xff) && (!strncmp(bp+1,SMBIDSTR,SMBIDSZ)) )  {
1837c478bd9Sstevel@tonic-gate 		if (dbp = getdbfentry(DBF_SMB_CODE))
1847c478bd9Sstevel@tonic-gate 		    if (dbp->dbf_flags & DBF_OFF)
1857c478bd9Sstevel@tonic-gate 			logmessage("NLPS: SMB message, server disabled in data base");
1867c478bd9Sstevel@tonic-gate 		    else    {
1877c478bd9Sstevel@tonic-gate 			argv = mkdbfargv(dbp);
1887c478bd9Sstevel@tonic-gate 			smbservice(bp, size, argv);
1897c478bd9Sstevel@tonic-gate 		    }
1907c478bd9Sstevel@tonic-gate 		else
1917c478bd9Sstevel@tonic-gate 			logmessage("NLPS: SMB message, no data base entry");
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 	/*
1947c478bd9Sstevel@tonic-gate 	 * else, message type is unknown...
1957c478bd9Sstevel@tonic-gate 	 */
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	} else  {
1987c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Unknown service request (ignored)");
1997c478bd9Sstevel@tonic-gate 		DEBUG((7,"msg size: %d; 1st four chars (hex) %x %x %x %x",
2007c478bd9Sstevel@tonic-gate 			*bp, *(bp+1), *(bp+2), *(bp+3)));
2017c478bd9Sstevel@tonic-gate 	}
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	/*
2047c478bd9Sstevel@tonic-gate 	 * the routines that start servers return only if there was an error
2057c478bd9Sstevel@tonic-gate 	 * and will have logged their own errors.
2067c478bd9Sstevel@tonic-gate 	 */
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	return(-1);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate  * getrequest:	read in a full message.  Timeout, in case the client died.
2147c478bd9Sstevel@tonic-gate  *		returns: -1 = timeout or other error.
2157c478bd9Sstevel@tonic-gate  *			 positive number = message size.
2167c478bd9Sstevel@tonic-gate  */
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate int
getrequest(bp)2197c478bd9Sstevel@tonic-gate getrequest(bp)
220113f4232Sakaplan char *bp;
2217c478bd9Sstevel@tonic-gate {
222113f4232Sakaplan 	int size;
223113f4232Sakaplan 	char *tmp = bp;
2247c478bd9Sstevel@tonic-gate 	int flags;
2257c478bd9Sstevel@tonic-gate 	extern void timeout();
2267c478bd9Sstevel@tonic-gate 	short cnt;
2277c478bd9Sstevel@tonic-gate 	void (*oldhanp)();
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	DEBUG((9,"in getrequest"));
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	oldhanp = signal(SIGALRM, timeout);
2327c478bd9Sstevel@tonic-gate 	(void)alarm(ALARMTIME);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	/* read in MINMSGSZ to determine type of msg */
2357c478bd9Sstevel@tonic-gate 	if ((size = l_rcv(bp, MINMSGSZ, &flags)) != MINMSGSZ) {
2367c478bd9Sstevel@tonic-gate 		DEBUG((9, "getrequest: l_rcv returned %d", size));
2377c478bd9Sstevel@tonic-gate 		tli_error(E_RCV_MSG, CONTINUE);
2387c478bd9Sstevel@tonic-gate 		return(-1);
2397c478bd9Sstevel@tonic-gate 	}
2407c478bd9Sstevel@tonic-gate 	tmp += size;
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	/*
2437c478bd9Sstevel@tonic-gate 	 * if message is NLPS protocol...
2447c478bd9Sstevel@tonic-gate 	 */
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	if ((!strncmp(bp,NLPSIDSTR,NLPSIDSZ))  && 	/* NLPS request	*/
2477c478bd9Sstevel@tonic-gate 	    (*(bp + NLPSIDSZ) == NLPSSEPCHAR)) {
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 		do {
2507c478bd9Sstevel@tonic-gate 			if (++size > RCVBUFSZ) {
2517c478bd9Sstevel@tonic-gate 				logmessage("NLPS: recieve buffer not large enough");
2527c478bd9Sstevel@tonic-gate 				return(-1);
2537c478bd9Sstevel@tonic-gate 			}
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 			if (t_rcv(0, tmp, sizeof(char), &flags) != sizeof(char)) {
2567c478bd9Sstevel@tonic-gate 				tli_error(E_RCV_MSG, CONTINUE);
2577c478bd9Sstevel@tonic-gate 				return(-1);
2587c478bd9Sstevel@tonic-gate 			}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		} while (*tmp++ != '\0');
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	/*
2657c478bd9Sstevel@tonic-gate 	 * else if message is for the MS-NET file server...
2667c478bd9Sstevel@tonic-gate 	 */
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	} else if ( (*bp == (char)0xff) && (!strncmp(bp+1,SMBIDSTR,SMBIDSZ)) )  {
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 		/* read in 28 more bytes to get count of paramter words */
2717c478bd9Sstevel@tonic-gate 		if (l_rcv(tmp, 28, &flags) != 28) {
2727c478bd9Sstevel@tonic-gate 			tli_error(E_RCV_MSG, CONTINUE);
2737c478bd9Sstevel@tonic-gate 			return(-1);
2747c478bd9Sstevel@tonic-gate 		}
2757c478bd9Sstevel@tonic-gate 		tmp += 28;
2767c478bd9Sstevel@tonic-gate 		size += 28;
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 		/*
2797c478bd9Sstevel@tonic-gate 		 * read amount of paramater words plus word for
2807c478bd9Sstevel@tonic-gate                  * the number of data bytes to follow (2 bytes/word)
2817c478bd9Sstevel@tonic-gate                  */
2827c478bd9Sstevel@tonic-gate 		cnt = (int)*(tmp - 1) * 2 + 2;
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate 		if ((size += cnt) > RCVBUFSZ) {
2857c478bd9Sstevel@tonic-gate 			logmessage("NLPS: recieve buffer not large enough");
2867c478bd9Sstevel@tonic-gate 			return(-1);
2877c478bd9Sstevel@tonic-gate 		}
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 		if (l_rcv(tmp, cnt, &flags) != cnt) {
2907c478bd9Sstevel@tonic-gate 			tli_error(E_RCV_MSG, CONTINUE);
2917c478bd9Sstevel@tonic-gate 			return(-1);
2927c478bd9Sstevel@tonic-gate 		}
2937c478bd9Sstevel@tonic-gate 		tmp += cnt;
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 		getword(tmp - 2, &cnt);
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 		if ((size += cnt) > RCVBUFSZ) {
2987c478bd9Sstevel@tonic-gate 			logmessage("NLPS: recieve buffer not large enough");
2997c478bd9Sstevel@tonic-gate 			return(-1);
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		if (l_rcv(tmp, cnt, &flags) != cnt) {
3037c478bd9Sstevel@tonic-gate 			tli_error(E_RCV_MSG, CONTINUE);
3047c478bd9Sstevel@tonic-gate 			return(-1);
3057c478bd9Sstevel@tonic-gate 		}
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 		nullfix();
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	/*
3107c478bd9Sstevel@tonic-gate 	 * else, message type is unknown...
3117c478bd9Sstevel@tonic-gate 	 */
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	} else  {
3147c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Unknown service request (ignored)");
3157c478bd9Sstevel@tonic-gate 		DEBUG((7,"msg size: %d; 1st four chars (hex) %x %x %x %x",
3167c478bd9Sstevel@tonic-gate 			*bp, *(bp+1), *(bp+2), *(bp+3)));
3177c478bd9Sstevel@tonic-gate 		return(-1);
3187c478bd9Sstevel@tonic-gate 	}
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	(void)alarm(0);
3217c478bd9Sstevel@tonic-gate 	signal(SIGALRM, oldhanp);
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	DEBUG((7,"t_rcv returned %d, flags: %x",size,flags));
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	return(size);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate /*
3307c478bd9Sstevel@tonic-gate  * The following code is for patching a 6300 side bug.  The original
3317c478bd9Sstevel@tonic-gate  * message that comes over may contain 2 null bytes which aren't
3327c478bd9Sstevel@tonic-gate  * part of the message, and if left on the stream, will poison the
3337c478bd9Sstevel@tonic-gate  * server.  Peek into the stream and snarf up those bytes if they
3347c478bd9Sstevel@tonic-gate  * are there.  If anything goes wrong with the I_PEEK, just continue,
3357c478bd9Sstevel@tonic-gate  * if the nulls weren't there, it'll work, and if they were, all that
3367c478bd9Sstevel@tonic-gate  * will happen is that the server will fail.  Just note what happened
3377c478bd9Sstevel@tonic-gate  * in the log file.
3387c478bd9Sstevel@tonic-gate  */
3397c478bd9Sstevel@tonic-gate 
340113f4232Sakaplan static void
nullfix(void)341113f4232Sakaplan nullfix(void)
3427c478bd9Sstevel@tonic-gate {
3437c478bd9Sstevel@tonic-gate 	struct strpeek peek;
3447c478bd9Sstevel@tonic-gate 	register struct strpeek *peekp;
3457c478bd9Sstevel@tonic-gate 	char scratch[BUFSIZ];
3467c478bd9Sstevel@tonic-gate 	char junk[2];
3477c478bd9Sstevel@tonic-gate 	int flags;
3487c478bd9Sstevel@tonic-gate 	int ret;
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 	peekp = &peek;
3517c478bd9Sstevel@tonic-gate 	peekp->flags = 0;
3527c478bd9Sstevel@tonic-gate 	/* need to ask for ctl info to avoid bug in I_PEEK code */
3537c478bd9Sstevel@tonic-gate 	peekp->ctlbuf.maxlen = 1;
3547c478bd9Sstevel@tonic-gate 	peekp->ctlbuf.buf = junk;
3557c478bd9Sstevel@tonic-gate 	peekp->databuf.maxlen = 2;
3567c478bd9Sstevel@tonic-gate 	peekp->databuf.buf = junk;
3577c478bd9Sstevel@tonic-gate 	ret = ioctl(0, I_PEEK, &peek);
3587c478bd9Sstevel@tonic-gate 	if (ret == -1) {
3597c478bd9Sstevel@tonic-gate 		sprintf(scratch, "NLPS: nullfix(): unable to PEEK, errno is %d", errno);
3607c478bd9Sstevel@tonic-gate 		DEBUG((9, "nullfix(): I_PEEK failed, errno is %d", errno));
3617c478bd9Sstevel@tonic-gate 		logmessage(scratch);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 	else if (ret == 0) {
3647c478bd9Sstevel@tonic-gate 		DEBUG((9, "nullfix(): no messages on stream to PEEK"));
3657c478bd9Sstevel@tonic-gate 	}
3667c478bd9Sstevel@tonic-gate 	else {
3677c478bd9Sstevel@tonic-gate 		if (peekp->databuf.len == 2) {
3687c478bd9Sstevel@tonic-gate 			/* Note: junk contains "peeked" data */
3697c478bd9Sstevel@tonic-gate 			DEBUG((9, "peeked <%x> <%x>", junk[0], junk[1]));
3707c478bd9Sstevel@tonic-gate 			if ((junk[0] == 0) && (junk[1] == 0)) {
3717c478bd9Sstevel@tonic-gate 				/* pitch the nulls */
3727c478bd9Sstevel@tonic-gate 				DEBUG((9, "pitching 2 nulls from first peek"));
3737c478bd9Sstevel@tonic-gate 				l_rcv(junk, 2, &flags);
3747c478bd9Sstevel@tonic-gate 			}
3757c478bd9Sstevel@tonic-gate 		}
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 		/*
3787c478bd9Sstevel@tonic-gate 		 * this represents a somewhat pathological case where
3797c478bd9Sstevel@tonic-gate 		 * the "2 nulls" are broken across message boundaries.
3807c478bd9Sstevel@tonic-gate 		 * Pitch the first and hope the next one is there
3817c478bd9Sstevel@tonic-gate 		 */
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 		else if (peekp->databuf.len == 1) {
3847c478bd9Sstevel@tonic-gate 			DEBUG((9, "peeked <%x>", junk[0]));
3857c478bd9Sstevel@tonic-gate 			if (junk[0] == 0) {
3867c478bd9Sstevel@tonic-gate 				/* pitch the first */
3877c478bd9Sstevel@tonic-gate 				DEBUG((9, "split nulls, pitching first"));
3887c478bd9Sstevel@tonic-gate 				l_rcv(junk, 1, &flags);
3897c478bd9Sstevel@tonic-gate 				peekp->databuf.maxlen = 1;
3907c478bd9Sstevel@tonic-gate 				ret = ioctl(0, I_PEEK, &peek);
3917c478bd9Sstevel@tonic-gate 				if (ret == -1) {
3927c478bd9Sstevel@tonic-gate 					sprintf(scratch, "NLPS: nullfix(): unable to PEEK second time, errno is %d", errno);
3937c478bd9Sstevel@tonic-gate 					DEBUG((9, "second peek failed, errno %d", errno));
3947c478bd9Sstevel@tonic-gate 					logmessage(scratch);
3957c478bd9Sstevel@tonic-gate 				}
3967c478bd9Sstevel@tonic-gate 				else if (ret == 0) {
3977c478bd9Sstevel@tonic-gate 					DEBUG((9, "no messages for 2nd peek"));
3987c478bd9Sstevel@tonic-gate 				}
3997c478bd9Sstevel@tonic-gate 				else {
4007c478bd9Sstevel@tonic-gate 					if (peekp->databuf.len == 1) {
4017c478bd9Sstevel@tonic-gate 						DEBUG((9, "2nd peek <%x>", junk[0]));
4027c478bd9Sstevel@tonic-gate 						if (junk[0] == 0) {
4037c478bd9Sstevel@tonic-gate 							/* pitch the second */
4047c478bd9Sstevel@tonic-gate 							DEBUG((9, "pitching 2nd single null"));
4057c478bd9Sstevel@tonic-gate 							l_rcv(junk, 1, &flags);
4067c478bd9Sstevel@tonic-gate 						}
4077c478bd9Sstevel@tonic-gate 						else {
4087c478bd9Sstevel@tonic-gate 							/* uh oh, server will most likely fail */
4097c478bd9Sstevel@tonic-gate 							DEBUG((9, "2nd null not found"));
4107c478bd9Sstevel@tonic-gate 							logmessage("NLPS: nullfix(): threw away a valid null byte");
4117c478bd9Sstevel@tonic-gate 						}
4127c478bd9Sstevel@tonic-gate 					}
4137c478bd9Sstevel@tonic-gate 				}
4147c478bd9Sstevel@tonic-gate 			}
4157c478bd9Sstevel@tonic-gate 		}
4167c478bd9Sstevel@tonic-gate 	}
4177c478bd9Sstevel@tonic-gate }
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate /*
4217c478bd9Sstevel@tonic-gate  * timeout:	SIGALRM signal handler.  Invoked if t_rcv timed out.
4227c478bd9Sstevel@tonic-gate  *		See comments about 'exit' in nlps_server().
4237c478bd9Sstevel@tonic-gate  */
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate void
timeout()4277c478bd9Sstevel@tonic-gate timeout()
4287c478bd9Sstevel@tonic-gate {
4297c478bd9Sstevel@tonic-gate 	DEBUG((9, "TIMEOUT"));
4307c478bd9Sstevel@tonic-gate 	error(E_RCV_TMO, EXIT | NOCORE);
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate /*
4367c478bd9Sstevel@tonic-gate  * nls_service:	Validate and start a server requested via the NLPS protocol
4377c478bd9Sstevel@tonic-gate  *
4387c478bd9Sstevel@tonic-gate  *		version 0:1 -- expect "NLPS:000:001:service_code".
4397c478bd9Sstevel@tonic-gate  *
4407c478bd9Sstevel@tonic-gate  *	returns only if there was an error (either msg format, or couldn't exec)
4417c478bd9Sstevel@tonic-gate  */
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate static char *badversion =
4447c478bd9Sstevel@tonic-gate 	"NLPS: Unknown version of an NLPS service request: %d:%d";
4457c478bd9Sstevel@tonic-gate static char *disabledmsg =
4467c478bd9Sstevel@tonic-gate 	"NLPS: Request for service code <%s> denied, service is disabled";
4477c478bd9Sstevel@tonic-gate static char *nlsunknown =
4487c478bd9Sstevel@tonic-gate 	"NLPS: Request for service code <%s> denied, unknown service code";
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate /*
4527c478bd9Sstevel@tonic-gate  * Nlsversion can be used as a NLPS flag (< 0 == not nls service)
4537c478bd9Sstevel@tonic-gate  * and when >= 0, indicates the version of the NLPS protocol used
4547c478bd9Sstevel@tonic-gate  */
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate static int Nlsversion = -1;	/* protocol version	*/
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate int
nls_service(bp,size)4597c478bd9Sstevel@tonic-gate nls_service(bp, size)
4607c478bd9Sstevel@tonic-gate int  size;
4617c478bd9Sstevel@tonic-gate char *bp;
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate 	int low, high;
4647c478bd9Sstevel@tonic-gate 	char svc_buf[64];
4657c478bd9Sstevel@tonic-gate 	register char *svc_code_p = svc_buf;
4667c478bd9Sstevel@tonic-gate 	char scratch[256];
4677c478bd9Sstevel@tonic-gate 	register dbf_t *dbp;
4687c478bd9Sstevel@tonic-gate 	dbf_t *getdbfentry();
4697c478bd9Sstevel@tonic-gate 	extern char **mkdbfargv();
4707c478bd9Sstevel@tonic-gate 	int passfd;
4717c478bd9Sstevel@tonic-gate 	int i;
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate 	if (nls_chkmsg(bp, size, &low, &high, svc_code_p))  {
4747c478bd9Sstevel@tonic-gate 		if ((low == 0) || (low == 2))
4757c478bd9Sstevel@tonic-gate 			Nlsversion = low;
4767c478bd9Sstevel@tonic-gate 		else  {
4777c478bd9Sstevel@tonic-gate 			sprintf(scratch, badversion, low, high);
4787c478bd9Sstevel@tonic-gate 			logmessage(scratch);
4797c478bd9Sstevel@tonic-gate 			error(E_BAD_VERSION, CONTINUE);
4807c478bd9Sstevel@tonic-gate 			return(-1);
4817c478bd9Sstevel@tonic-gate 		}
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 		DEBUG((9,"nls_service: protocol version %d", Nlsversion));
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 		/*
4867c478bd9Sstevel@tonic-gate 		 * common code for protocol version 0 or 2
4877c478bd9Sstevel@tonic-gate 		 * version 0 allows no answerback message
4887c478bd9Sstevel@tonic-gate 		 * version 2 allows exactly 1 answerback message
4897c478bd9Sstevel@tonic-gate 		 */
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 		if (dbp = getdbfentry(svc_code_p)) {
4927c478bd9Sstevel@tonic-gate 			if (dbp->dbf_flags & DBF_OFF)  {
4937c478bd9Sstevel@tonic-gate 				sprintf(scratch, disabledmsg, svc_code_p);
4947c478bd9Sstevel@tonic-gate 				logmessage(scratch);
4957c478bd9Sstevel@tonic-gate 				nls_reply(NLSDISABLED, scratch);
496*2a8bcb4eSToomas Soome 			}
4977c478bd9Sstevel@tonic-gate 			else {
4987c478bd9Sstevel@tonic-gate 				if (dbp->dbf_sflags & CFLAG) {
4997c478bd9Sstevel@tonic-gate 					exec_cmd(dbp, (char **)0);
5007c478bd9Sstevel@tonic-gate 					/* return is an error	*/
5017c478bd9Sstevel@tonic-gate 				}
5027c478bd9Sstevel@tonic-gate 				else {
503*2a8bcb4eSToomas Soome 					sprintf(msgbuf,"NLPS (%s) passfd: %s",
504*2a8bcb4eSToomas Soome 						dbp->dbf_svc_code,
5057c478bd9Sstevel@tonic-gate 						dbp->dbf_cmd_line);
5067c478bd9Sstevel@tonic-gate 					nls_reply(NLSSTART, msgbuf);
5077c478bd9Sstevel@tonic-gate 					logmessage(msgbuf);
5087c478bd9Sstevel@tonic-gate 					/* open pipe to pass fd through */
509*2a8bcb4eSToomas Soome 					if ((passfd = open(dbp->dbf_cmd_line,
5107c478bd9Sstevel@tonic-gate 							O_WRONLY)) < 0) {
5117c478bd9Sstevel@tonic-gate 						sprintf(scratch,"NLPS open failed: %s", dbp->dbf_cmd_line);
5127c478bd9Sstevel@tonic-gate 						logmessage(scratch);
5137c478bd9Sstevel@tonic-gate 					}
5147c478bd9Sstevel@tonic-gate 					DEBUG((9, "pushmod string: %s", dbp->dbf_modules));
5157c478bd9Sstevel@tonic-gate 					if (pushmod(0, dbp->dbf_modules)) {
5167c478bd9Sstevel@tonic-gate 						logmessage("NLPS: Can't push server's modules: exit");
5177c478bd9Sstevel@tonic-gate 						(void)exit(2); /* server, don't log */
5187c478bd9Sstevel@tonic-gate 					}
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 					DEBUG((9, "Running doconfig on %s", dbp->dbf_svc_code));
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 					sprintf(msgbuf,"%s/%s",Basedir,dbp->dbf_svc_code);
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 					if ((i = doconfig(0, msgbuf, NOASSIGN)) != 0) {
5257c478bd9Sstevel@tonic-gate 						DEBUG((9, "doconfig exited with code %d", i));
526*2a8bcb4eSToomas Soome 						sprintf(scratch, "doconfig failed on line %d of script %s",
5277c478bd9Sstevel@tonic-gate 								i, msgbuf);
5287c478bd9Sstevel@tonic-gate 						logmessage(scratch);
5297c478bd9Sstevel@tonic-gate 						(void)exit(2);
5307c478bd9Sstevel@tonic-gate 					}
5317c478bd9Sstevel@tonic-gate 					if (ioctl(passfd, I_SENDFD, 0) < 0) {
5327c478bd9Sstevel@tonic-gate 						sprintf(scratch,"NLPS passfd failed: %s", dbp->dbf_cmd_line);
5337c478bd9Sstevel@tonic-gate 						logmessage(scratch);
5347c478bd9Sstevel@tonic-gate 					}
5357c478bd9Sstevel@tonic-gate 				}
5367c478bd9Sstevel@tonic-gate 			}
5377c478bd9Sstevel@tonic-gate 		}
5387c478bd9Sstevel@tonic-gate 		else  {
5397c478bd9Sstevel@tonic-gate 			sprintf(scratch, nlsunknown, svc_code_p);
5407c478bd9Sstevel@tonic-gate 			logmessage(scratch);
5417c478bd9Sstevel@tonic-gate 			nls_reply(NLSUNKNOWN, scratch);
5427c478bd9Sstevel@tonic-gate 		}
5437c478bd9Sstevel@tonic-gate 		exit(2);
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	}  else
5467c478bd9Sstevel@tonic-gate 		error(E_BAD_FORMAT, CONTINUE);
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	/* if we're still here, server didn't get exec'ed	*/
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	return(-1);
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate /*
5567c478bd9Sstevel@tonic-gate  * nls_chkmsg:	validate message and return fields to caller.
5577c478bd9Sstevel@tonic-gate  *		returns: TRUE == good format
5587c478bd9Sstevel@tonic-gate  *			 FALSE== bad format
5597c478bd9Sstevel@tonic-gate  */
5607c478bd9Sstevel@tonic-gate 
561113f4232Sakaplan int
nls_chkmsg(bp,size,lowp,highp,svc_code_p)5627c478bd9Sstevel@tonic-gate nls_chkmsg(bp, size, lowp, highp, svc_code_p)
5637c478bd9Sstevel@tonic-gate char *bp, *svc_code_p;
5647c478bd9Sstevel@tonic-gate int size, *lowp, *highp;
5657c478bd9Sstevel@tonic-gate {
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	/* first, make sure bp is null terminated */
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	if ((*(bp + size - 1)) != (char)0)
5707c478bd9Sstevel@tonic-gate 		return(0);
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	/* scanf returns number of "matched and assigned items"	*/
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	return(sscanf(bp, "%*4c:%3d:%3d:%s", lowp, highp, svc_code_p) == 3);
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate /*
5807c478bd9Sstevel@tonic-gate  * nls_reply:	send the "service request response message"
5817c478bd9Sstevel@tonic-gate  *		when appropriate.  (Valid if running version 2 or greater).
5827c478bd9Sstevel@tonic-gate  *		Must use write(2) since unknown modules may be pushed.
5837c478bd9Sstevel@tonic-gate  *
5847c478bd9Sstevel@tonic-gate  *		Message format:
5857c478bd9Sstevel@tonic-gate  *		protocol_verion_# : message_code_# : message_text
5867c478bd9Sstevel@tonic-gate  */
5877c478bd9Sstevel@tonic-gate 
5887c478bd9Sstevel@tonic-gate static char *srrpprot = "%d:%d:%s";
5897c478bd9Sstevel@tonic-gate 
590113f4232Sakaplan static void
nls_reply(int code,char * text)591113f4232Sakaplan nls_reply(int code, char *text)
5927c478bd9Sstevel@tonic-gate {
5937c478bd9Sstevel@tonic-gate 	char scratch[256];
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 	/* Nlsversion = -1 for login service */
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	if (Nlsversion >= 2)  {
5987c478bd9Sstevel@tonic-gate 		DEBUG((7, "nls_reply: sending response message"));
5997c478bd9Sstevel@tonic-gate 		sprintf(scratch, srrpprot, Nlsversion, code, text);
6007c478bd9Sstevel@tonic-gate 		t_snd(0, scratch, strlen(scratch)+1, 0);
6017c478bd9Sstevel@tonic-gate 	}
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate /*
6067c478bd9Sstevel@tonic-gate  * common code to  start a server process (for any service)
6077c478bd9Sstevel@tonic-gate  * if optional argv is given, info comes from o_argv, else pointer
6087c478bd9Sstevel@tonic-gate  * to dbf struct is used.  In either case, first argument in argv is
6097c478bd9Sstevel@tonic-gate  * full pathname of server. Before exec-ing the server, the caller's
610*2a8bcb4eSToomas Soome  * logical address, opt and udata are added to the environment.
6117c478bd9Sstevel@tonic-gate  */
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate static char homeenv[BUFSIZ];
6147c478bd9Sstevel@tonic-gate #define NETFD	0
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 
617113f4232Sakaplan int
exec_cmd(dbf_t * dbp,char ** o_argv)618113f4232Sakaplan exec_cmd(dbf_t *dbp, char **o_argv)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate 	char *path;
6217c478bd9Sstevel@tonic-gate 	char **argvp;
6227c478bd9Sstevel@tonic-gate 	extern char **environ;
6237c478bd9Sstevel@tonic-gate 	dbf_t *getdbfentry();
6247c478bd9Sstevel@tonic-gate 	extern char **mkdbfargv();
625113f4232Sakaplan 	struct passwd *pwdp;
6267c478bd9Sstevel@tonic-gate 	struct group *grpp;
627113f4232Sakaplan 	dbf_t *wdbp = dbp;
6287c478bd9Sstevel@tonic-gate 	int	i;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 	/*
6317c478bd9Sstevel@tonic-gate 	 * o_argv is set during SMB service setup only, in
6327c478bd9Sstevel@tonic-gate 	 * which case dbp is NULL.
6337c478bd9Sstevel@tonic-gate 	 */
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 	if (o_argv) {
6367c478bd9Sstevel@tonic-gate 		argvp = o_argv;
6377c478bd9Sstevel@tonic-gate 		if ((wdbp = getdbfentry(DBF_SMB_CODE)) == NULL) {
6387c478bd9Sstevel@tonic-gate 			/* this shouldn't happen because at this point we've
6397c478bd9Sstevel@tonic-gate 			   already found it once */
6407c478bd9Sstevel@tonic-gate 			logmessage("NLPS: SMB message, missing data base entry");
6417c478bd9Sstevel@tonic-gate 			(void)exit(2); /* server, don't log */
6427c478bd9Sstevel@tonic-gate 		}
6437c478bd9Sstevel@tonic-gate 	}
6447c478bd9Sstevel@tonic-gate 	else
6457c478bd9Sstevel@tonic-gate 		argvp = mkdbfargv(dbp);
6467c478bd9Sstevel@tonic-gate 	path = *argvp;
6477c478bd9Sstevel@tonic-gate 
648*2a8bcb4eSToomas Soome 	sprintf(msgbuf,"NLPS (%s) exec: %s",
6497c478bd9Sstevel@tonic-gate 			(dbp)?dbp->dbf_svc_code:DBF_SMB_CODE, path);
6507c478bd9Sstevel@tonic-gate 	nls_reply(NLSSTART, msgbuf);
6517c478bd9Sstevel@tonic-gate 	logmessage(msgbuf);
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	if (wdbp->dbf_flags & DBF_UTMP) {
6547c478bd9Sstevel@tonic-gate 		pid_t	tmp;
6557c478bd9Sstevel@tonic-gate 		struct	stat	sbuf;
6567c478bd9Sstevel@tonic-gate 		char	*prefix;
6577c478bd9Sstevel@tonic-gate 		char	device[20];
6587c478bd9Sstevel@tonic-gate 		struct	utmpx utline;
6597c478bd9Sstevel@tonic-gate 
660*2a8bcb4eSToomas Soome 		/*
6617c478bd9Sstevel@tonic-gate 		 * create a utmpx entry.  extra fork makes parent init,
6627c478bd9Sstevel@tonic-gate 		 * which will clean up the entry.
6637c478bd9Sstevel@tonic-gate 		 */
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 		DEBUG((9, "Creating a utmpx entry for this service "));
6667c478bd9Sstevel@tonic-gate 		if ((tmp = fork()) < 0) {
6677c478bd9Sstevel@tonic-gate 			logmessage("NLPS: Can't fork to create utmpx entry");
6687c478bd9Sstevel@tonic-gate 			exit(2);
6697c478bd9Sstevel@tonic-gate 		}
6707c478bd9Sstevel@tonic-gate 		if (tmp)
6717c478bd9Sstevel@tonic-gate 			exit(0);	/* kill parent */
6727c478bd9Sstevel@tonic-gate 
673*2a8bcb4eSToomas Soome 		/*
6747c478bd9Sstevel@tonic-gate 		 * child continues processing, creating utmpx and exec'ing
6757c478bd9Sstevel@tonic-gate 		 * the service
6767c478bd9Sstevel@tonic-gate 		 */
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 		setpgrp();
6797c478bd9Sstevel@tonic-gate 		if (fstat(0, &sbuf) < 0) {
6807c478bd9Sstevel@tonic-gate 			logmessage("NLPS: Stat failed on fd 0: no line "
6817c478bd9Sstevel@tonic-gate 			    "field available for utmpx entry");
6827c478bd9Sstevel@tonic-gate 			*device = '\0';
6837c478bd9Sstevel@tonic-gate 		}
6847c478bd9Sstevel@tonic-gate 		else {
685*2a8bcb4eSToomas Soome 			/*
6867c478bd9Sstevel@tonic-gate 			 * MPREFIX is added to the environment by the parent
6877c478bd9Sstevel@tonic-gate 			 * listener process.
6887c478bd9Sstevel@tonic-gate 			 */
6897c478bd9Sstevel@tonic-gate 			prefix = getenv("MPREFIX");
6907c478bd9Sstevel@tonic-gate 			if (minor(sbuf.st_rdev) < 100)
6917c478bd9Sstevel@tonic-gate 				sprintf(device, "%.9s%02.02d", prefix, minor(sbuf.st_rdev));
6927c478bd9Sstevel@tonic-gate 			else
6937c478bd9Sstevel@tonic-gate 				sprintf(device, "%.8s%03.03d", prefix, minor(sbuf.st_rdev));
6947c478bd9Sstevel@tonic-gate 			DEBUG((9, "Device: %s", device));
6957c478bd9Sstevel@tonic-gate 		}
6967c478bd9Sstevel@tonic-gate 		strncpy(utline.ut_user, wdbp->dbf_id,
6977c478bd9Sstevel@tonic-gate 		    sizeof (utline.ut_user) - 1);
6987c478bd9Sstevel@tonic-gate 		sprintf(utline.ut_id, "ps%c%c", SC_WILDC, SC_WILDC);
6997c478bd9Sstevel@tonic-gate 		strncpy(utline.ut_line, device, sizeof (utline.ut_line) - 1);
7007c478bd9Sstevel@tonic-gate 		utline.ut_pid = getpid();
7017c478bd9Sstevel@tonic-gate                 utline.ut_type = USER_PROCESS;
7027c478bd9Sstevel@tonic-gate 		utline.ut_exit.e_termination = 0;
7037c478bd9Sstevel@tonic-gate 		utline.ut_exit.e_exit = 0;
7047c478bd9Sstevel@tonic-gate 		utline.ut_xtime = (time_t) time((time_t *)0);
7057c478bd9Sstevel@tonic-gate 		makeutx(&utline);
7067c478bd9Sstevel@tonic-gate 	}
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 	/* after pushmod, tli calls are questionable?		*/
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate 	DEBUG((9, "pushmod string: %s", wdbp->dbf_modules));
7117c478bd9Sstevel@tonic-gate 	if (dbp && pushmod(NETFD, dbp->dbf_modules)) {
7127c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Can't push server's modules: exit");
7137c478bd9Sstevel@tonic-gate 		exit(2); /* server, don't log */
7147c478bd9Sstevel@tonic-gate 	}
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 	DEBUG((9, "Running doconfig on %s", wdbp->dbf_svc_code));
7177c478bd9Sstevel@tonic-gate 	if ((i = doconfig(NETFD, wdbp->dbf_svc_code, 0)) != 0) {
7187c478bd9Sstevel@tonic-gate 		DEBUG((9, "doconfig exited with code %d", i));
719*2a8bcb4eSToomas Soome 		sprintf(msgbuf, "doconfig failed on line %d of script %s",
7207c478bd9Sstevel@tonic-gate 				i, wdbp->dbf_svc_code);
7217c478bd9Sstevel@tonic-gate 		logmessage(msgbuf);
7227c478bd9Sstevel@tonic-gate 	}
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	if (wdbp == NULL) {
7257c478bd9Sstevel@tonic-gate 		logmessage("NLPS: No database entry");
7267c478bd9Sstevel@tonic-gate 		exit(2); /* server, don't log */
7277c478bd9Sstevel@tonic-gate 	}
728*2a8bcb4eSToomas Soome 
7297c478bd9Sstevel@tonic-gate 	if ((pwdp = getpwnam(wdbp->dbf_id)) == NULL)  {
7307c478bd9Sstevel@tonic-gate 		sprintf(msgbuf, "NLPS: Missing or bad passwd entry for <%s>",wdbp->dbf_id);
7317c478bd9Sstevel@tonic-gate 		logmessage(msgbuf);
7327c478bd9Sstevel@tonic-gate 		exit(2); /* server, don't log */
733*2a8bcb4eSToomas Soome 	}
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate 	if (setgid(pwdp->pw_gid)) {
7377c478bd9Sstevel@tonic-gate 		if ((grpp = getgrgid(pwdp->pw_gid)) == NULL) {
7387c478bd9Sstevel@tonic-gate 			sprintf(msgbuf, "NLPS: No group entry for %ld", pwdp->pw_gid);
7397c478bd9Sstevel@tonic-gate 			logmessage(msgbuf);
7407c478bd9Sstevel@tonic-gate 			exit(2); /* server, don't log */
7417c478bd9Sstevel@tonic-gate 		}
7427c478bd9Sstevel@tonic-gate 		sprintf(msgbuf, "NLPS: Cannot set group id to %s", grpp->gr_name);
7437c478bd9Sstevel@tonic-gate 		logmessage(msgbuf);
7447c478bd9Sstevel@tonic-gate 		(void)exit(2); /* server, don't log */
7457c478bd9Sstevel@tonic-gate 	}
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	if (setuid(pwdp->pw_uid)) {
7487c478bd9Sstevel@tonic-gate 		sprintf(msgbuf, "NLPS: Cannot set user id to %s", wdbp->dbf_id);
7497c478bd9Sstevel@tonic-gate 		logmessage(msgbuf);
7507c478bd9Sstevel@tonic-gate 		(void)exit(2); /* server, don't log */
7517c478bd9Sstevel@tonic-gate 	}
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	if (chdir(pwdp->pw_dir)) {
7547c478bd9Sstevel@tonic-gate 		sprintf(msgbuf, "NLPS: Cannot chdir to %s", pwdp->pw_dir);
7557c478bd9Sstevel@tonic-gate 		logmessage(msgbuf);
7567c478bd9Sstevel@tonic-gate 		(void)exit(2); /* server, don't log */
7577c478bd9Sstevel@tonic-gate 	}
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	DEBUG((9, "New uid %ld New gid %ld", getuid(), getgid()));
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	sprintf(homeenv, "HOME=%s", pwdp->pw_dir);
7627c478bd9Sstevel@tonic-gate 	DEBUG((9,"HOME=%s", pwdp->pw_dir));
7637c478bd9Sstevel@tonic-gate 	putenv(homeenv);
7647c478bd9Sstevel@tonic-gate 	endpwent();
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 	fclose(Logfp);
7677c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
7687c478bd9Sstevel@tonic-gate 	fclose(Debugfp);
7697c478bd9Sstevel@tonic-gate #endif
7707c478bd9Sstevel@tonic-gate 	execve(path, argvp, environ);
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	/* exec returns only on failure!		*/
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	logmessage("NLPS server: could not exec service");
7757c478bd9Sstevel@tonic-gate 	sys_error(E_SYS_ERROR, CONTINUE);
7767c478bd9Sstevel@tonic-gate 	return(-1);
7777c478bd9Sstevel@tonic-gate }
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate /*
7847c478bd9Sstevel@tonic-gate  * isdigits:	string version of isdigit.  (See ctype(3))
7857c478bd9Sstevel@tonic-gate  */
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate /* This routine is public here and used in lsdbf.c as an external */
7887c478bd9Sstevel@tonic-gate int
isdigits(p)7897c478bd9Sstevel@tonic-gate isdigits(p)
7907c478bd9Sstevel@tonic-gate register char *p;
7917c478bd9Sstevel@tonic-gate {
7927c478bd9Sstevel@tonic-gate 	register int flag = 1;
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 	if (!strlen(p))
7957c478bd9Sstevel@tonic-gate 		return(0);
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	while (*p)
7987c478bd9Sstevel@tonic-gate 		if (!isdigit(*p++))
7997c478bd9Sstevel@tonic-gate 			flag = 0;
8007c478bd9Sstevel@tonic-gate 	return(flag);
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate int
l_rcv(bufp,bytes,flagp)8057c478bd9Sstevel@tonic-gate l_rcv(bufp, bytes, flagp)
8067c478bd9Sstevel@tonic-gate char *bufp;
8077c478bd9Sstevel@tonic-gate int bytes;
8087c478bd9Sstevel@tonic-gate int *flagp;
8097c478bd9Sstevel@tonic-gate {
8107c478bd9Sstevel@tonic-gate 	register int n;
8117c478bd9Sstevel@tonic-gate 	register int count = bytes;
8127c478bd9Sstevel@tonic-gate 	register char *bp = bufp;
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate 	DEBUG((9, "in l_rcv"));
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	do {
8177c478bd9Sstevel@tonic-gate 		*flagp = 0;
8187c478bd9Sstevel@tonic-gate 		n = t_rcv(0, bp, count, flagp);
819*2a8bcb4eSToomas Soome 		DEBUG((9, "l_rcv, after t_rcv call, n =  %d",n));
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 		if (n < 0) {
822*2a8bcb4eSToomas Soome 			DEBUG((9, "l_rcv, t_errno is %d", t_errno));
8237c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
8247c478bd9Sstevel@tonic-gate 			if (t_errno == TLOOK) {
8257c478bd9Sstevel@tonic-gate 				DEBUG((9, "l_rcv, t_look returns %d", t_look(0)));
8267c478bd9Sstevel@tonic-gate 			}
8277c478bd9Sstevel@tonic-gate #endif
8287c478bd9Sstevel@tonic-gate 			return(n);
8297c478bd9Sstevel@tonic-gate 		}
8307c478bd9Sstevel@tonic-gate 		count -= n;
8317c478bd9Sstevel@tonic-gate 		bp += n;
8327c478bd9Sstevel@tonic-gate 	} while (count > 0);
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 	return(bp - bufp);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate /*
8397c478bd9Sstevel@tonic-gate  * getdbfentry:	Given a service code, return a pointer to the dbf_t
8407c478bd9Sstevel@tonic-gate  *		entry.  Return NULL if the entry doesn't exist.
8417c478bd9Sstevel@tonic-gate  *		Reads the data base, one line at a time, into
8427c478bd9Sstevel@tonic-gate  *		Dbf_line_buf.
8437c478bd9Sstevel@tonic-gate  */
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate static	char	Dbf_line_buf[DBFLINESZ];
8467c478bd9Sstevel@tonic-gate static	dbf_t	Dbf_entry;
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate dbf_t *
getdbfentry(svc_code_p)8497c478bd9Sstevel@tonic-gate getdbfentry(svc_code_p)
8507c478bd9Sstevel@tonic-gate register char *svc_code_p;
8517c478bd9Sstevel@tonic-gate {
8527c478bd9Sstevel@tonic-gate 	FILE	*dbfp;
8537c478bd9Sstevel@tonic-gate 	char	dbfname[BUFSIZ];
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate 	sprintf(dbfname, "%s/%s", Basedir, DBFNAME);
8567c478bd9Sstevel@tonic-gate 	if ((dbfp = fopen(dbfname, "r")) == NULL) {
8577c478bd9Sstevel@tonic-gate 		DEBUG((9, "open of database file %s failed", DBFNAME));
8587c478bd9Sstevel@tonic-gate 		logmessage("NLPS: Unable to open database file");
8597c478bd9Sstevel@tonic-gate 		return((dbf_t *)NULL);
8607c478bd9Sstevel@tonic-gate 	}
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	DEBUG((9, "database file opened, looking for %s", svc_code_p));
863*2a8bcb4eSToomas Soome 	while (rd_dbf_line(dbfp, Dbf_line_buf, &Dbf_entry.dbf_svc_code,
8647c478bd9Sstevel@tonic-gate 		&Dbf_entry.dbf_flags, &Dbf_entry.dbf_id, &Dbf_entry.dbf_res1,
8657c478bd9Sstevel@tonic-gate 		&Dbf_entry.dbf_res2, &Dbf_entry.dbf_res3,&Dbf_entry.dbf_prv_adr,
866*2a8bcb4eSToomas Soome 		&Dbf_entry.dbf_prognum, &Dbf_entry.dbf_version,
867*2a8bcb4eSToomas Soome 		&Dbf_entry.dbf_modules, &Dbf_entry.dbf_sflags,
8687c478bd9Sstevel@tonic-gate 		&Dbf_entry.dbf_cmd_line) > 0) {
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 		/* see if this line is the one we want (svc_code match) */
8717c478bd9Sstevel@tonic-gate 		if (!strcmp(Dbf_entry.dbf_svc_code, svc_code_p)) {
8727c478bd9Sstevel@tonic-gate 			fclose(dbfp);
8737c478bd9Sstevel@tonic-gate 			return(&Dbf_entry);
8747c478bd9Sstevel@tonic-gate 		}
8757c478bd9Sstevel@tonic-gate 	}
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	DEBUG((9, "No svc code match"));
8787c478bd9Sstevel@tonic-gate 	fclose(dbfp);
8797c478bd9Sstevel@tonic-gate 	return((dbf_t *)0);	/* svc code not in database	*/
8807c478bd9Sstevel@tonic-gate }
881