1 #ifndef lint 2 static char sccsid[] = "@(#)chkpth.c 5.3 (Berkeley) 04/10/85"; 3 #endif 4 5 #include "uucp.h" 6 #include <sys/stat.h> 7 8 struct userpath { 9 char *us_lname; 10 char *us_mname; 11 char us_callback; 12 char **us_path; 13 struct userpath *unext; 14 }; 15 struct userpath *Uhead = NULL; 16 struct userpath *Mchdef = NULL, *Logdef = NULL; 17 int Uptfirst = 1; 18 19 /******* 20 * chkpth(logname, mchname, path) 21 * char *path, *logname, *mchname; 22 * 23 * chkpth - this routine will check the path table for the 24 * machine or log name (non-null parameter) to see if the 25 * input path (path) 26 * starts with an acceptable prefix. 27 * 28 * return codes: 0 | FAIL 29 */ 30 31 chkpth(logname, mchname, path) 32 char *path, *logname, *mchname; 33 { 34 register struct userpath *u; 35 extern char *lastpart(); 36 register char **p, *s; 37 38 /* Allow only rooted pathnames. Security wish. rti!trt */ 39 if (*path != '/') { 40 DEBUG(4, "filename doesn't begin with /\n", CNULL); 41 return FAIL; 42 } 43 44 if (Uptfirst) { 45 rdpth(); 46 ASSERT(Uhead != NULL, "INIT USERFILE, No entrys!", CNULL, 0); 47 Uptfirst = 0; 48 } 49 for (u = Uhead; u != NULL; ) { 50 if (*logname != '\0' && strcmp(logname, u->us_lname) == SAME) 51 break; 52 if (*mchname != '\0' && strncmp(mchname, u->us_mname, 7) == SAME) 53 break; 54 u = u->unext; 55 } 56 if (u == NULL) { 57 if (*logname == '\0') 58 u = Mchdef; 59 else 60 u = Logdef; 61 if (u == NULL) 62 return FAIL; 63 } 64 65 /* check for /../ in path name */ 66 for (s = path; *s != '\0'; s++) { 67 if (prefix("/../",s)) { 68 DEBUG(4, "filename has /../ in it\n", CNULL); 69 return FAIL; 70 } 71 } 72 73 /* Check for access permission */ 74 for (p = u->us_path; *p != NULL; p++) 75 if (prefix(*p, path)) 76 return SUCCESS; 77 DEBUG(4, "filename not in list\n", CNULL); 78 79 /* path name not valid */ 80 return FAIL; 81 } 82 83 84 /*** 85 * rdpth() 86 * 87 * rdpth - this routine will read the USERFILE and 88 * construct the userpath structure pointed to by (u); 89 * 90 */ 91 92 rdpth() 93 { 94 char buf[100 + 1], *pbuf[50 + 1]; 95 register struct userpath *u; 96 register char *pc, **cp; 97 FILE *uf; 98 99 if ((uf = fopen(USERFILE, "r")) == NULL) { 100 /* can not open file */ 101 return; 102 } 103 104 while (cfgets(buf, sizeof(buf), uf) != NULL) { 105 int nargs, i; 106 107 u = (struct userpath *)malloc(sizeof (struct userpath)); 108 if (u == NULL) { 109 DEBUG (1, "*** Userpath malloc failed\n", 0); 110 fclose (uf); 111 return; 112 } 113 if ((pc = calloc((unsigned)strlen(buf) + 1, sizeof (char))) 114 == NULL) { 115 /* can not allocate space */ 116 DEBUG (1, "Userpath calloc 1 failed\n", 0); 117 fclose(uf); 118 return; 119 } 120 121 strcpy(pc, buf); 122 nargs = getargs(pc, pbuf, 50); 123 u->us_lname = pbuf[0]; 124 pc = index(u->us_lname, ','); 125 if (pc != NULL) 126 *pc++ = '\0'; 127 else 128 pc = u->us_lname + strlen(u->us_lname); 129 u->us_mname = pc; 130 if (strlen(u->us_mname) > 7) 131 u->us_mname[7] = '\0'; 132 if (*u->us_lname == '\0' && Logdef == NULL) 133 Logdef = u; 134 if (*u->us_mname == '\0' && Mchdef == NULL) 135 Mchdef = u; 136 i = 1; 137 if (strcmp(pbuf[1], "c") == SAME) { 138 u->us_callback = 1; 139 i++; 140 } 141 else 142 u->us_callback = 0; 143 cp = (char **)calloc((unsigned)(nargs-i+1), sizeof(char *)); 144 if (cp == NULL) { 145 /* can not allocate space */ 146 DEBUG (1, "Userpath calloc 2 failed!\n", 0); 147 fclose(uf); 148 return; 149 } 150 u->us_path = cp; 151 152 while (i < nargs) 153 *cp++ = pbuf[i++]; 154 *cp = NULL; 155 u->unext = Uhead; 156 Uhead = u; 157 } 158 159 fclose(uf); 160 return; 161 } 162 163 /*** 164 * callback(name) check for callback 165 * char *name; 166 * 167 * return codes: 168 * 0 - no call back 169 * 1 - call back 170 */ 171 172 callback(name) 173 register char *name; 174 { 175 register struct userpath *u; 176 177 if (Uptfirst) { 178 rdpth(); 179 ASSERT(Uhead != NULL, "INIT USERFILE, No Users!", CNULL, 0); 180 Uptfirst = 0; 181 } 182 183 for (u = Uhead; u != NULL; ) { 184 if (strcmp(u->us_lname, name) == SAME) 185 /* found user name */ 186 return u->us_callback; 187 u = u->unext; 188 } 189 190 /* userid not found */ 191 return 0; 192 } 193 194 195 /*** 196 * chkperm(file, mopt) check write permission of file 197 * char *mopt; none NULL - create directories 198 * 199 * if mopt != NULL and permissions are ok, 200 * a side effect of this routine is to make 201 * directories up to the last part of the 202 * filename (if they do not exist). 203 * 204 * return SUCCESS | FAIL 205 */ 206 207 chkperm(file, mopt) 208 char *file, *mopt; 209 { 210 struct stat s; 211 int ret; 212 char dir[MAXFULLNAME]; 213 extern char *lastpart(); 214 215 if (stat(subfile(file), &s) == 0) { 216 if ((s.st_mode & ANYWRITE) == 0) { 217 DEBUG(4,"file is not writable: mode %o\n", s.st_mode); 218 return FAIL; 219 } 220 return SUCCESS; 221 } 222 223 strcpy(dir, file); 224 *lastpart(dir) = '\0'; 225 if ((ret = stat(subfile(dir), &s)) == -1 && mopt == NULL) { 226 DEBUG(4, "can't stat directory %s\n", subfile(dir)); 227 return FAIL; 228 } 229 230 if (ret != -1) { 231 if ((s.st_mode & ANYWRITE) == 0) 232 return FAIL; 233 else 234 return SUCCESS; 235 } 236 237 /* make directories */ 238 return mkdirs(file); 239 } 240 241 /* 242 * Check for sufficient privilege to request debugging. 243 */ 244 chkdebug() 245 { 246 if (access(SYSFILE, 04) < 0) { 247 fprintf(stderr, "Sorry, you must be able to read L.sys for debugging\n"); 248 cleanup(1); 249 exit(1); /* Just in case */ 250 } 251 } 252