|
|
1.1 ! root 1: /* /sccs/src/cmd/uucp/s.permission.c ! 2: permission.c 1.3 8/30/84 17:37:34 ! 3: */ ! 4: #ifndef UUCHECK ! 5: #include "uucp.h" ! 6: VERSION(@(#)permission.c 1.3); ! 7: #endif ! 8: ! 9: ! 10: /* field array indexes for PERMISSIONS parameters */ ! 11: #define U_LOGNAME 0 ! 12: #define U_MACHINE 1 ! 13: #define U_CALLBACK 2 ! 14: #define U_REQUEST 3 ! 15: #define U_SENDFILES 4 ! 16: #define U_READPATH 5 ! 17: #define U_WRITEPATH 6 ! 18: #define U_NOREADPATH 7 ! 19: #define U_NOWRITEPATH 8 ! 20: #define U_MYNAME 9 ! 21: #define U_COMMANDS 10 ! 22: #define U_VALIDATE 11 ! 23: #define U_PUBDIR 12 ! 24: /* NUMFLDS should be one more than the highest U_ value */ ! 25: #define NUMFLDS 13 ! 26: ! 27: /* fields found in PERMISSIONS for requested system/login */ ! 28: static char *_Flds[NUMFLDS]; ! 29: ! 30: /* keyword/value structure */ ! 31: struct keywords { ! 32: char* kword; ! 33: int kvalue; ! 34: }; ! 35: static struct keywords _Kwords[] = { ! 36: {"LOGNAME", U_LOGNAME}, ! 37: {"MACHINE", U_MACHINE}, ! 38: {"CALLBACK", U_CALLBACK}, ! 39: {"REQUEST", U_REQUEST}, ! 40: {"SENDFILES", U_SENDFILES}, ! 41: {"READ", U_READPATH}, ! 42: {"WRITE", U_WRITEPATH}, ! 43: {"NOREAD", U_NOREADPATH}, ! 44: {"NOWRITE", U_NOWRITEPATH}, ! 45: {"MYNAME", U_MYNAME}, ! 46: {"COMMANDS", U_COMMANDS}, ! 47: {"VALIDATE", U_VALIDATE}, ! 48: {"PUBDIR", U_PUBDIR}, ! 49: }; ! 50: ! 51: #define MAXCMDS 30 ! 52: #define MAXPATHS 20 ! 53: ! 54: /* for all options on paths - read, write, noread, nowrite */ ! 55: static char *_RPaths[MAXPATHS+1]; ! 56: static char *_WPaths[MAXPATHS+1]; ! 57: static char *_NoRPaths[MAXPATHS+1]; ! 58: static char *_NoWPaths[MAXPATHS+1]; ! 59: static char *_Commands[MAXCMDS+1]; ! 60: static char _Cmd_defaults[BUFSIZ]; ! 61: ! 62: /* option variables */ ! 63: static int _Request; /* TRUE can request, FALSE can not request files */ ! 64: static int _Switch; /* FALSE requires a call back to send any files */ ! 65: static int _CallBack; /* TRUE for call back for any transaction */ ! 66: static char _MyName[MAXBASENAME+1]; /* Myname from PERMISSIONS file */ ! 67: static char *_Pubdir = NULL; /* PUBDIR from PERMISSIONS file */ ! 68: ! 69: struct name_value ! 70: { ! 71: char *name; ! 72: char *value; ! 73: }; ! 74: ! 75: /* file pointer for PERMISSIONS */ ! 76: static FILE *Fp = NULL; ! 77: ! 78: /* functions */ ! 79: static char *next_token(), *nextarg(); ! 80: static void fillFlds(); ! 81: static int fillList(); ! 82: ! 83: /* ! 84: * fill in fields for login name ! 85: * name - the login id ! 86: * rmtname - remote system name ! 87: * ! 88: * return: ! 89: * 0 -> found login name ! 90: * FAIL -> did not find login ! 91: */ ! 92: ! 93: logFind(name, rmtname) ! 94: char *name, *rmtname; ! 95: { ! 96: int ret; ! 97: DEBUG(5, "logFind called (name: %s, ", name); ! 98: DEBUG(5, "rmtname: %s)\n", rmtname); ! 99: ! 100: ret = validateFind (rmtname); ! 101: if (ret == SUCCESS) { /* found VALIDATE entry */ ! 102: ret = userFind (name, rmtname, U_VALIDATE); ! 103: if (ret) { ! 104: DEBUG(5, "machine/login match failed", ""); ! 105: return(FAIL); ! 106: } ! 107: } ! 108: else ! 109: ret = userFind (name, "", U_LOGNAME); ! 110: ! 111: DEBUG(7, "_Request (%s), ", ! 112: requestOK() ? "TRUE" : "FALSE"); ! 113: DEBUG(7, "_Switch (%s), ", ! 114: switchRole() ? "TRUE" : "FALSE"); ! 115: DEBUG(7, "_CallBack (%s), ", ! 116: callBack() ? "TRUE" : "FALSE"); ! 117: DEBUG(7, "_MyName (%s), ", _MyName); ! 118: return(ret); ! 119: } ! 120: ! 121: /* ! 122: * fill in fields for machine name ! 123: * return: ! 124: * 0 -> found machine name ! 125: * FAIL -> did not find machine ! 126: */ ! 127: ! 128: mchFind(name) ! 129: char *name; ! 130: { ! 131: register i, ret; ! 132: DEBUG(5, "mchFind called (%s)\n", name); ! 133: if ( (ret = userFind (name, "", U_MACHINE)) == FAIL) ! 134: /* see if there is a default line */ ! 135: (void) userFind ("OTHER", "", U_MACHINE); ! 136: ! 137: /* mchFind is from MASTER mode - switch role is always ok */ ! 138: _Switch = TRUE; ! 139: ! 140: DEBUG(7, "_Request (%s), ", ! 141: requestOK() ? "TRUE" : "FALSE"); ! 142: DEBUG(7, "_Switch (%s), ", ! 143: switchRole() ? "TRUE" : "FALSE"); ! 144: DEBUG(7, "_CallBack (%s), ", ! 145: callBack() ? "TRUE" : "FALSE"); ! 146: DEBUG(7, "_MyName (%s), ", _MyName); ! 147: for (i=0; _Commands[i] != NULL; i++) ! 148: DEBUG(7, "_Commands %s\n", _Commands[i]); ! 149: return(ret); ! 150: } ! 151: ! 152: /* ! 153: * this function will find a login name in the LOGNAME ! 154: * field. ! 155: * input: ! 156: * name -> who the remote says he/she is ! 157: * return: ! 158: * SUCCESS -> found ! 159: * FAIL -> not found ! 160: */ ! 161: static ! 162: int ! 163: nameMatch(name, fld) ! 164: char *name, *fld; ! 165: { ! 166: char *arg; ! 167: ! 168: if (fld == NULL) ! 169: return(FAIL); ! 170: ! 171: while (*fld) { ! 172: fld = nextarg(fld, &arg); ! 173: if (EQUALS(arg, name)) ! 174: return(SUCCESS); ! 175: } ! 176: return (FAIL); ! 177: } ! 178: ! 179: ! 180: /* ! 181: * interpret the _Flds options and set the option variables ! 182: */ ! 183: static ! 184: void ! 185: fillFlds() ! 186: { ! 187: ! 188: if (EQUALS(_Flds[U_REQUEST], "yes")) ! 189: _Request = TRUE; ! 190: else ! 191: _Request = FALSE; ! 192: ! 193: if (EQUALS(_Flds[U_SENDFILES], "yes")) ! 194: _Switch = TRUE; ! 195: else ! 196: _Switch = FALSE; ! 197: ! 198: if (EQUALS(_Flds[U_CALLBACK], "yes")) ! 199: _CallBack = TRUE; ! 200: else ! 201: _CallBack = FALSE; ! 202: ! 203: if (_Flds[U_MYNAME] != NULL) { ! 204: strncpy(_MyName, _Flds[U_MYNAME], MAXBASENAME); ! 205: _MyName[MAXBASENAME] = NULLCHAR; ! 206: } ! 207: else ! 208: *_MyName = NULLCHAR; ! 209: ! 210: if (_Flds[U_PUBDIR] != NULL) { ! 211: if (_Pubdir != NULL) ! 212: free(_Pubdir); /* get rid of previous one */ ! 213: _Pubdir = malloc(strlen(_Flds[U_PUBDIR])+1); ! 214: #ifndef UUCHECK ! 215: ASSERT(_Pubdir != NULL, Ct_ALLOCATE, _Flds[U_PUBDIR], 0); ! 216: #else ! 217: if (_Pubdir == NULL) { ! 218: (void) fprintf(stderr, "malloc() error\n"); ! 219: exit(1); ! 220: } ! 221: #endif ! 222: strcpy(_Pubdir, _Flds[U_PUBDIR]); ! 223: Pubdir = _RPaths[0] = _WPaths[0] = _Pubdir; /* reset default */ ! 224: } ! 225: else ! 226: Pubdir = PUBDIR; ! 227: ! 228: return; ! 229: } ! 230: ! 231: /* ! 232: * fill in the list vector for the system/login ! 233: * input: ! 234: * type - list type (read, write, noread, nowrite, command) ! 235: * output: ! 236: * list - filled in with items. ! 237: * return: ! 238: * number of items in list ! 239: */ ! 240: static ! 241: fillList(type, list) ! 242: int type; ! 243: char *list[]; ! 244: { ! 245: register char *p; ! 246: register num; ! 247: int maxlist = 0; ! 248: ! 249: p = _Flds[type]; ! 250: ! 251: /* find list limit */ ! 252: if (type == U_READPATH || type == U_WRITEPATH ! 253: || type == U_NOREADPATH || type == U_NOWRITEPATH) ! 254: maxlist = MAXPATHS; ! 255: else if (type == U_COMMANDS) ! 256: maxlist = MAXCMDS; ! 257: ! 258: if (p == NULL || !*p) { ! 259: /* no names specified, default already setup */ ! 260: return(0); ! 261: } ! 262: ! 263: num = 0; ! 264: while (*p && num < maxlist) { ! 265: list[num] = p; ! 266: if (*p == ':') { /* null path */ ! 267: *p++ = NULLCHAR; ! 268: continue; ! 269: } ! 270: while (*p && *p != ':') ! 271: p++; ! 272: if (*p == ':') ! 273: *p++ = NULLCHAR; ! 274: DEBUG(7, "list (%s) ", list[num]); ! 275: num++; ! 276: } ! 277: DEBUG(7, "num = %d\n", num); ! 278: list[num] = NULL; ! 279: return(num); ! 280: } ! 281: ! 282: /* ! 283: * Find the line of PERMISSIONS for login. ! 284: * The search is determined by the type field ! 285: * (type=U_LOGNAME, U_MACHINE or U_VALIDATE) ! 286: * For U_LOGNAME: ! 287: * search for "name" in a LOGNAME= option ! 288: * For U_MACHINE: ! 289: * search for "name" in a MACHINE= option ! 290: * For U_VALIDATE: ! 291: * search for "rmtname" in a VALIDATE= option and ! 292: * for the same entry see if "name" is in the LOGNAME= option ! 293: * input: ! 294: * name -> search name ! 295: * logname -> for validate entry ! 296: * type -> U_MACHINE or U_LOGNAME ! 297: * output: ! 298: * The global values of all options will be set ! 299: * (e.g. _RPaths, _WPaths, _Request, ...) ! 300: * return: ! 301: * 0 -> ok ! 302: * FAIL -> no match found ! 303: */ ! 304: static ! 305: userFind(name, rmtname, type) ! 306: char *name, *rmtname; ! 307: int type; ! 308: { ! 309: char *p, *arg; ! 310: ! 311: /* initialize permission variables in case line is not found */ ! 312: _Request = FALSE; ! 313: _CallBack = FALSE; ! 314: _Switch = FALSE; ! 315: _MyName[0] = NULLCHAR; ! 316: _RPaths[0] = _WPaths[0] = PUBDIR; /* default is public */ ! 317: _RPaths[1] = _WPaths[1] = NULLCHAR; ! 318: /* set up Commands defaults */ ! 319: _Flds[U_COMMANDS] = strcpy(_Cmd_defaults, DEFAULTCMDS); ! 320: fillList(U_COMMANDS, _Commands); ! 321: ! 322: if (name == NULL) /* use defaults */ ! 323: return(0); /* I don't think this will ever happen */ ! 324: ! 325: if ( (Fp = fopen(PFILE, "r")) == NULL) { ! 326: DEBUG(5, "can't open %s\n", PFILE); ! 327: return(FAIL); ! 328: } ! 329: ! 330: for (;;) { ! 331: if (parse_tokens (_Flds) != 0) { ! 332: (void) fclose(Fp); ! 333: DEBUG(5, "name (%s) not found; return FAIL\n", name); ! 334: return(FAIL); ! 335: } ! 336: ! 337: p = _Flds[type]; ! 338: while (p && *p) { ! 339: p = nextarg(p, &arg); ! 340: switch (type) { ! 341: case U_VALIDATE: ! 342: if (EQUALS(arg, rmtname) ! 343: && nameMatch(name, _Flds[U_LOGNAME])==SUCCESS) ! 344: break; ! 345: continue; ! 346: ! 347: case U_LOGNAME: ! 348: if (EQUALS(arg, name)) ! 349: break; ! 350: continue; ! 351: ! 352: case U_MACHINE: ! 353: if (EQUALSN(arg, name, SYSNSIZE)) ! 354: break; ! 355: continue; ! 356: } ! 357: ! 358: (void) fclose(Fp); ! 359: fillFlds(); ! 360: ! 361: /* fill in path lists */ ! 362: fillList(U_READPATH, _RPaths); ! 363: fillList(U_WRITEPATH, _WPaths); ! 364: if (!requestOK()) ! 365: _Flds[U_NOREADPATH] = "/"; ! 366: fillList(U_NOREADPATH, _NoRPaths); ! 367: fillList(U_NOWRITEPATH, _NoWPaths); ! 368: ! 369: /* fill in command list */ ! 370: fillList(U_COMMANDS, _Commands); ! 371: ! 372: return(0); ! 373: } ! 374: } ! 375: } ! 376: ! 377: /* ! 378: * see if name is in a VALIDATE option ! 379: * return: ! 380: * FAIL -> not found ! 381: * SUCCESS -> found ! 382: */ ! 383: static ! 384: int ! 385: validateFind(name) ! 386: char *name; ! 387: { ! 388: ! 389: if ( (Fp = fopen(PFILE, "r")) == NULL) { ! 390: DEBUG(5, "can't open %s\n", PFILE); ! 391: return(FAIL); ! 392: } ! 393: ! 394: for (;;) { ! 395: if (parse_tokens (_Flds) != 0) { ! 396: DEBUG(5, "validateFind (%s) FAIL\n", name); ! 397: (void) fclose(Fp); ! 398: return(FAIL); ! 399: } ! 400: ! 401: if (_Flds[U_VALIDATE] == NULL) ! 402: continue; ! 403: if (nameMatch(name, _Flds[U_VALIDATE])==SUCCESS) { ! 404: (void) fclose(Fp); ! 405: return (SUCCESS); ! 406: } ! 407: } ! 408: ! 409: } ! 410: ! 411: ! 412: /* ! 413: * parse a line in PERMISSIONS and return a vector ! 414: * of fields (flds) ! 415: * ! 416: * return: ! 417: * 0 - OK ! 418: * EOF - at end of file ! 419: */ ! 420: parse_tokens (flds) ! 421: char *flds[]; ! 422: { ! 423: register i; ! 424: register char *p; ! 425: struct name_value pair; ! 426: static char line[BUFSIZ]; ! 427: ! 428: /* initialize defaults in case parameter is not specified */ ! 429: for (i=0;i<NUMFLDS;i++) ! 430: flds[i] = NULL; ! 431: ! 432: if (getuline(line) == 0) ! 433: return(EOF); ! 434: ! 435: for (p=line;p && *p;) { ! 436: p = next_token (p, &pair); ! 437: ! 438: for (i=0; i<NUMFLDS; i++) { ! 439: if (EQUALS(pair.name, _Kwords[i].kword)) { ! 440: flds[i] = pair.value; ! 441: break; ! 442: } ! 443: } ! 444: #ifndef UUCHECK ! 445: ASSERT(i<NUMFLDS, "PERMISSIONS file: BAD OPTION--", ! 446: pair.name, NUMFLDS); ! 447: #else ! 448: if (i >= NUMFLDS) { ! 449: DEBUG(3, "bad option (%s) in PERMISSIONS\n",pair.name); ! 450: (void) printf("\n*****************************\n"); ! 451: (void) printf("**BAD OPTION in PERMISSIONS file: %s\n", ! 452: pair.name); ! 453: (void) printf("*****************************\n"); ! 454: Uerrors++; ! 455: return(0); ! 456: } ! 457: #endif ! 458: ! 459: } ! 460: return(0); ! 461: } ! 462: ! 463: /* ! 464: * return a name value pair ! 465: * string -> input pointer ! 466: * pair -> name value pair ! 467: * return: ! 468: * pointer to next character ! 469: */ ! 470: static ! 471: char * ! 472: next_token (string, pair) ! 473: register char *string; ! 474: struct name_value *pair; ! 475: { ! 476: ! 477: while ( (*string) && ((*string == '\t') || (*string == ' ')) ) ! 478: string++; ! 479: ! 480: pair->name = string; ! 481: while ((*string) && (*string != '=')) ! 482: string++; ! 483: if (*string) ! 484: *string++ = NULLCHAR; ! 485: ! 486: pair->value = string; ! 487: while ((*string) && (*string != '\t') && (*string != ' ') ! 488: && (*string != '\n')) ! 489: string++; ! 490: ! 491: if (*string) ! 492: *string++ = NULLCHAR; ! 493: ! 494: return (string); ! 495: } ! 496: ! 497: /* ! 498: * get a line from the PERMISSIONS ! 499: * take care of comments (#) in col 1 ! 500: * and continuations (\) in last col ! 501: * return: ! 502: * len of line ! 503: * 0 -> end of file ! 504: */ ! 505: getuline(line) ! 506: char *line; ! 507: { ! 508: register char *p, *c; ! 509: char buf[BUFSIZ]; ! 510: ! 511: p = line; ! 512: for (;fgets(buf, BUFSIZ, Fp) != NULL;) { ! 513: /* remove trailing white space */ ! 514: c = &buf[strlen(buf)-1]; ! 515: while (c>=buf && (*c == '\n' || *c == '\t' || *c == ' ') ) ! 516: *c-- = NULLCHAR; ! 517: ! 518: if (buf[0] == '#' || buf[0] == '\n' || buf[0] == NULLCHAR) ! 519: continue; ! 520: (void) strcpy(p, buf); ! 521: p += strlen(buf); ! 522: if ( *(p-1) == '\\') ! 523: p--; ! 524: else ! 525: break; ! 526: } ! 527: ! 528: return(p-line); ! 529: } ! 530: ! 531: ! 532: #define SMAX 15 ! 533: ! 534: /* ! 535: * get the next colon separated argument from the list ! 536: * return: ! 537: * p -> pointer to next arg in string ! 538: * input: ! 539: * str -> pointer to input string ! 540: * output: ! 541: * name -> pointer to arg string ! 542: */ ! 543: static ! 544: char * ! 545: nextarg(str, name) ! 546: char *str, **name; ! 547: { ! 548: register char *p, *b; ! 549: static char buf[SMAX+1]; ! 550: ! 551: for(b=buf,p=str; *p != ':' && *p && b < buf+SMAX;) ! 552: *b++ = *p++; ! 553: *b++ = NULLCHAR; ! 554: if (*p == ':') ! 555: p++; ! 556: *name = buf; ! 557: return(p); ! 558: } ! 559: ! 560: /* ! 561: * check if requesting files is permitted ! 562: * return ! 563: * TRUE -> request permitted ! 564: * FALSE -> request denied ! 565: */ ! 566: requestOK() ! 567: { ! 568: return(_Request); ! 569: } ! 570: ! 571: /* ! 572: * myName - return my name from PERMISSIONS file ! 573: * or if not there, from uucpname() ! 574: * return: none ! 575: */ ! 576: ! 577: void ! 578: myName(name) ! 579: char *name; ! 580: { ! 581: if (*_MyName) ! 582: strcpy(name, _MyName); ! 583: else ! 584: uucpname(name); ! 585: return; ! 586: } ! 587: ! 588: /* ! 589: * check for callback required for any transaction ! 590: * return: ! 591: * TRUE -> callback required ! 592: * FALSE-> callback NOT required ! 593: */ ! 594: callBack() ! 595: { ! 596: return(_CallBack); ! 597: } ! 598: ! 599: /* ! 600: * check for callback to send any files from here ! 601: * This means that the called (SLAVE) system will not switch roles. ! 602: * return: ! 603: * TRUE -> callback requried to send files ! 604: * FALSE-> callback NOT required to send files ! 605: */ ! 606: switchRole() ! 607: { ! 608: return(_Switch); ! 609: } ! 610: ! 611: /* ! 612: * Check to see if command is valid for a specific machine. ! 613: * The PERMISSIONS file has an option XQT=name1:name2:... for ! 614: * any machine that does not have the default list which is ! 615: * rmail:rnews ! 616: * Note that the PERMISSIONS file is read once for each system ! 617: * at the time the Rmtname is set in xprocess(). ! 618: * Return codes: ! 619: * ok: TRUE ! 620: * fail: FALSE ! 621: */ ! 622: cmdOK(cmd, fullcmd) ! 623: char *cmd, *fullcmd; ! 624: { ! 625: DEBUG(7, "cmdOK(%s, )\n", cmd); ! 626: return(cmdMatch(cmd, fullcmd)); ! 627: } ! 628: ! 629: ! 630: /* ! 631: * check a name against a list ! 632: * input: ! 633: * name -> name ! 634: * list -> list of names ! 635: * return: ! 636: * TRUE -> found path ! 637: * FALSE -> not found ! 638: */ ! 639: static ! 640: int ! 641: listMatch(name, list) ! 642: register char *name, *list[]; ! 643: { ! 644: register i; ! 645: ! 646: for (i=0; list[i] != NULL; i++) ! 647: if (PREFIX(list[i], name)) ! 648: return(TRUE); ! 649: return(FALSE); ! 650: } ! 651: ! 652: ! 653: /* ! 654: * Check "name" against a BASENAME or full name of _Commands list. ! 655: * If "name" specifies full path, check full, else check BASENAME. ! 656: * e.g. "name" rmail matches list item /usr/bin/rmail ! 657: * input: ! 658: * name -> name ! 659: * output: ! 660: * fullname -> copy full command name into fullname if ! 661: * a full path was specified in _Commands; ! 662: * if not, put name into fullname. ! 663: * return: ! 664: * TRUE -> found path ! 665: * FALSE -> not found ! 666: */ ! 667: static ! 668: cmdMatch(name, fullname) ! 669: register char *name; ! 670: char *fullname; ! 671: { ! 672: register i; ! 673: char *bname; ! 674: int allok = FALSE; ! 675: ! 676: for (i=0; _Commands[i] != NULL; i++) { ! 677: if (EQUALS(_Commands[i], "ALL")) { ! 678: /* if ALL specified in the list ! 679: * set allok and continue in case ! 680: * a full path name is specified for the command ! 681: */ ! 682: allok = TRUE; ! 683: continue; ! 684: } ! 685: if (name[0] != '/') ! 686: bname = BASENAME(_Commands[i], '/'); ! 687: else ! 688: bname = _Commands[i]; ! 689: DEBUG(7, "bname=%s\n", bname); ! 690: if (EQUALS(bname, name)) { ! 691: (void) strcpy(fullname, _Commands[i]); ! 692: return(TRUE); ! 693: } ! 694: } ! 695: if (allok == TRUE) { ! 696: /* ALL was specified and the command was not found in list */ ! 697: (void) strcpy(fullname, name); ! 698: return(TRUE); ! 699: } ! 700: (void) strcpy(fullname, "NuLL"); /* this is a dummy command */ ! 701: return(FALSE); ! 702: } ! 703: ! 704: ! 705: /* ! 706: * check the paths for this login/machine ! 707: * input: ! 708: * path pathname ! 709: * flag CK_READ or CK_WRITE ! 710: * output: ! 711: * path may be modified to canonical form ! 712: * (../, ./, // will be interpreted/removed) ! 713: * returns: ! 714: * 0 -> success ! 715: * FAIL -> failure - not a valid path for access ! 716: */ ! 717: chkpth(path, flag) ! 718: char *path; ! 719: { ! 720: register char *s; ! 721: ! 722: /* ! 723: * this is probably redundant, ! 724: * because expfile did it, but that's ok ! 725: * Note - the /../ check is not required because of canPath ! 726: */ ! 727: if (canPath(path) == FAIL) ! 728: return(FAIL); ! 729: ! 730: if (flag == CK_READ) ! 731: if (listMatch(path, _RPaths) ! 732: && !listMatch(path, _NoRPaths)) ! 733: return(0); ! 734: if (flag == CK_WRITE) ! 735: if (listMatch(path, _WPaths) ! 736: && !listMatch(path, _NoWPaths)) ! 737: return(0); ! 738: ! 739: ! 740: /* ok if uucp generated D. or X. name for the spool directory */ ! 741: if (PREFIX(RemSpool, path) ) { ! 742: s = &path[strlen(RemSpool)]; ! 743: if ( (*s++ == '/') ! 744: && (*s == DATAPRE || *s == XQTPRE) ! 745: && (*(++s) == '.') ! 746: && (strchr(s, '/') == NULL) ) ! 747: return(0); ! 748: } ! 749: ! 750: /* path name not valid */ ! 751: return(FAIL); ! 752: } ! 753: ! 754: /* ! 755: * check write permission of file. ! 756: * if mopt != NULL and permissions are ok, ! 757: * a side effect of this routine is to make ! 758: * directories up to the last part of the ! 759: * "to" ( if they do not exit). ! 760: * Input: ! 761: * to - a path name of the destination file or directory ! 762: * from - full path name of source file ! 763: * opt - create directory option (NULL - don't create) ! 764: * Output: ! 765: * to - will be the full path name of the destination file ! 766: * returns: ! 767: * 0 ->success ! 768: * FAIL -> failure ! 769: */ ! 770: chkperm(from, to, opt) ! 771: char *from, *to, *opt; ! 772: { ! 773: register char *lxp, *p; ! 774: struct stat s; ! 775: char dir[MAXFULLNAME]; ! 776: ! 777: if ( *(p = LASTCHAR(to)) == '/') ! 778: (void) strcpy(p+1, BASENAME(from, '/')); ! 779: else ! 780: if (DIRECTORY(to)) { ! 781: *++p = '/'; ! 782: (void) strcpy(p+1, BASENAME(from, '/')); ! 783: } ! 784: ! 785: /* to is now the full path name of the destination file */ ! 786: ! 787: if (WRITEANY(to)) ! 788: return(0); ! 789: if (stat(to, &s) == 0) ! 790: return(FAIL); /* file exists, but not writeable */ ! 791: ! 792: /* file does not exist--check directory and make when necessary */ ! 793: ! 794: (void) strcpy(dir, to); ! 795: if ( (lxp=strrchr(dir, '/')) == NULL) ! 796: return(FAIL); /* no directory part of name */ ! 797: if (lxp == dir) /* at root */ ! 798: lxp++; ! 799: *lxp = NULLCHAR; ! 800: ! 801: if (!DIRECTORY(dir)) { ! 802: if (opt == NULL) ! 803: return(FAIL); /* no directory and no opt to make them */ ! 804: else if (mkdirs(dir) == FAIL) ! 805: return(FAIL); ! 806: } ! 807: ! 808: /* the directory now exists--check for writability */ ! 809: if (EQUALS(RemSpool, dir) || WRITEANY(dir)) ! 810: return(0); ! 811: ! 812: return(FAIL); ! 813: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.