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