xref: /titanic_51/usr/src/cmd/bnu/permission.c (revision 462be471126495414a94f9fa35e16c02dc462c04)
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 /*
23*462be471Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
27*462be471Sceastha /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*462be471Sceastha /*	  All Rights Reserved  	*/
29*462be471Sceastha 
30*462be471Sceastha #pragma ident	"%Z%%M%	%I%	%E% SMI"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #ifndef UUCHECK
337c478bd9Sstevel@tonic-gate #include "uucp.h"
347c478bd9Sstevel@tonic-gate #endif
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /*  field array indexes for PERMISSIONS parameters */
387c478bd9Sstevel@tonic-gate #define U_LOGNAME	0
397c478bd9Sstevel@tonic-gate #define U_MACHINE	1
407c478bd9Sstevel@tonic-gate #define U_CALLBACK	2
417c478bd9Sstevel@tonic-gate #define U_REQUEST	3
427c478bd9Sstevel@tonic-gate #define U_SENDFILES	4
437c478bd9Sstevel@tonic-gate #define U_READPATH	5
447c478bd9Sstevel@tonic-gate #define U_WRITEPATH	6
457c478bd9Sstevel@tonic-gate #define U_NOREADPATH	7
467c478bd9Sstevel@tonic-gate #define U_NOWRITEPATH	8
477c478bd9Sstevel@tonic-gate #define U_MYNAME	9
487c478bd9Sstevel@tonic-gate #define U_COMMANDS	10
497c478bd9Sstevel@tonic-gate #define U_VALIDATE	11
507c478bd9Sstevel@tonic-gate #define U_PUBDIR	12
517c478bd9Sstevel@tonic-gate #define U_DIRECT	13
527c478bd9Sstevel@tonic-gate #define U_ALIAS		14
537c478bd9Sstevel@tonic-gate #define U_PATH		15
547c478bd9Sstevel@tonic-gate /*  NUMFLDS should be one more than the highest U_ value */
557c478bd9Sstevel@tonic-gate #define NUMFLDS		16
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate /* fields found in PERMISSIONS for requested system/login */
587c478bd9Sstevel@tonic-gate static char *_Flds[NUMFLDS];
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /* keyword/value structure */
617c478bd9Sstevel@tonic-gate struct keywords {
627c478bd9Sstevel@tonic-gate 	char* kword;
637c478bd9Sstevel@tonic-gate 	int kvalue;
647c478bd9Sstevel@tonic-gate };
657c478bd9Sstevel@tonic-gate static struct keywords _Kwords[] = {
667c478bd9Sstevel@tonic-gate 	{"LOGNAME", U_LOGNAME},
677c478bd9Sstevel@tonic-gate 	{"MACHINE", U_MACHINE},
687c478bd9Sstevel@tonic-gate 	{"CALLBACK", U_CALLBACK},
697c478bd9Sstevel@tonic-gate 	{"REQUEST", U_REQUEST},
707c478bd9Sstevel@tonic-gate 	{"SENDFILES", U_SENDFILES},
717c478bd9Sstevel@tonic-gate 	{"READ", U_READPATH},
727c478bd9Sstevel@tonic-gate 	{"WRITE", U_WRITEPATH},
737c478bd9Sstevel@tonic-gate 	{"NOREAD", U_NOREADPATH},
747c478bd9Sstevel@tonic-gate 	{"NOWRITE", U_NOWRITEPATH},
757c478bd9Sstevel@tonic-gate 	{"MYNAME", U_MYNAME},
767c478bd9Sstevel@tonic-gate 	{"COMMANDS", U_COMMANDS},
777c478bd9Sstevel@tonic-gate 	{"VALIDATE", U_VALIDATE},
787c478bd9Sstevel@tonic-gate 	{"PUBDIR", U_PUBDIR},
797c478bd9Sstevel@tonic-gate 	{"DIRECT", U_DIRECT},
807c478bd9Sstevel@tonic-gate 	{"ALIAS", U_ALIAS},
817c478bd9Sstevel@tonic-gate 	{"PATH", U_PATH},
827c478bd9Sstevel@tonic-gate };
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate #define MAXCMDS		30
857c478bd9Sstevel@tonic-gate #define MAXPATHS	20
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /* for all options on paths - read, write, noread, nowrite */
887c478bd9Sstevel@tonic-gate /* NB: all pointers assumed to point to static data */
897c478bd9Sstevel@tonic-gate static char *_RPaths[MAXPATHS+1];
907c478bd9Sstevel@tonic-gate static char *_WPaths[MAXPATHS+1];
917c478bd9Sstevel@tonic-gate static char *_NoRPaths[MAXPATHS+1];
927c478bd9Sstevel@tonic-gate static char *_NoWPaths[MAXPATHS+1];
937c478bd9Sstevel@tonic-gate static char *_Commands[MAXCMDS+1];
947c478bd9Sstevel@tonic-gate static char _Cmd_defaults[BUFSIZ];
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /* option variables */
977c478bd9Sstevel@tonic-gate static int _Request;	/* TRUE can request, FALSE can not request files */
987c478bd9Sstevel@tonic-gate static int _Switch;	/* FALSE requires a call back to send any files */
997c478bd9Sstevel@tonic-gate static int _CallBack;	/* TRUE for call back for any transaction */
1007c478bd9Sstevel@tonic-gate static int _NoSpool;	/* TRUE if delivering directly to destination file */
1017c478bd9Sstevel@tonic-gate static char _MyName[MAXBASENAME+1];	/* Myname from PERMISSIONS file */
1027c478bd9Sstevel@tonic-gate /* NB: _Pubdir and _Path assumed to point to dynamic data */
1037c478bd9Sstevel@tonic-gate static char *_Pubdir = NULL;		/* PUBDIR from PERMISSIONS file */
1047c478bd9Sstevel@tonic-gate static char *_Path = NULL;		/* PATH from PERMISSIONS file */
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate struct name_value
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate 	char *name;
1097c478bd9Sstevel@tonic-gate 	char *value;
1107c478bd9Sstevel@tonic-gate };
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate /* file pointer for PERMISSIONS */
1137c478bd9Sstevel@tonic-gate static FILE *Fp = NULL;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate /* functions */
1167c478bd9Sstevel@tonic-gate extern char *next_token(), *nextarg();
1177c478bd9Sstevel@tonic-gate extern int parse_tokens(), canPath(), mkdirs();
1187c478bd9Sstevel@tonic-gate static void fillFlds();
1197c478bd9Sstevel@tonic-gate static void fillList();
1207c478bd9Sstevel@tonic-gate static int cmdMatch(), listMatch(), nameMatch(),
1217c478bd9Sstevel@tonic-gate 	userFind(), validateFind();
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate int
1247c478bd9Sstevel@tonic-gate noSpool()
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	return(_NoSpool);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate  * fill in fields for login name
1317c478bd9Sstevel@tonic-gate  * name - the login id
1327c478bd9Sstevel@tonic-gate  * rmtname - remote system name
1337c478bd9Sstevel@tonic-gate  *
1347c478bd9Sstevel@tonic-gate  * return:
1357c478bd9Sstevel@tonic-gate  *	0 -> found login name
1367c478bd9Sstevel@tonic-gate  *	FAIL -> did not find login
1377c478bd9Sstevel@tonic-gate  */
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate int
1407c478bd9Sstevel@tonic-gate logFind(name, rmtname)
1417c478bd9Sstevel@tonic-gate char *name, *rmtname;
1427c478bd9Sstevel@tonic-gate {
1437c478bd9Sstevel@tonic-gate 	int ret;
1447c478bd9Sstevel@tonic-gate 	DEBUG(5, "logFind called (name: %s, ", name);
1457c478bd9Sstevel@tonic-gate 	DEBUG(5, "rmtname: %s)\n", rmtname);
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	ret = validateFind (rmtname);
1487c478bd9Sstevel@tonic-gate 	if (ret == SUCCESS) { /* found VALIDATE entry */
1497c478bd9Sstevel@tonic-gate 	    ret = userFind (name, rmtname, U_VALIDATE);
1507c478bd9Sstevel@tonic-gate 	    if (ret) {
1517c478bd9Sstevel@tonic-gate 		DEBUG(5, "machine/login match failed%s", "");
1527c478bd9Sstevel@tonic-gate 		return(FAIL);
1537c478bd9Sstevel@tonic-gate 	    }
1547c478bd9Sstevel@tonic-gate 	}
1557c478bd9Sstevel@tonic-gate 	else
1567c478bd9Sstevel@tonic-gate 	    ret = userFind (name, "", U_LOGNAME);
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	DEBUG(7, "_Request (%s), ",
1597c478bd9Sstevel@tonic-gate 	    requestOK() ? "TRUE" : "FALSE");
1607c478bd9Sstevel@tonic-gate 	DEBUG(7, "_Switch (%s), ",
1617c478bd9Sstevel@tonic-gate 	    switchRole() ? "TRUE" : "FALSE");
1627c478bd9Sstevel@tonic-gate 	DEBUG(7, "_CallBack (%s), ",
1637c478bd9Sstevel@tonic-gate 	    callBack() ? "TRUE" : "FALSE");
1647c478bd9Sstevel@tonic-gate 	DEBUG(7, "_MyName (%s), ", _MyName);
1657c478bd9Sstevel@tonic-gate 	DEBUG(7, "_NoSpool (%s), ",
1667c478bd9Sstevel@tonic-gate 	    noSpool() ? "TRUE" : "FALSE");
1677c478bd9Sstevel@tonic-gate 	return(ret);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate  * fill in fields for machine name
1727c478bd9Sstevel@tonic-gate  * return:
1737c478bd9Sstevel@tonic-gate  *	0 -> found machine name
1747c478bd9Sstevel@tonic-gate  *	FAIL -> did not find machine
1757c478bd9Sstevel@tonic-gate  */
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate int
1787c478bd9Sstevel@tonic-gate mchFind(name)
1797c478bd9Sstevel@tonic-gate char *name;
1807c478bd9Sstevel@tonic-gate {
181*462be471Sceastha 	int i, ret;
1827c478bd9Sstevel@tonic-gate 	DEBUG(5, "mchFind called (%s)\n", name);
1837c478bd9Sstevel@tonic-gate 	if ( (ret = userFind (name, "", U_MACHINE)) == FAIL)
1847c478bd9Sstevel@tonic-gate 	    /* see if there is a default line */
1857c478bd9Sstevel@tonic-gate 	    (void) userFind ("OTHER", "", U_MACHINE);
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	/*  mchFind is from MASTER mode - switch role is always ok */
1887c478bd9Sstevel@tonic-gate 	_Switch = TRUE;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	DEBUG(7, "_Request (%s), ",
1917c478bd9Sstevel@tonic-gate 	    requestOK() ? "TRUE" : "FALSE");
1927c478bd9Sstevel@tonic-gate 	DEBUG(7, "_Switch (%s), ",
1937c478bd9Sstevel@tonic-gate 	    switchRole() ? "TRUE" : "FALSE");
1947c478bd9Sstevel@tonic-gate 	DEBUG(7, "_CallBack (%s), ",
1957c478bd9Sstevel@tonic-gate 	    callBack() ? "TRUE" : "FALSE");
1967c478bd9Sstevel@tonic-gate 	DEBUG(7, "_MyName (%s), ", _MyName);
1977c478bd9Sstevel@tonic-gate 	DEBUG(7, "_NoSpool (%s), ",
1987c478bd9Sstevel@tonic-gate 	    noSpool() ? "TRUE" : "FALSE");
1997c478bd9Sstevel@tonic-gate 	for (i=0; _Commands[i] != NULL; i++)
2007c478bd9Sstevel@tonic-gate 	    DEBUG(7, "_Commands %s\n",  _Commands[i]);
2017c478bd9Sstevel@tonic-gate 	return(ret);
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate /*
2057c478bd9Sstevel@tonic-gate  * this function will find a login name in the LOGNAME
2067c478bd9Sstevel@tonic-gate  * field.
2077c478bd9Sstevel@tonic-gate  * input:
2087c478bd9Sstevel@tonic-gate  *	name	-> who the remote says he/she is
2097c478bd9Sstevel@tonic-gate  * return:
2107c478bd9Sstevel@tonic-gate  *	SUCCESS	-> found
2117c478bd9Sstevel@tonic-gate  *	FAIL	-> not found
2127c478bd9Sstevel@tonic-gate  */
2137c478bd9Sstevel@tonic-gate static int
2147c478bd9Sstevel@tonic-gate nameMatch(name, fld)
2157c478bd9Sstevel@tonic-gate char *name, *fld;
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate 	char *arg;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	if (fld == NULL)
2207c478bd9Sstevel@tonic-gate 	    return(FAIL);
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	while (*fld) {
2237c478bd9Sstevel@tonic-gate 	    fld = nextarg(fld, &arg);
2247c478bd9Sstevel@tonic-gate 	    if (EQUALS(arg, name))
2257c478bd9Sstevel@tonic-gate 		return(SUCCESS);
2267c478bd9Sstevel@tonic-gate 	}
2277c478bd9Sstevel@tonic-gate 	return (FAIL);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate  * interpret the _Flds options and set the option variables
2337c478bd9Sstevel@tonic-gate  */
2347c478bd9Sstevel@tonic-gate static void
2357c478bd9Sstevel@tonic-gate fillFlds()
2367c478bd9Sstevel@tonic-gate {
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 	if (_Flds[U_REQUEST] != NULL) {
2397c478bd9Sstevel@tonic-gate 		if (EQUALS(_Flds[U_REQUEST], "yes"))
2407c478bd9Sstevel@tonic-gate 			_Request = TRUE;
2417c478bd9Sstevel@tonic-gate 		else
2427c478bd9Sstevel@tonic-gate 			_Request = FALSE;
2437c478bd9Sstevel@tonic-gate 	}
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	if (_Flds[U_SENDFILES] != NULL) {
2467c478bd9Sstevel@tonic-gate 		if (EQUALS(_Flds[U_SENDFILES], "yes"))
2477c478bd9Sstevel@tonic-gate 			_Switch = TRUE;
2487c478bd9Sstevel@tonic-gate 		else
2497c478bd9Sstevel@tonic-gate 			_Switch = FALSE;
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	if (_Flds[U_CALLBACK] != NULL) {
2537c478bd9Sstevel@tonic-gate 		if (EQUALS(_Flds[U_CALLBACK], "yes"))
2547c478bd9Sstevel@tonic-gate 			_CallBack = TRUE;
2557c478bd9Sstevel@tonic-gate 		else
2567c478bd9Sstevel@tonic-gate 			_CallBack = FALSE;
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	if (_Flds[U_DIRECT] != NULL) {
2607c478bd9Sstevel@tonic-gate 		if (EQUALS(_Flds[U_DIRECT], "yes"))
2617c478bd9Sstevel@tonic-gate 			_NoSpool = TRUE;
2627c478bd9Sstevel@tonic-gate 		else
2637c478bd9Sstevel@tonic-gate 			_NoSpool = FALSE;
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	if (_Flds[U_MYNAME] != NULL) {
2677c478bd9Sstevel@tonic-gate 		strncpy(_MyName, _Flds[U_MYNAME], MAXBASENAME);
2687c478bd9Sstevel@tonic-gate 		_MyName[MAXBASENAME] = NULLCHAR;
2697c478bd9Sstevel@tonic-gate 	}
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	if (_Flds[U_PUBDIR] != NULL) {
2727c478bd9Sstevel@tonic-gate 		if (_Pubdir != NULL)
2737c478bd9Sstevel@tonic-gate 		    free(_Pubdir);	/* get rid of previous one */
2747c478bd9Sstevel@tonic-gate 		_Pubdir = strdup(_Flds[U_PUBDIR]);
2757c478bd9Sstevel@tonic-gate #ifndef UUCHECK
2767c478bd9Sstevel@tonic-gate 		ASSERT(_Pubdir != NULL, Ct_ALLOCATE, _Flds[U_PUBDIR], 0);
2777c478bd9Sstevel@tonic-gate #else /* UUCHECK */
2787c478bd9Sstevel@tonic-gate 		if (_Pubdir == NULL) {
2797c478bd9Sstevel@tonic-gate 		    perror(gettext("malloc() error"));
2807c478bd9Sstevel@tonic-gate 		    exit(1);
2817c478bd9Sstevel@tonic-gate 		}
2827c478bd9Sstevel@tonic-gate #endif /* UUCHECK */
2837c478bd9Sstevel@tonic-gate 		Pubdir = _RPaths[0] = _WPaths[0] = _Pubdir; /* reset default */
2847c478bd9Sstevel@tonic-gate 	}
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	if (_Flds[U_PATH] != NULL) {
2877c478bd9Sstevel@tonic-gate 		if (_Path != NULL)
2887c478bd9Sstevel@tonic-gate 		    free(_Path);	/* get rid of previous one */
2897c478bd9Sstevel@tonic-gate 		_Path = strdup(_Flds[U_PATH]);
2907c478bd9Sstevel@tonic-gate #ifndef UUCHECK
2917c478bd9Sstevel@tonic-gate 		ASSERT(_Path != NULL, Ct_ALLOCATE, _Flds[U_PATH], 0);
2927c478bd9Sstevel@tonic-gate #else /* UUCHECK */
2937c478bd9Sstevel@tonic-gate 		if (_Path == NULL) {
2947c478bd9Sstevel@tonic-gate 		    perror(gettext("malloc() error"));
2957c478bd9Sstevel@tonic-gate 		    exit(1);
2967c478bd9Sstevel@tonic-gate 		}
2977c478bd9Sstevel@tonic-gate #endif /* UUCHECK */
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	return;
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate /*
3047c478bd9Sstevel@tonic-gate  * fill in the list vector for the system/login
3057c478bd9Sstevel@tonic-gate  * input:
3067c478bd9Sstevel@tonic-gate  *	type - list type (read, write, noread, nowrite, command)
3077c478bd9Sstevel@tonic-gate  * output:
3087c478bd9Sstevel@tonic-gate  *	list - filled in with items.
3097c478bd9Sstevel@tonic-gate  * return:
3107c478bd9Sstevel@tonic-gate  *	number of items in list
3117c478bd9Sstevel@tonic-gate  */
3127c478bd9Sstevel@tonic-gate static void
3137c478bd9Sstevel@tonic-gate fillList(type, list)
3147c478bd9Sstevel@tonic-gate int type;
3157c478bd9Sstevel@tonic-gate char *list[];
3167c478bd9Sstevel@tonic-gate {
317*462be471Sceastha 	char *p;
318*462be471Sceastha 	int num;
3197c478bd9Sstevel@tonic-gate 	int maxlist = 0;
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	p = _Flds[type];
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	/* find list limit */
3247c478bd9Sstevel@tonic-gate 	if (type == U_READPATH || type == U_WRITEPATH
3257c478bd9Sstevel@tonic-gate 	 || type == U_NOREADPATH || type == U_NOWRITEPATH)
3267c478bd9Sstevel@tonic-gate 		maxlist = MAXPATHS;
3277c478bd9Sstevel@tonic-gate 	else if (type == U_COMMANDS)
3287c478bd9Sstevel@tonic-gate 		maxlist = MAXCMDS;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	if (p == NULL || !*p) {
3317c478bd9Sstevel@tonic-gate 		 /* no names specified, default already setup */
3327c478bd9Sstevel@tonic-gate 		return;
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	num = 0;
3367c478bd9Sstevel@tonic-gate 	while (*p && num < maxlist) {
3377c478bd9Sstevel@tonic-gate 		list[num] = p;
3387c478bd9Sstevel@tonic-gate 		if (*p == ':') {	/* null path */
3397c478bd9Sstevel@tonic-gate 			*p++ = NULLCHAR;
3407c478bd9Sstevel@tonic-gate 			continue;
3417c478bd9Sstevel@tonic-gate 		}
3427c478bd9Sstevel@tonic-gate 		while (*p && *p != ':')
3437c478bd9Sstevel@tonic-gate 			p++;
3447c478bd9Sstevel@tonic-gate 		if (*p == ':')
3457c478bd9Sstevel@tonic-gate 			*p++ = NULLCHAR;
3467c478bd9Sstevel@tonic-gate 		DEBUG(7, "list (%s) ", list[num]);
3477c478bd9Sstevel@tonic-gate 		num++;
3487c478bd9Sstevel@tonic-gate 	}
3497c478bd9Sstevel@tonic-gate 	DEBUG(7, "num = %d\n", num);
3507c478bd9Sstevel@tonic-gate 	list[num] = NULL;
3517c478bd9Sstevel@tonic-gate 	return;
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate  * Find the line of PERMISSIONS for login.
3567c478bd9Sstevel@tonic-gate  * The search is determined by the type field
3577c478bd9Sstevel@tonic-gate  * (type=U_LOGNAME, U_MACHINE or U_VALIDATE)
3587c478bd9Sstevel@tonic-gate  * For U_LOGNAME:
3597c478bd9Sstevel@tonic-gate  *	search for "name" in a LOGNAME= option
3607c478bd9Sstevel@tonic-gate  * For U_MACHINE:
3617c478bd9Sstevel@tonic-gate  *	search for "name" in a MACHINE= option
3627c478bd9Sstevel@tonic-gate  * For U_VALIDATE:
3637c478bd9Sstevel@tonic-gate  *	search for "rmtname" in a VALIDATE= option and
3647c478bd9Sstevel@tonic-gate  *	for the same entry see if "name" is in the LOGNAME= option
3657c478bd9Sstevel@tonic-gate  * input:
3667c478bd9Sstevel@tonic-gate  *	name -> search name
3677c478bd9Sstevel@tonic-gate  *	logname -> for validate entry
3687c478bd9Sstevel@tonic-gate  *	type -> U_MACHINE or U_LOGNAME
3697c478bd9Sstevel@tonic-gate  * output:
3707c478bd9Sstevel@tonic-gate  *	The global values of all options will be set
3717c478bd9Sstevel@tonic-gate  *	(e.g. _RPaths, _WPaths,  _Request, ...)
3727c478bd9Sstevel@tonic-gate  * return:
3737c478bd9Sstevel@tonic-gate  *	0 -> ok
3747c478bd9Sstevel@tonic-gate  *	FAIL -> no match found
3757c478bd9Sstevel@tonic-gate  */
3767c478bd9Sstevel@tonic-gate static int
3777c478bd9Sstevel@tonic-gate userFind(name, rmtname, type)
3787c478bd9Sstevel@tonic-gate char *name, *rmtname;
3797c478bd9Sstevel@tonic-gate int type;
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 	char *p, *arg, *buf = NULL;
3827c478bd9Sstevel@tonic-gate 	static char default_buf[BUFSIZ];
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 	if (name != NULL && strcmp(name, "DEFAULT") != 0) {
3857c478bd9Sstevel@tonic-gate 		/* call ourself recursively to set defaults */
3867c478bd9Sstevel@tonic-gate 		(void) userFind("DEFAULT", "", U_MACHINE);
3877c478bd9Sstevel@tonic-gate 	} else {
3887c478bd9Sstevel@tonic-gate 		/*
3897c478bd9Sstevel@tonic-gate 		 * Handle case where looking for DEFAULT entry.
3907c478bd9Sstevel@tonic-gate 		 * First initialize all defaults to their "base"
3917c478bd9Sstevel@tonic-gate 		 * values.  Then the DEFAULT entry, if found,
3927c478bd9Sstevel@tonic-gate 		 * will override these settings.
3937c478bd9Sstevel@tonic-gate 		 */
3947c478bd9Sstevel@tonic-gate 		_Request = FALSE;
3957c478bd9Sstevel@tonic-gate 		_CallBack = FALSE;
3967c478bd9Sstevel@tonic-gate 		_Switch = FALSE;
3977c478bd9Sstevel@tonic-gate 		_NoSpool = FALSE;
3987c478bd9Sstevel@tonic-gate 		_MyName[0] = NULLCHAR;
3997c478bd9Sstevel@tonic-gate 		_RPaths[0] = _WPaths[0] = PUBDIR;	/* default is public */
4007c478bd9Sstevel@tonic-gate 		_RPaths[1] = _WPaths[1] = NULLCHAR;
4017c478bd9Sstevel@tonic-gate 		_NoRPaths[0] = NULLCHAR;
4027c478bd9Sstevel@tonic-gate 		_NoWPaths[0] = NULLCHAR;
4037c478bd9Sstevel@tonic-gate 		if (_Pubdir != NULL)
4047c478bd9Sstevel@tonic-gate 			free(_Pubdir);
4057c478bd9Sstevel@tonic-gate 		Pubdir = _Pubdir = strdup(PUBDIR);
4067c478bd9Sstevel@tonic-gate 		if (_Path != NULL)
4077c478bd9Sstevel@tonic-gate 			free(_Path);
4087c478bd9Sstevel@tonic-gate 		_Path = strdup(PATH);
4097c478bd9Sstevel@tonic-gate 		/* set up Commands defaults */
4107c478bd9Sstevel@tonic-gate 		_Flds[U_COMMANDS] = strcpy(_Cmd_defaults, DEFAULTCMDS);
4117c478bd9Sstevel@tonic-gate 		fillList(U_COMMANDS, _Commands);
4127c478bd9Sstevel@tonic-gate 		/*
4137c478bd9Sstevel@tonic-gate 		 * put defaults we read in in here so they're not overwritten
4147c478bd9Sstevel@tonic-gate 		 * by non-DEFAULT entries.
4157c478bd9Sstevel@tonic-gate 		 */
4167c478bd9Sstevel@tonic-gate 		buf = default_buf;
4177c478bd9Sstevel@tonic-gate 	}
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	if (name == NULL)	/* use defaults */
4207c478bd9Sstevel@tonic-gate 		return(0);	/* I don't think this will ever happen */
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate 	if ( (Fp = fopen(PERMISSIONS, "r")) == NULL) {
4237c478bd9Sstevel@tonic-gate 		DEBUG(5, "can't open %s\n", PERMISSIONS);
4247c478bd9Sstevel@tonic-gate 		return(FAIL);
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	for (;;) {
4287c478bd9Sstevel@tonic-gate 	    if (parse_tokens (_Flds, buf) != 0) {
4297c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
4307c478bd9Sstevel@tonic-gate 		DEBUG(5, "name (%s) not found; return FAIL\n", name);
4317c478bd9Sstevel@tonic-gate 		return(FAIL);
4327c478bd9Sstevel@tonic-gate 	    }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 	    p = _Flds[type];
4357c478bd9Sstevel@tonic-gate 	    while (p && *p) {
4367c478bd9Sstevel@tonic-gate 		p = nextarg(p, &arg);
4377c478bd9Sstevel@tonic-gate 		switch (type) {
4387c478bd9Sstevel@tonic-gate 		case U_VALIDATE:
4397c478bd9Sstevel@tonic-gate 		    if (EQUALS(arg, rmtname)
4407c478bd9Sstevel@tonic-gate 			&& nameMatch(name, _Flds[U_LOGNAME])==SUCCESS)
4417c478bd9Sstevel@tonic-gate 				break;
4427c478bd9Sstevel@tonic-gate 		    continue;
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 		case U_LOGNAME:
4457c478bd9Sstevel@tonic-gate 		    if (EQUALS(arg, name))
4467c478bd9Sstevel@tonic-gate 				break;
4477c478bd9Sstevel@tonic-gate 		    continue;
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 		case U_MACHINE:
4507c478bd9Sstevel@tonic-gate 		    if (EQUALSN(arg, name, MAXBASENAME))
4517c478bd9Sstevel@tonic-gate 				break;
4527c478bd9Sstevel@tonic-gate 		    continue;
4537c478bd9Sstevel@tonic-gate 		}
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
4567c478bd9Sstevel@tonic-gate 		fillFlds();
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 		/* fill in path lists */
4597c478bd9Sstevel@tonic-gate 		fillList(U_READPATH, _RPaths);
4607c478bd9Sstevel@tonic-gate 		fillList(U_WRITEPATH, _WPaths);
4617c478bd9Sstevel@tonic-gate 		if (!requestOK())
4627c478bd9Sstevel@tonic-gate 		    _Flds[U_NOREADPATH] = "/";
4637c478bd9Sstevel@tonic-gate 		fillList(U_NOREADPATH, _NoRPaths);
4647c478bd9Sstevel@tonic-gate 		fillList(U_NOWRITEPATH, _NoWPaths);
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 		/* fill in command list */
4677c478bd9Sstevel@tonic-gate 		fillList(U_COMMANDS, _Commands);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 		return(0);
4707c478bd9Sstevel@tonic-gate 	    }
4717c478bd9Sstevel@tonic-gate 	}
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate /*
4757c478bd9Sstevel@tonic-gate  * see if name is in a VALIDATE option
4767c478bd9Sstevel@tonic-gate  * return:
4777c478bd9Sstevel@tonic-gate  *	FAIL -> not found
4787c478bd9Sstevel@tonic-gate  *	SUCCESS -> found
4797c478bd9Sstevel@tonic-gate  */
4807c478bd9Sstevel@tonic-gate static int
4817c478bd9Sstevel@tonic-gate validateFind(name)
4827c478bd9Sstevel@tonic-gate char *name;
4837c478bd9Sstevel@tonic-gate {
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate 	if ( (Fp = fopen(PERMISSIONS, "r")) == NULL) {
4867c478bd9Sstevel@tonic-gate 		DEBUG(5, "can't open %s\n", PERMISSIONS);
4877c478bd9Sstevel@tonic-gate 		return(FAIL);
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	for (;;) {
4917c478bd9Sstevel@tonic-gate 	    if (parse_tokens (_Flds, NULL) != 0) {
4927c478bd9Sstevel@tonic-gate 		DEBUG(5, "validateFind (%s) FAIL\n", name);
4937c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
4947c478bd9Sstevel@tonic-gate 		return(FAIL);
4957c478bd9Sstevel@tonic-gate 	    }
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate 	    if (_Flds[U_VALIDATE] == NULL)
4987c478bd9Sstevel@tonic-gate 		continue;
4997c478bd9Sstevel@tonic-gate 	    if (nameMatch(name, _Flds[U_VALIDATE])==SUCCESS) {
5007c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
5017c478bd9Sstevel@tonic-gate 		return (SUCCESS);
5027c478bd9Sstevel@tonic-gate 	    }
5037c478bd9Sstevel@tonic-gate 	}
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate /*
5087c478bd9Sstevel@tonic-gate  * see if name is in an ALIAS option
5097c478bd9Sstevel@tonic-gate  * return:
5107c478bd9Sstevel@tonic-gate  *	NULL -> not found
5117c478bd9Sstevel@tonic-gate  *	otherwise -> machine name
5127c478bd9Sstevel@tonic-gate  */
5137c478bd9Sstevel@tonic-gate char *
5147c478bd9Sstevel@tonic-gate aliasFind(name)
5157c478bd9Sstevel@tonic-gate char *name;
5167c478bd9Sstevel@tonic-gate {
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 	if ( (Fp = fopen(PERMISSIONS, "r")) == NULL) {
5197c478bd9Sstevel@tonic-gate 		DEBUG(5, "can't open %s\n", PERMISSIONS);
5207c478bd9Sstevel@tonic-gate 		return(NULL);
5217c478bd9Sstevel@tonic-gate 	}
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	for (;;) {
5247c478bd9Sstevel@tonic-gate 	    if (parse_tokens (_Flds, NULL) != 0) {
5257c478bd9Sstevel@tonic-gate 		DEBUG(5, "aliasFind (%s) FAIL\n", name);
5267c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
5277c478bd9Sstevel@tonic-gate 		return(NULL);
5287c478bd9Sstevel@tonic-gate 	    }
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	    if (_Flds[U_ALIAS] == NULL)
5317c478bd9Sstevel@tonic-gate 		continue;
5327c478bd9Sstevel@tonic-gate 	    if (nameMatch(name, _Flds[U_ALIAS])==SUCCESS) {
5337c478bd9Sstevel@tonic-gate 		(void) fclose(Fp);
5347c478bd9Sstevel@tonic-gate #ifndef UUCHECK
5357c478bd9Sstevel@tonic-gate 		ASSERT(strchr(_Flds[U_MACHINE], ':') == NULL,
5367c478bd9Sstevel@tonic-gate 		    "PERMISSIONS file: ALIAS is one-to-many:",
5377c478bd9Sstevel@tonic-gate 		    _Flds[U_MACHINE], 0);
5387c478bd9Sstevel@tonic-gate #else /* UUCHECK */
5397c478bd9Sstevel@tonic-gate 		if (strchr(_Flds[U_MACHINE], ':') != NULL) {
5407c478bd9Sstevel@tonic-gate 		    printf(gettext("ALIAS is one-to-many: %s -> %s\n"),
5417c478bd9Sstevel@tonic-gate 			name, _Flds[U_MACHINE]);
5427c478bd9Sstevel@tonic-gate 		    return(NULL);
5437c478bd9Sstevel@tonic-gate 		}
5447c478bd9Sstevel@tonic-gate #endif /* UUCHECK */
5457c478bd9Sstevel@tonic-gate 		return(_Flds[U_MACHINE]);
5467c478bd9Sstevel@tonic-gate 	    }
5477c478bd9Sstevel@tonic-gate 	}
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate  * parse a line in PERMISSIONS and return a vector
5537c478bd9Sstevel@tonic-gate  * of fields (flds)
5547c478bd9Sstevel@tonic-gate  *
5557c478bd9Sstevel@tonic-gate  * return:
5567c478bd9Sstevel@tonic-gate  *	0 - OK
5577c478bd9Sstevel@tonic-gate  *	EOF - at end of file
5587c478bd9Sstevel@tonic-gate  */
5597c478bd9Sstevel@tonic-gate int
5607c478bd9Sstevel@tonic-gate parse_tokens(flds, buf)
5617c478bd9Sstevel@tonic-gate char *flds[];
5627c478bd9Sstevel@tonic-gate char *buf;
5637c478bd9Sstevel@tonic-gate {
564*462be471Sceastha 	int i;
565*462be471Sceastha 	char *p;
5667c478bd9Sstevel@tonic-gate 	struct name_value pair;
5677c478bd9Sstevel@tonic-gate 	static char _line[BUFSIZ];
568*462be471Sceastha 	char *line = buf;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	if (buf == NULL)
5717c478bd9Sstevel@tonic-gate 		line = _line;	/* if no buffer specified, use default */
5727c478bd9Sstevel@tonic-gate 	/* initialize defaults  in case parameter is not specified */
5737c478bd9Sstevel@tonic-gate 	for (i=0;i<NUMFLDS;i++)
5747c478bd9Sstevel@tonic-gate 		flds[i] = NULL;
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	if (getuline(Fp, line) == 0)
5777c478bd9Sstevel@tonic-gate 		return(EOF);
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	for (p=line;p && *p;) {
5807c478bd9Sstevel@tonic-gate 		p = next_token (p, &pair);
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 		for (i=0; i<NUMFLDS; i++) {
5837c478bd9Sstevel@tonic-gate 			if (EQUALS(pair.name, _Kwords[i].kword)) {
5847c478bd9Sstevel@tonic-gate 				flds[i] = pair.value;
5857c478bd9Sstevel@tonic-gate 				break;
5867c478bd9Sstevel@tonic-gate 			}
5877c478bd9Sstevel@tonic-gate 		}
5887c478bd9Sstevel@tonic-gate #ifndef UUCHECK
5897c478bd9Sstevel@tonic-gate 		ASSERT(i<NUMFLDS, "PERMISSIONS file: BAD OPTION--",
5907c478bd9Sstevel@tonic-gate 		    pair.name, NUMFLDS);
5917c478bd9Sstevel@tonic-gate #else /* UUCHECK */
5927c478bd9Sstevel@tonic-gate 		if (i >= NUMFLDS) {
5937c478bd9Sstevel@tonic-gate 			DEBUG(3, "bad option (%s) in PERMISSIONS\n",pair.name);
5947c478bd9Sstevel@tonic-gate 			(void) printf("\n*****************************\n");
5957c478bd9Sstevel@tonic-gate 			(void) printf(gettext("**BAD OPTION in PERMISSIONS file: %s\n"),
5967c478bd9Sstevel@tonic-gate 				pair.name);
5977c478bd9Sstevel@tonic-gate 			(void) printf("*****************************\n");
5987c478bd9Sstevel@tonic-gate 			Uerrors++;
5997c478bd9Sstevel@tonic-gate 			return(0);
6007c478bd9Sstevel@tonic-gate 		}
6017c478bd9Sstevel@tonic-gate #endif /* UUCHECK */
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	}
6047c478bd9Sstevel@tonic-gate 	return(0);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate /*
6087c478bd9Sstevel@tonic-gate  * return a name value pair
6097c478bd9Sstevel@tonic-gate  *	string	-> input pointer
6107c478bd9Sstevel@tonic-gate  *	pair	-> name value pair
6117c478bd9Sstevel@tonic-gate  * return:
6127c478bd9Sstevel@tonic-gate  *	pointer to next character
6137c478bd9Sstevel@tonic-gate  */
6147c478bd9Sstevel@tonic-gate char *
6157c478bd9Sstevel@tonic-gate next_token (string, pair)
616*462be471Sceastha char *string;
6177c478bd9Sstevel@tonic-gate struct name_value *pair;
6187c478bd9Sstevel@tonic-gate {
6197c478bd9Sstevel@tonic-gate 	char	*prev = _uu_setlocale(LC_ALL, "C");
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	while ( (*string) && ((*string == '\t') || (*string == ' ')) )
6227c478bd9Sstevel@tonic-gate 		string++;
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 	pair->name = string;
6257c478bd9Sstevel@tonic-gate 	while ((*string) && (*string != '='))
6267c478bd9Sstevel@tonic-gate 		string++;
6277c478bd9Sstevel@tonic-gate 	if (*string)
6287c478bd9Sstevel@tonic-gate 		*string++ = NULLCHAR;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 	pair->value = string;
6317c478bd9Sstevel@tonic-gate 	while ((*string) && (*string != '\t') && (*string != ' ')
6327c478bd9Sstevel@tonic-gate 	    && (*string != '\n'))
6337c478bd9Sstevel@tonic-gate 		string++;
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 	if (*string)
6367c478bd9Sstevel@tonic-gate 		*string++ = NULLCHAR;
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 	(void) _uu_resetlocale(LC_ALL, prev);
6397c478bd9Sstevel@tonic-gate 	return (string);
6407c478bd9Sstevel@tonic-gate }
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate /*
6437c478bd9Sstevel@tonic-gate  * get a line from the PERMISSIONS
6447c478bd9Sstevel@tonic-gate  * take care of comments (#) in col 1
6457c478bd9Sstevel@tonic-gate  * and continuations (\) in last col
6467c478bd9Sstevel@tonic-gate  * return:
6477c478bd9Sstevel@tonic-gate  *	len of line
6487c478bd9Sstevel@tonic-gate  *	0 -> end of file
6497c478bd9Sstevel@tonic-gate  */
6507c478bd9Sstevel@tonic-gate int
6517c478bd9Sstevel@tonic-gate getuline(fp, line)
6527c478bd9Sstevel@tonic-gate FILE *fp;
6537c478bd9Sstevel@tonic-gate char *line;
6547c478bd9Sstevel@tonic-gate {
655*462be471Sceastha 	char *p, *c;
6567c478bd9Sstevel@tonic-gate 	char buf[BUFSIZ];
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	p = line;
6597c478bd9Sstevel@tonic-gate 	for (;fgets(buf, BUFSIZ, fp) != NULL;) {
6607c478bd9Sstevel@tonic-gate 		/* remove trailing white space */
6617c478bd9Sstevel@tonic-gate 		c = &buf[strlen(buf)-1];
6627c478bd9Sstevel@tonic-gate 		while (c>=buf && (*c == '\n' || *c == '\t' || *c == ' ') )
6637c478bd9Sstevel@tonic-gate 			*c-- = NULLCHAR;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 		if (buf[0] == '#' || buf[0] == '\n' || buf[0] == NULLCHAR)
6667c478bd9Sstevel@tonic-gate 			continue;
6677c478bd9Sstevel@tonic-gate 		(void) strcpy(p, buf);
6687c478bd9Sstevel@tonic-gate 		p += strlen(buf);
6697c478bd9Sstevel@tonic-gate 		if ( *(p-1) == '\\')
6707c478bd9Sstevel@tonic-gate 			p--;
6717c478bd9Sstevel@tonic-gate 		else
6727c478bd9Sstevel@tonic-gate 			break;
6737c478bd9Sstevel@tonic-gate 	}
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	return(p-line);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate #define SMAX	15
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate /*
6827c478bd9Sstevel@tonic-gate  * get the next colon separated argument from the list
6837c478bd9Sstevel@tonic-gate  * return:
6847c478bd9Sstevel@tonic-gate  *	p -> pointer to next arg in string
6857c478bd9Sstevel@tonic-gate  * input:
6867c478bd9Sstevel@tonic-gate  *	str -> pointer to input string
6877c478bd9Sstevel@tonic-gate  * output:
6887c478bd9Sstevel@tonic-gate  *	name -> pointer to arg string
6897c478bd9Sstevel@tonic-gate  */
6907c478bd9Sstevel@tonic-gate char *
6917c478bd9Sstevel@tonic-gate nextarg(str, name)
6927c478bd9Sstevel@tonic-gate char *str, **name;
6937c478bd9Sstevel@tonic-gate {
694*462be471Sceastha 	char *p, *b;
6957c478bd9Sstevel@tonic-gate 	static char buf[SMAX+1];
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	for(b=buf,p=str; *p != ':' && *p && b < buf+SMAX;)
6987c478bd9Sstevel@tonic-gate 		*b++ = *p++;
6997c478bd9Sstevel@tonic-gate 	*b++ = NULLCHAR;
7007c478bd9Sstevel@tonic-gate 	if (*p == ':')
7017c478bd9Sstevel@tonic-gate 		p++;
7027c478bd9Sstevel@tonic-gate 	*name = buf;
7037c478bd9Sstevel@tonic-gate 	return(p);
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate  * check if requesting files is permitted
7087c478bd9Sstevel@tonic-gate  * return
7097c478bd9Sstevel@tonic-gate  *	TRUE -> request permitted
7107c478bd9Sstevel@tonic-gate  *	FALSE -> request denied
7117c478bd9Sstevel@tonic-gate  */
7127c478bd9Sstevel@tonic-gate int
7137c478bd9Sstevel@tonic-gate requestOK()
7147c478bd9Sstevel@tonic-gate {
7157c478bd9Sstevel@tonic-gate 	return(_Request);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate /*
7197c478bd9Sstevel@tonic-gate  * myName - return my name from PERMISSIONS file
7207c478bd9Sstevel@tonic-gate  *	or if not there, from  uucpname()
7217c478bd9Sstevel@tonic-gate  * return: none
7227c478bd9Sstevel@tonic-gate  */
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate void
7257c478bd9Sstevel@tonic-gate myName(name)
7267c478bd9Sstevel@tonic-gate char *name;
7277c478bd9Sstevel@tonic-gate {
7287c478bd9Sstevel@tonic-gate 	if (*_MyName)
7297c478bd9Sstevel@tonic-gate 		strcpy(name, _MyName);
7307c478bd9Sstevel@tonic-gate 	else
7317c478bd9Sstevel@tonic-gate 		uucpname(name);
7327c478bd9Sstevel@tonic-gate 	return;
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate /*
7367c478bd9Sstevel@tonic-gate  * check for callback required for any transaction
7377c478bd9Sstevel@tonic-gate  * return:
7387c478bd9Sstevel@tonic-gate  *	TRUE -> callback required
7397c478bd9Sstevel@tonic-gate  *	FALSE-> callback NOT required
7407c478bd9Sstevel@tonic-gate  */
7417c478bd9Sstevel@tonic-gate int
7427c478bd9Sstevel@tonic-gate callBack()
7437c478bd9Sstevel@tonic-gate {
7447c478bd9Sstevel@tonic-gate 	return(_CallBack);
7457c478bd9Sstevel@tonic-gate }
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate /*
7487c478bd9Sstevel@tonic-gate  * check for callback to send any files from here
7497c478bd9Sstevel@tonic-gate  * This means that the called (SLAVE) system will not switch roles.
7507c478bd9Sstevel@tonic-gate  * return:
7517c478bd9Sstevel@tonic-gate  *	TRUE -> callback requried to send files
7527c478bd9Sstevel@tonic-gate  *	FALSE-> callback NOT required to send files
7537c478bd9Sstevel@tonic-gate  */
7547c478bd9Sstevel@tonic-gate int
7557c478bd9Sstevel@tonic-gate switchRole()
7567c478bd9Sstevel@tonic-gate {
7577c478bd9Sstevel@tonic-gate 	return(_Switch);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate /*
7617c478bd9Sstevel@tonic-gate  * Check to see if command is valid for a specific machine.
7627c478bd9Sstevel@tonic-gate  * The PERMISSIONS file has an option COMMANDS=name1:name2:... for
7637c478bd9Sstevel@tonic-gate  * any machine that does not have the default list which is
7647c478bd9Sstevel@tonic-gate  * rmail
7657c478bd9Sstevel@tonic-gate  * Note that the PERMISSIONS file is read once for each system
7667c478bd9Sstevel@tonic-gate  * at the time the Rmtname is set in xprocess().
7677c478bd9Sstevel@tonic-gate  * Return codes:
7687c478bd9Sstevel@tonic-gate  *	ok: TRUE
7697c478bd9Sstevel@tonic-gate  *	fail: FALSE
7707c478bd9Sstevel@tonic-gate  */
7717c478bd9Sstevel@tonic-gate int
7727c478bd9Sstevel@tonic-gate cmdOK(cmd, fullcmd)
7737c478bd9Sstevel@tonic-gate char	*cmd, *fullcmd;
7747c478bd9Sstevel@tonic-gate {
7757c478bd9Sstevel@tonic-gate 	DEBUG(7, "cmdOK(%s, )\n", cmd);
7767c478bd9Sstevel@tonic-gate 	return(cmdMatch(cmd, fullcmd));
7777c478bd9Sstevel@tonic-gate }
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate /*
7817c478bd9Sstevel@tonic-gate  * check a name against a list
7827c478bd9Sstevel@tonic-gate  * input:
7837c478bd9Sstevel@tonic-gate  *	name	-> name
7847c478bd9Sstevel@tonic-gate  *	list	-> list of names
7857c478bd9Sstevel@tonic-gate  * return:
7867c478bd9Sstevel@tonic-gate  *	TRUE	-> found path
7877c478bd9Sstevel@tonic-gate  *	FALSE	-> not found
7887c478bd9Sstevel@tonic-gate  */
7897c478bd9Sstevel@tonic-gate static int
7907c478bd9Sstevel@tonic-gate listMatch(name, list)
791*462be471Sceastha char *name, *list[];
7927c478bd9Sstevel@tonic-gate {
793*462be471Sceastha     int i;
7947c478bd9Sstevel@tonic-gate     char *temp, *tend;
7957c478bd9Sstevel@tonic-gate     struct stat statbuf;
7967c478bd9Sstevel@tonic-gate     dev_t _dev[MAXPATHS+1];
7977c478bd9Sstevel@tonic-gate     ino_t _ino[MAXPATHS+1];
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate     /* ino set to 0 so stat is only done first time */
8007c478bd9Sstevel@tonic-gate     for (i=0; list[i] != NULL; i++)
8017c478bd9Sstevel@tonic-gate 	_ino[i] = 0;
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate     /* try to match inodes */
8047c478bd9Sstevel@tonic-gate     if ( (temp = strdup(name)) != NULL ) {
8057c478bd9Sstevel@tonic-gate 	for ( tend = temp + strlen(temp) ; *temp; ) {
8067c478bd9Sstevel@tonic-gate 	    if ( stat(temp, &statbuf) == 0 ) {
8077c478bd9Sstevel@tonic-gate 		for (i=0; list[i] != NULL; i++) {
8087c478bd9Sstevel@tonic-gate 		    if ( _ino[i] == 0 ) {
8097c478bd9Sstevel@tonic-gate 			struct stat tempbuf;
8107c478bd9Sstevel@tonic-gate 			if ( stat(list[i], &tempbuf) == 0 ) {
8117c478bd9Sstevel@tonic-gate 			    _dev[i] = tempbuf.st_dev;
8127c478bd9Sstevel@tonic-gate 			    _ino[i] = tempbuf.st_ino;
8137c478bd9Sstevel@tonic-gate 			}
8147c478bd9Sstevel@tonic-gate 		    }
8157c478bd9Sstevel@tonic-gate 		    if ( _dev[i] == statbuf.st_dev
8167c478bd9Sstevel@tonic-gate 		      && _ino[i] == statbuf.st_ino ) {
8177c478bd9Sstevel@tonic-gate 			free(temp);
8187c478bd9Sstevel@tonic-gate 			return(TRUE);
8197c478bd9Sstevel@tonic-gate 		    }
8207c478bd9Sstevel@tonic-gate 		}
8217c478bd9Sstevel@tonic-gate 	    }
8227c478bd9Sstevel@tonic-gate 	    *tend = '\0';
8237c478bd9Sstevel@tonic-gate 	    if ( (tend = strrchr(temp, '/')) == NULL ) {
8247c478bd9Sstevel@tonic-gate 		free(temp);
8257c478bd9Sstevel@tonic-gate 		break;
8267c478bd9Sstevel@tonic-gate 	    } else
8277c478bd9Sstevel@tonic-gate 		*(tend+1) = '\0';
8287c478bd9Sstevel@tonic-gate 	}
8297c478bd9Sstevel@tonic-gate     }
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate     return(FALSE);
8327c478bd9Sstevel@tonic-gate }
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate /*
8367c478bd9Sstevel@tonic-gate  * Check "name" against a BASENAME or full name of _Commands list.
8377c478bd9Sstevel@tonic-gate  * If "name" specifies full path, check full, else check BASENAME.
8387c478bd9Sstevel@tonic-gate  *  e.g. "name" rmail matches list item /usr/bin/rmail
8397c478bd9Sstevel@tonic-gate  * input:
8407c478bd9Sstevel@tonic-gate  *	name	-> name
8417c478bd9Sstevel@tonic-gate  * output:
8427c478bd9Sstevel@tonic-gate  *	fullname -> copy full command name into fullname if
8437c478bd9Sstevel@tonic-gate  *		    a full path was specified in _Commands;
8447c478bd9Sstevel@tonic-gate  *		    if not, put name into fullname.
8457c478bd9Sstevel@tonic-gate  * return:
8467c478bd9Sstevel@tonic-gate  *	TRUE	-> found path
8477c478bd9Sstevel@tonic-gate  *	FALSE	-> not found
8487c478bd9Sstevel@tonic-gate  */
8497c478bd9Sstevel@tonic-gate static int
8507c478bd9Sstevel@tonic-gate cmdMatch(name, fullname)
851*462be471Sceastha char *name;
8527c478bd9Sstevel@tonic-gate char *fullname;
8537c478bd9Sstevel@tonic-gate {
854*462be471Sceastha 	int i;
8557c478bd9Sstevel@tonic-gate 	char *bname;
8567c478bd9Sstevel@tonic-gate 	int allok = FALSE;
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	for (i=0; _Commands[i] != NULL; i++) {
8597c478bd9Sstevel@tonic-gate 		if (EQUALS(_Commands[i], "ALL")) {
8607c478bd9Sstevel@tonic-gate 			/* if ALL specified in the list
8617c478bd9Sstevel@tonic-gate 			 * set allok and continue in case
8627c478bd9Sstevel@tonic-gate 			 * a full path name is specified for the command
8637c478bd9Sstevel@tonic-gate 			 */
8647c478bd9Sstevel@tonic-gate 			allok = TRUE;
8657c478bd9Sstevel@tonic-gate 			continue;
8667c478bd9Sstevel@tonic-gate 		}
8677c478bd9Sstevel@tonic-gate 		if (name[0] != '/')
8687c478bd9Sstevel@tonic-gate 			bname = BASENAME(_Commands[i], '/');
8697c478bd9Sstevel@tonic-gate 		else
8707c478bd9Sstevel@tonic-gate 			bname = _Commands[i];
8717c478bd9Sstevel@tonic-gate 		DEBUG(7, "bname=%s\n", bname);
8727c478bd9Sstevel@tonic-gate 		if (EQUALS(bname, name)) {
8737c478bd9Sstevel@tonic-gate 			(void) strcpy(fullname, _Commands[i]);
8747c478bd9Sstevel@tonic-gate 			return(TRUE);
8757c478bd9Sstevel@tonic-gate 		}
8767c478bd9Sstevel@tonic-gate 	}
8777c478bd9Sstevel@tonic-gate 	if (allok == TRUE) {
8787c478bd9Sstevel@tonic-gate 		/* ALL was specified and the command was not found in list */
8797c478bd9Sstevel@tonic-gate 		(void) strcpy(fullname, name);
8807c478bd9Sstevel@tonic-gate 		return(TRUE);
8817c478bd9Sstevel@tonic-gate 	}
8827c478bd9Sstevel@tonic-gate 	(void) strcpy(fullname, "NuLL");	/* this is a dummy command */
8837c478bd9Sstevel@tonic-gate 	return(FALSE);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate /*
8887c478bd9Sstevel@tonic-gate  * check the paths for this login/machine
8897c478bd9Sstevel@tonic-gate  * input:
8907c478bd9Sstevel@tonic-gate  *	path	pathname
8917c478bd9Sstevel@tonic-gate  *	flag	CK_READ or CK_WRITE
8927c478bd9Sstevel@tonic-gate  * output:
8937c478bd9Sstevel@tonic-gate  *	path	may be modified to canonical form
8947c478bd9Sstevel@tonic-gate  *		(../, ./, // will be interpreted/removed)
8957c478bd9Sstevel@tonic-gate  * returns:
8967c478bd9Sstevel@tonic-gate  *	0		-> success
8977c478bd9Sstevel@tonic-gate  *	FAIL		-> failure - not a valid path for access
8987c478bd9Sstevel@tonic-gate  */
8997c478bd9Sstevel@tonic-gate int
9007c478bd9Sstevel@tonic-gate chkpth(path, flag)
9017c478bd9Sstevel@tonic-gate char *path;
9027c478bd9Sstevel@tonic-gate {
903*462be471Sceastha 	char *s;
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate 	/*
9067c478bd9Sstevel@tonic-gate 	 * this is probably redundant,
9077c478bd9Sstevel@tonic-gate 	 * because expfile did it, but that's ok
9087c478bd9Sstevel@tonic-gate 	 * Note - the /../ check is not required because of canPath
9097c478bd9Sstevel@tonic-gate 	 */
9107c478bd9Sstevel@tonic-gate 	if (canPath(path) == FAIL)
9117c478bd9Sstevel@tonic-gate 		return(FAIL);
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	if (flag == CK_READ)
9147c478bd9Sstevel@tonic-gate 		if (listMatch(path, _RPaths)
9157c478bd9Sstevel@tonic-gate 		&& !listMatch(path, _NoRPaths))
9167c478bd9Sstevel@tonic-gate 			return(0);
9177c478bd9Sstevel@tonic-gate 	if (flag == CK_WRITE)
9187c478bd9Sstevel@tonic-gate 		if (listMatch(path, _WPaths)
9197c478bd9Sstevel@tonic-gate 		&& !listMatch(path, _NoWPaths))
9207c478bd9Sstevel@tonic-gate 			return(0);
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 	/* ok if uucp generated D. or X. name for the spool directory */
9247c478bd9Sstevel@tonic-gate 	if (PREFIX(RemSpool, path) ) {
9257c478bd9Sstevel@tonic-gate     		s = &path[strlen(RemSpool)];
9267c478bd9Sstevel@tonic-gate 		if ( (*s++ == '/')
9277c478bd9Sstevel@tonic-gate 		  && (*s == DATAPRE || *s == XQTPRE)
9287c478bd9Sstevel@tonic-gate 		  && (*(++s) == '.')
9297c478bd9Sstevel@tonic-gate 		  && (strchr(s, '/') == NULL) )
9307c478bd9Sstevel@tonic-gate 			return(0);
9317c478bd9Sstevel@tonic-gate 	}
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 	/*  path name not valid */
9347c478bd9Sstevel@tonic-gate 	return(FAIL);
9357c478bd9Sstevel@tonic-gate }
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate /*
9387c478bd9Sstevel@tonic-gate  * check write permission of file.
9397c478bd9Sstevel@tonic-gate  * if mopt != NULL and permissions are ok,
9407c478bd9Sstevel@tonic-gate  * a side effect of this routine is to make
9417c478bd9Sstevel@tonic-gate  * directories up to the last part of the
9427c478bd9Sstevel@tonic-gate  * "to" ( if they do not exit).
9437c478bd9Sstevel@tonic-gate  * Input:
9447c478bd9Sstevel@tonic-gate  *	to - a path name of the destination file or directory
9457c478bd9Sstevel@tonic-gate  *	from - full path name of source file
9467c478bd9Sstevel@tonic-gate  *	opt - create directory option (NULL - don't create)
9477c478bd9Sstevel@tonic-gate  * Output:
9487c478bd9Sstevel@tonic-gate  *	to - will be the full path name of the destination file
9497c478bd9Sstevel@tonic-gate  * returns:
9507c478bd9Sstevel@tonic-gate  *	0	->success
9517c478bd9Sstevel@tonic-gate  *	FAIL	-> failure
9527c478bd9Sstevel@tonic-gate  */
9537c478bd9Sstevel@tonic-gate int
9547c478bd9Sstevel@tonic-gate chkperm(from, to, opt)
9557c478bd9Sstevel@tonic-gate char *from, *to, *opt;
9567c478bd9Sstevel@tonic-gate {
957*462be471Sceastha 	char *lxp, *p;
9587c478bd9Sstevel@tonic-gate 	struct stat s;
9597c478bd9Sstevel@tonic-gate 	char dir[MAXFULLNAME];
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	if (*(p = LASTCHAR(to)) == '/') {
9627c478bd9Sstevel@tonic-gate 	    if (strlcpy(p+1, BASENAME(from, '/'), MAXFULLNAME - strlen(to)) >=
9637c478bd9Sstevel@tonic-gate 		MAXFULLNAME - strlen(to)) {
9647c478bd9Sstevel@tonic-gate 		    return(FAIL);
9657c478bd9Sstevel@tonic-gate 	    }
9667c478bd9Sstevel@tonic-gate 	} else if (DIRECTORY(to)) {
9677c478bd9Sstevel@tonic-gate 	    *++p = '/';
9687c478bd9Sstevel@tonic-gate 	    if (strlcpy(p+1, BASENAME(from, '/'), MAXFULLNAME - strlen(to)) >=
9697c478bd9Sstevel@tonic-gate 		MAXFULLNAME - strlen(to)) {
9707c478bd9Sstevel@tonic-gate 		    return(FAIL);
9717c478bd9Sstevel@tonic-gate 	    }
9727c478bd9Sstevel@tonic-gate 	}
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	/* to is now the full path name of the destination file */
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	if (WRITEANY(to))
9777c478bd9Sstevel@tonic-gate 	    return(0);
9787c478bd9Sstevel@tonic-gate 	if (stat(to, &s) == 0)
9797c478bd9Sstevel@tonic-gate 	    return(FAIL);	/* file exists, but not writeable */
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 	/* file does not exist--check directory and make when necessary */
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 	(void) strcpy(dir, to);
9847c478bd9Sstevel@tonic-gate 	if ( (lxp=strrchr(dir, '/')) == NULL)
9857c478bd9Sstevel@tonic-gate 	    return(FAIL);	/* no directory part of name */
9867c478bd9Sstevel@tonic-gate 	if (lxp == dir)	/* at root */
9877c478bd9Sstevel@tonic-gate 	    lxp++;
9887c478bd9Sstevel@tonic-gate 	*lxp = NULLCHAR;
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	/* should check WRITEANY on parent before mkdirs() */
9917c478bd9Sstevel@tonic-gate 	if (!DIRECTORY(dir)) {
9927c478bd9Sstevel@tonic-gate 	    if (opt == NULL)
9937c478bd9Sstevel@tonic-gate 		return(FAIL);	/* no directory and no opt to make them */
9947c478bd9Sstevel@tonic-gate 	    else if (mkdirs(dir, PUBMASK) == FAIL)
9957c478bd9Sstevel@tonic-gate 		return(FAIL);
9967c478bd9Sstevel@tonic-gate 	}
9977c478bd9Sstevel@tonic-gate 
9987c478bd9Sstevel@tonic-gate 	/* the directory now exists--check for writability */
9997c478bd9Sstevel@tonic-gate 	if (EQUALS(RemSpool, dir) || WRITEANY(dir))
10007c478bd9Sstevel@tonic-gate 	    return(0);
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 	return(FAIL);
10037c478bd9Sstevel@tonic-gate }
1004