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