#include "uucp.h" #include #include #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)); }