Research V7 release
[unix-history] / usr / src / cmd / uucp / chkpth.c
#include "uucp.h"
#include <sys/types.h>
#include <sys/stat.h>
#define DFLTNAME "default"
#define MAXUSERS 20
struct userpath {
char *us_lname;
char *us_mname;
char us_callback;
char **us_path;
};
struct userpath Upt[15];
struct userpath *Mchdef = NULL, *Logdef = NULL;
int Nbrusers = 0;
int Uptfirst = 1;
/*******
* chkpth(logname, mchname, path)
* char *path, *logname, *mchname;
*
* chkpth - this routine will check the path table for the
* machine or log name (non-null parameter) to see if the
* input path (path)
* starts with an acceptable prefix.
*
* return codes: 0 | FAIL
*/
chkpth(logname, mchname, path)
char *path, *logname, *mchname;
{
struct userpath *u;
extern char *lastpart();
char **p, *s;
char c;
int ret, i;
if (prefix(THISDIR, path))
return(FAIL);
if (Uptfirst) {
ret = rdpth(Upt);
ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);
Uptfirst = 0;
}
for (u = Upt, i = 0; i < Nbrusers; i++, u++) {
if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME)
break;
if (*mchname != '\0' && strcmp(mchname, u->us_mname) == SAME)
break;
}
if (i >= Nbrusers) {
if (*logname == '\0')
u = Mchdef;
else
u = Logdef;
if (u == NULL)
return(FAIL);
}
/* found user name */
p = u->us_path;
/* check for /../ in path name */
for (s = path; *s != '\0'; s++) {
if (*s == '/' && prefix("../", (++s)))
return(FAIL);
}
if (chklnk(path) > LINKLEVEL)
return(FAIL);
for (p = u->us_path; *p != NULL; p++)
if (prefix(*p, path))
return(0);
if (prefix(Spool, path)) {
if ((c = *lastpart(path)) == DATAPRE
|| c == XQTPRE)
return(0);
}
/* path name not valid */
return(FAIL);
}
/***
* rdpth(u)
* struct userpath *u;
*
* rdpth - this routine will read the USFILE and
* construct the userpath structure pointed to by (u);
*
* return codes: 0 | FAIL
*/
rdpth(u)
struct userpath *u;
{
char buf[BUFSIZ + 1], *pbuf[BUFSIZ + 1], *pc, **cp;
extern char *calloc(), *index();
FILE *uf;
if ((uf = fopen(USERFILE, "r")) == NULL) {
/* can not open file */
return(FAIL);
}
while (fgets(buf, BUFSIZ, uf) != NULL) {
int nargs, i;
if (++Nbrusers > MAXUSERS) {
fclose(uf);
return(FAIL);
}
if ((pc = calloc(strlen(buf) + 1, sizeof (char)))
== NULL) {
/* can not allocate space */
fclose(uf);
return(FAIL);
}
strcpy(pc, buf);
nargs = getargs(pc, pbuf);
u->us_lname = pbuf[0];
pc = index(u->us_lname, ',');
if (pc != NULL)
*pc++ = '\0';
else
pc = u + strlen(u->us_lname);
u->us_mname = pc;
if (*u->us_lname == '\0')
Logdef = u;
else if (*u->us_mname == '\0')
Mchdef = u;
i = 1;
if (strcmp(pbuf[1], "c") == SAME) {
u->us_callback = 1;
i++;
}
else
u->us_callback = 0;
if ((cp = u->us_path =
calloc(nargs - i + 1, sizeof (char *))) == NULL) {
/* can not allocate space */
fclose(uf);
return(FAIL);
}
while (i < nargs)
*cp++ = pbuf[i++];
*cp = NULL;
u++;
}
fclose(uf);
return(0);
}
/***
* callback(name) check for callback
* char *name;
*
* return codes:
* 0 - no call back
* 1 - call back
*/
callback(name)
char *name;
{
struct userpath *u;
int ret, i;
if (Uptfirst) {
ret = rdpth(Upt);
ASSERT(ret == 0, "INIT USERFILE %d", Nbrusers);
Uptfirst = 0;
}
for (u = Upt, i = 0; i < Nbrusers; u++, i++) {
if (strcmp(u->us_lname, name) != SAME)
continue;
/* found user name */
return(u->us_callback);
}
/* userid not found */
return(0);
}
/***
* chklnk(name) get number of links
* char *name;
*
* return codes: 0 - stat failed or directory | number of links
*/
chklnk(name)
char *name;
{
struct stat s;
if (stat(name, &s) == -1)
return(0);
if ((s.st_mode & S_IFMT) == S_IFDIR)
return(0);
return(s.st_nlinks);
}
/***
* chkperm(file, user, mopt) check write permission of file
* char *file, *user;
* char *mopt; none NULL - create directories
*
* if mopt != NULL and permissions are ok,
* a side effect of this routine is to make
* directories up to the last part of the
* filename (if they do not exist).
*
* return 0 | FAIL
*/
chkperm(file, user, mopt)
char *file, *user, *mopt;
{
struct stat s;
int ret, bits;
char dir[MAXFULLNAME];
extern char *lastpart();
if (stat(file, &s) != -1)
return(0);
strcpy(dir, file);
*lastpart(dir) = '\0';
if ((ret = stat(dir, &s)) == -1
&& mopt == NULL)
return(FAIL);
bits = (geteuid() == 0) ? 02 : 0200;
if (ret != -1) {
if ((s.st_mode & bits) == 0)
return(FAIL);
else
return(0);
}
/* make directories */
return(mkdirs(file));
}