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