|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)uuxqt.c 5.12 (Berkeley) 5/13/88"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <sys/stat.h> ! 7: #ifdef NDIR ! 8: #include "ndir.h" ! 9: #else ! 10: #include <sys/dir.h> ! 11: #endif ! 12: #include <signal.h> ! 13: ! 14: #define BADCHARS "&^|(`\\<>;\"{}\n'" ! 15: #define RECHECKTIME 60*10 /* 10 minutes */ ! 16: ! 17: #define APPCMD(d) {\ ! 18: char *p;\ ! 19: for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';} ! 20: ! 21: extern char Filent[LLEN][NAMESIZE]; ! 22: ! 23: /* ! 24: * uuxqt will execute commands set up by a uux command, ! 25: * usually from a remote machine - set by uucp. ! 26: */ ! 27: ! 28: #define NCMDS 50 ! 29: char *Cmds[NCMDS+1]; ! 30: int Notify[NCMDS+1]; ! 31: #define NT_YES 0 /* if should notify on execution */ ! 32: #define NT_ERR 1 /* if should notify if non-zero exit status (-z equivalent) */ ! 33: #define NT_NO 2 /* if should not notify ever (-n equivalent) */ ! 34: ! 35: extern int Nfiles; ! 36: ! 37: int TransferSucceeded = 1; ! 38: int notiok = 1; ! 39: int nonzero = 0; ! 40: ! 41: struct timeb Now; ! 42: ! 43: char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin:/usr/ucb"; ! 44: char UU_MACHINE[MAXFULLNAME]; ! 45: char Shell[MAXFULLNAME]; ! 46: char HOME[MAXFULLNAME]; ! 47: ! 48: extern char **environ; ! 49: char *nenv[] = { ! 50: PATH, ! 51: Shell, ! 52: HOME, ! 53: UU_MACHINE, ! 54: 0 ! 55: }; ! 56: ! 57: /* to remove restrictions from uuxqt ! 58: * define ALLOK 1 ! 59: * ! 60: * to add allowable commands, add to the file CMDFILE ! 61: * A line of form "PATH=..." changes the search path ! 62: */ ! 63: main(argc, argv) ! 64: char *argv[]; ! 65: { ! 66: char xcmd[BUFSIZ*2]; ! 67: int argnok; ! 68: int notiflg; ! 69: char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ*2]; ! 70: char lbuf[MAXFULLNAME]; ! 71: char cfile[NAMESIZE], dfile[MAXFULLNAME]; ! 72: char file[NAMESIZE]; ! 73: char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME]; ! 74: register FILE *xfp, *fp; ! 75: FILE *dfp; ! 76: char path[MAXFULLNAME]; ! 77: char cmd[BUFSIZ*2]; ! 78: char *cmdp, prm[1000], *ptr; ! 79: char *getprm(), *lastpart(); ! 80: int uid, ret, badfiles; ! 81: register int i; ! 82: int stcico = 0; ! 83: time_t xstart, xnow; ! 84: char retstat[30]; ! 85: extern char *optarg; ! 86: extern int optind; ! 87: ! 88: strcpy(Progname, "uuxqt"); ! 89: uucpname(Myname); ! 90: strcpy(Rmtname, Myname); ! 91: ! 92: umask(WFMASK); ! 93: Ofn = 1; ! 94: Ifn = 0; ! 95: while ((i = getopt(argc, argv, "x:S:")) != EOF) ! 96: switch(i) { ! 97: case 'x': ! 98: chkdebug(); ! 99: Debug = atoi(optarg); ! 100: if (Debug <= 0) ! 101: Debug = 1; ! 102: break; ! 103: case 'S': ! 104: Spool = optarg; ! 105: DEBUG(1, "Spool set to %s", Spool); ! 106: break; ! 107: case '?': ! 108: default: ! 109: fprintf(stderr, "unknown flag %s\n", argv[optind-1]); ! 110: break; ! 111: } ! 112: ! 113: DEBUG(4, "\n\n** START **\n", CNULL); ! 114: if (subchdir(Spool) < 0) { ! 115: syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool); ! 116: cleanup(1); ! 117: } ! 118: strcpy(Wrkdir, Spool); ! 119: uid = getuid(); ! 120: if (guinfo(uid, User, path) != SUCCESS) { ! 121: syslog(LOG_WARNING, "Can't find username for uid %d", uid); ! 122: DEBUG(1, "Using username", "uucp"); ! 123: strcpy(User, "uucp"); ! 124: } ! 125: setgid(getegid()); ! 126: setuid(geteuid()); ! 127: ! 128: DEBUG(4, "User - %s\n", User); ! 129: if (ulockf(X_LOCK, X_LOCKTIME) != 0) ! 130: exit(0); ! 131: ! 132: fp = fopen(CMDFILE, "r"); ! 133: if (fp == NULL) { ! 134: logent(CANTOPEN, CMDFILE); ! 135: Cmds[0] = "rmail"; ! 136: Cmds[1] = "rnews"; ! 137: Cmds[2] = "ruusend"; ! 138: Cmds[3] = NULL; ! 139: goto doprocess; ! 140: } ! 141: DEBUG(5, "%s opened\n", CMDFILE); ! 142: for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) { ! 143: int j; ! 144: /* strip trailing whitespace */ ! 145: for (j = strlen(xcmd)-1; j >= 0; --j) ! 146: if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') ! 147: xcmd[j] = '\0'; ! 148: else ! 149: break; ! 150: /* look for imbedded whitespace */ ! 151: for (; j >= 0; --j) ! 152: if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') ! 153: break; ! 154: /* skip this entry if it has embedded whitespace */ ! 155: /* This defends against a bad PATH=, for example */ ! 156: if (j >= 0) { ! 157: logent(xcmd, "BAD WHITESPACE"); ! 158: continue; ! 159: } ! 160: if (strncmp(xcmd, "PATH=", 5) == 0) { ! 161: strcpy(PATH, xcmd); ! 162: i--; /*kludge */ ! 163: continue; ! 164: } ! 165: DEBUG(5, "xcmd = %s\n", xcmd); ! 166: ! 167: if ((ptr = index(xcmd, ',')) != NULL) { ! 168: *ptr++ = '\0'; ! 169: if (strncmp(ptr, "Err", 3) == SAME) ! 170: Notify[i] = NT_ERR; ! 171: else if (strcmp(ptr, "No") == SAME) ! 172: Notify[i] = NT_NO; ! 173: else ! 174: Notify[i] = NT_YES; ! 175: } else ! 176: Notify[i] = NT_YES; ! 177: if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) { ! 178: DEBUG(1, "MALLOC FAILED", CNULL); ! 179: break; ! 180: } ! 181: strcpy(Cmds[i], xcmd); ! 182: } ! 183: Cmds[i] = CNULL; ! 184: fclose(fp); ! 185: ! 186: doprocess: ! 187: ! 188: (void) sprintf(HOME, "HOME=%s", Spool); ! 189: (void) sprintf(Shell, "SHELL=%s", SHELL); ! 190: environ = nenv; /* force use if our environment */ ! 191: ! 192: DEBUG(11,"path = %s\n", getenv("PATH")); ! 193: ! 194: DEBUG(4, "process %s\n", CNULL); ! 195: ! 196: time(&xstart); ! 197: while (gtxfile(xfile) > 0) { ! 198: /* if /etc/nologin exists, exit cleanly */ ! 199: #if defined(BSD4_2) || defined(USG) ! 200: if (access(NOLOGIN) == 0) { ! 201: #else !BSD4_2 && ! USG ! 202: ultouch(); ! 203: if (nologinflag) { ! 204: #endif !BSD4_2 && !USG ! 205: logent(NOLOGIN, "UUXQT SHUTDOWN"); ! 206: if (Debug) ! 207: logent("debugging", "continuing anyway"); ! 208: else ! 209: break; ! 210: } ! 211: DEBUG(4, "xfile - %s\n", xfile); ! 212: ! 213: xfp = fopen(subfile(xfile), "r"); ! 214: if (xfp == NULL) { ! 215: syslog(LOG_ERR, "fopen(%s) failed: %m", subfile(xfile)); ! 216: cleanup(1); ! 217: } ! 218: ! 219: /* initialize to default */ ! 220: strcpy(user, User); ! 221: strcpy(fin, DEVNULL); ! 222: strcpy(fout, DEVNULL); ! 223: strcpy(sysout, Myname); ! 224: badfiles = 0; ! 225: while (fgets(buf, BUFSIZ, xfp) != NULL) { ! 226: if(buf[0] != '\0' && buf[0] != '#' && ! 227: buf[1] != ' ' && buf[1] != '\0' && buf[1] != '\n') { ! 228: char *bnp, cfilename[BUFSIZ]; ! 229: DEBUG(4, "uuxqt: buf = %s\n", buf); ! 230: bnp = rindex(xfile, '/'); ! 231: sprintf(cfilename, "%s/%s", CORRUPT, ! 232: bnp ? bnp + 1 : xfile); ! 233: DEBUG(4, "uuxqt: move %s to ", xfile); ! 234: DEBUG(4, "%s\n", cfilename); ! 235: xmv(xfile, cfilename); ! 236: syslog(LOG_WARNING, "%s: X. FILE CORRUPTED", ! 237: xfile); ! 238: fclose(xfp); ! 239: goto doprocess; ! 240: } ! 241: switch (buf[0]) { ! 242: case X_USER: { ! 243: char ORmtname[MAXFULLNAME]; ! 244: strcpy(ORmtname, Rmtname); ! 245: sscanf(&buf[1], "%s %s", user, Rmtname); ! 246: sprintf(UU_MACHINE, "UU_MACHINE=%s", Rmtname); ! 247: if (strcmp(ORmtname, Rmtname) != 0) ! 248: logcls(); ! 249: break;} ! 250: case X_RETURNTO: ! 251: sscanf(&buf[1], "%s", user); ! 252: break; ! 253: case X_STDIN: ! 254: sscanf(&buf[1], "%s", fin); ! 255: i = expfile(fin); ! 256: /* rti!trt: do not check permissions of ! 257: * vanilla spool file */ ! 258: if (i != 0 ! 259: && (chkpth("", "", fin) || anyread(fin) != 0)) ! 260: badfiles = 1; ! 261: break; ! 262: case X_STDOUT: ! 263: sscanf(&buf[1], "%s%s", fout, sysout); ! 264: sysout[MAXBASENAME] = '\0'; ! 265: /* rti!trt: do not check permissions of ! 266: * vanilla spool file. DO check permissions ! 267: * of writing on a non-vanilla file */ ! 268: i = 1; ! 269: if (fout[0] != '~' || prefix(sysout, Myname)) ! 270: i = expfile(fout); ! 271: if (i != 0 ! 272: && (chkpth("", "", fout) ! 273: || chkperm(fout, (char *)1))) ! 274: badfiles = 1; ! 275: break; ! 276: case X_CMD: ! 277: strcpy(cmd, &buf[2]); ! 278: if (*(cmd + strlen(cmd) - 1) == '\n') ! 279: *(cmd + strlen(cmd) - 1) = '\0'; ! 280: break; ! 281: case X_NONOTI: ! 282: notiok = 0; ! 283: break; ! 284: case X_NONZERO: ! 285: nonzero = 1; ! 286: break; ! 287: default: ! 288: break; ! 289: } ! 290: } ! 291: ! 292: fclose(xfp); ! 293: DEBUG(4, "fin - %s, ", fin); ! 294: DEBUG(4, "fout - %s, ", fout); ! 295: DEBUG(4, "sysout - %s, ", sysout); ! 296: DEBUG(4, "user - %s\n", user); ! 297: DEBUG(4, "cmd - %s\n", cmd); ! 298: ! 299: /* command execution */ ! 300: if (strcmp(fout, DEVNULL) == SAME) ! 301: strcpy(dfile,DEVNULL); ! 302: else ! 303: gename(DATAPRE, sysout, 'O', dfile); ! 304: ! 305: /* expand file names where necessary */ ! 306: expfile(dfile); ! 307: cmdp = buf; ! 308: ptr = cmd; ! 309: xcmd[0] = '\0'; ! 310: argnok = 0; ! 311: while ((ptr = getprm(ptr, prm)) != NULL) { ! 312: if (prm[0] == ';' || prm[0] == '^' ! 313: || prm[0] == '&' || prm[0] == '|') { ! 314: xcmd[0] = '\0'; ! 315: APPCMD(prm); ! 316: continue; ! 317: } ! 318: ! 319: if ((argnok = argok(xcmd, prm)) != SUCCESS) ! 320: /* command not valid */ ! 321: break; ! 322: ! 323: if (prm[0] == '~') ! 324: expfile(prm); ! 325: APPCMD(prm); ! 326: } ! 327: /* ! 328: * clean up trailing ' ' in command. ! 329: */ ! 330: if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ') ! 331: *--cmdp = '\0'; ! 332: if (argnok || badfiles) { ! 333: sprintf(lbuf, "%s XQT DENIED", user); ! 334: logent(cmd, lbuf); ! 335: DEBUG(4, "bad command %s\n", prm); ! 336: notify(user, Rmtname, cmd, "DENIED"); ! 337: goto rmfiles; ! 338: } ! 339: sprintf(lbuf, "%s XQT", user); ! 340: logent(buf, lbuf); ! 341: DEBUG(4, "cmd %s\n", buf); ! 342: ! 343: mvxfiles(xfile); ! 344: if (subchdir(XQTDIR) < 0) { ! 345: syslog(LOG_ERR, "chdir(%s) failed: %m", XQTDIR); ! 346: cleanup(1); ! 347: } ! 348: ret = shio(buf, fin, dfile); ! 349: sprintf(retstat, "signal %d, exit %d", ret & 0377, ! 350: (ret>>8) & 0377); ! 351: if (strcmp(xcmd, "rmail") == SAME) ! 352: notiok = 0; ! 353: if (strcmp(xcmd, "rnews") == SAME) ! 354: nonzero = 1; ! 355: notiflg = chknotify(xcmd); ! 356: if (notiok && notiflg != NT_NO && ! 357: (ret != 0 || (!nonzero && notiflg == NT_YES))) ! 358: notify(user, Rmtname, cmd, retstat); ! 359: else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) { ! 360: /* mail failed - return letter to sender */ ! 361: #ifdef DANGEROUS ! 362: /* NOT GUARANTEED SAFE!!! */ ! 363: if (!nonzero) ! 364: retosndr(user, Rmtname, fin); ! 365: #else ! 366: notify(user, Rmtname, cmd, retstat); ! 367: #endif ! 368: sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user); ! 369: logent("MAIL FAIL", buf); ! 370: } ! 371: DEBUG(4, "exit cmd - %d\n", ret); ! 372: if (subchdir(Spool) < 0) { ! 373: syslog(LOG_ERR, "chdir(%s) failed: %m", Spool); ! 374: cleanup(1); ! 375: } ! 376: rmxfiles(xfile); ! 377: if (ret != 0) { ! 378: /* exit status not zero */ ! 379: dfp = fopen(subfile(dfile), "a"); ! 380: if (dfp == NULL) { ! 381: syslog(LOG_ERR, "fopen(%s) failed: %m", ! 382: subfile(dfile)); ! 383: cleanup(1); ! 384: } ! 385: fprintf(dfp, "exit status %d", ret); ! 386: fclose(dfp); ! 387: } ! 388: if (strcmp(fout, DEVNULL) != SAME) { ! 389: if (prefix(sysout, Myname)) { ! 390: xmv(dfile, fout); ! 391: chmod(fout, BASEMODE); ! 392: } else { ! 393: char *cp = rindex(user, '!'); ! 394: gename(CMDPRE, sysout, 'O', cfile); ! 395: fp = fopen(subfile(cfile), "w"); ! 396: if (fp == NULL) { ! 397: syslog(LOG_ERR, "fopen(%s) failed: %m", ! 398: subfile(cfile)); ! 399: cleanup(1); ! 400: } ! 401: fprintf(fp, "S %s %s %s - %s 0666\n", dfile, ! 402: fout, cp ? cp : user, lastpart(dfile)); ! 403: fclose(fp); ! 404: } ! 405: } ! 406: rmfiles: ! 407: xfp = fopen(subfile(xfile), "r"); ! 408: if (xfp == NULL) { ! 409: syslog(LOG_ERR, "fopen(%s) failed: %m", ! 410: subfile(xfile)); ! 411: cleanup(1); ! 412: } ! 413: while (fgets(buf, BUFSIZ, xfp) != NULL) { ! 414: if (buf[0] != X_RQDFILE) ! 415: continue; ! 416: sscanf(&buf[1], "%s", file); ! 417: unlink(subfile(file)); ! 418: } ! 419: unlink(subfile(xfile)); ! 420: fclose(xfp); ! 421: ! 422: /* rescan X. for new work every RECHECKTIME seconds */ ! 423: time(&xnow); ! 424: if (xnow > (xstart + RECHECKTIME)) { ! 425: extern int Nfiles; ! 426: Nfiles = 0; /*force rescan for new work */ ! 427: } ! 428: xstart = xnow; ! 429: } ! 430: ! 431: if (stcico) ! 432: xuucico(""); ! 433: cleanup(0); ! 434: } ! 435: ! 436: ! 437: cleanup(code) ! 438: int code; ! 439: { ! 440: logcls(); ! 441: rmlock(CNULL); ! 442: #ifdef VMS ! 443: /* ! 444: * Since we run as a BATCH job we must wait for all processes to ! 445: * to finish ! 446: */ ! 447: while(wait(0) != -1) ! 448: ; ! 449: #endif VMS ! 450: exit(code); ! 451: } ! 452: ! 453: ! 454: /* ! 455: * get a file to execute ! 456: * ! 457: * return codes: 0 - no file | 1 - file to execute ! 458: */ ! 459: ! 460: gtxfile(file) ! 461: register char *file; ! 462: { ! 463: char pre[3]; ! 464: register int rechecked, i; ! 465: time_t ystrdy; /* yesterday */ ! 466: struct stat stbuf; /* for X file age */ ! 467: ! 468: pre[0] = XQTPRE; ! 469: pre[1] = '.'; ! 470: pre[2] = '\0'; ! 471: rechecked = 0; ! 472: retry: ! 473: if (Nfiles-- <= 0) { ! 474: Nfiles = 0; ! 475: if (rechecked) ! 476: return 0; ! 477: rechecked = 1; ! 478: DEBUG(4, "iswrk\n", CNULL); ! 479: return iswrk(file, "get", Spool, pre); ! 480: } ! 481: sprintf(file, "%s/%s", Spool, Filent[0]); ! 482: for (i=0; i<Nfiles;i++) ! 483: strcpy(Filent[i], Filent[i+1]); ! 484: ! 485: DEBUG(4, "file - %s\n", file); ! 486: /* skip spurious subdirectories */ ! 487: if (strcmp(pre, file) == SAME) ! 488: goto retry; ! 489: if (gotfiles(file)) ! 490: return 1; ! 491: /* check for old X. file with no work files and remove them. */ ! 492: if (Nfiles > LLEN/2) { ! 493: time(&ystrdy); ! 494: ystrdy -= (4 * 3600L); /* 4 hours ago */ ! 495: DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL); ! 496: while (Nfiles-- > 0) { ! 497: sprintf(file, "%s/%s", Spool, Filent[0]); ! 498: for (i=0; i<Nfiles; i++) ! 499: strcpy(Filent[i], Filent[i+1]); ! 500: ! 501: if (gotfiles(file)) ! 502: return 1; ! 503: if (stat(subfile(file), &stbuf) == 0) ! 504: if (stbuf.st_mtime <= ystrdy) { ! 505: char *bnp, cfilename[NAMESIZE]; ! 506: DEBUG(4, "gtxfile: move %s to CORRUPT \n", file); ! 507: bnp = rindex(file, '/'); ! 508: sprintf(cfilename, "%s/%s", CORRUPT, ! 509: bnp ? bnp + 1 : file); ! 510: xmv(file, cfilename); ! 511: syslog(LOG_WARNING, "%s: X. FILE MISSING FILES", file); ! 512: } ! 513: } ! 514: Nfiles = 0; ! 515: DEBUG(4, "iswrk\n", CNULL); ! 516: if (!iswrk(file, "get", Spool, pre)) ! 517: return 0; ! 518: } ! 519: goto retry; ! 520: } ! 521: ! 522: /* ! 523: * check for needed files ! 524: * ! 525: * return codes: 0 - not ready | 1 - all files ready ! 526: */ ! 527: ! 528: gotfiles(file) ! 529: register char *file; ! 530: { ! 531: struct stat stbuf; ! 532: register FILE *fp; ! 533: char buf[BUFSIZ], rqfile[MAXFULLNAME]; ! 534: ! 535: fp = fopen(subfile(file), "r"); ! 536: if (fp == NULL) ! 537: return 0; ! 538: ! 539: while (fgets(buf, BUFSIZ, fp) != NULL) { ! 540: DEBUG(4, "%s\n", buf); ! 541: if (buf[0] != X_RQDFILE) ! 542: continue; ! 543: sscanf(&buf[1], "%s", rqfile); ! 544: expfile(rqfile); ! 545: if (stat(subfile(rqfile), &stbuf) == -1) { ! 546: fclose(fp); ! 547: return 0; ! 548: } ! 549: } ! 550: ! 551: fclose(fp); ! 552: return 1; ! 553: } ! 554: ! 555: ! 556: /* ! 557: * remove execute files to x-directory ! 558: */ ! 559: ! 560: rmxfiles(xfile) ! 561: register char *xfile; ! 562: { ! 563: register FILE *fp; ! 564: char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE]; ! 565: char tfull[MAXFULLNAME]; ! 566: ! 567: if((fp = fopen(subfile(xfile), "r")) == NULL) ! 568: return; ! 569: ! 570: while (fgets(buf, BUFSIZ, fp) != NULL) { ! 571: if (buf[0] != X_RQDFILE) ! 572: continue; ! 573: if (sscanf(&buf[1], "%s%s", file, tfile) < 2) ! 574: continue; ! 575: sprintf(tfull, "%s/%s", XQTDIR, tfile); ! 576: unlink(subfile(tfull)); ! 577: } ! 578: fclose(fp); ! 579: return; ! 580: } ! 581: ! 582: ! 583: /* ! 584: * move execute files to x-directory ! 585: */ ! 586: ! 587: mvxfiles(xfile) ! 588: char *xfile; ! 589: { ! 590: register FILE *fp; ! 591: char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE]; ! 592: char tfull[MAXFULLNAME]; ! 593: ! 594: if((fp = fopen(subfile(xfile), "r")) == NULL) ! 595: return; ! 596: ! 597: while (fgets(buf, BUFSIZ, fp) != NULL) { ! 598: if (buf[0] != X_RQDFILE) ! 599: continue; ! 600: if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2) ! 601: continue; ! 602: expfile(ffile); ! 603: sprintf(tfull, "%s/%s", XQTDIR, tfile); ! 604: unlink(subfile(tfull)); ! 605: if (xmv(ffile, tfull) != 0) { ! 606: syslog(LOG_WARNING, "xmv(%s,%s) failed: %m", ! 607: ffile, tfull); ! 608: cleanup(1); ! 609: } ! 610: } ! 611: fclose(fp); ! 612: } ! 613: ! 614: /* ! 615: * check for valid command/argument ! 616: * *NOTE - side effect is to set xc to the command to be executed. ! 617: * ! 618: * return 0 - ok | 1 nok ! 619: */ ! 620: ! 621: argok(xc, cmd) ! 622: register char *xc, *cmd; ! 623: { ! 624: register char **ptr; ! 625: ! 626: #ifndef ALLOK ! 627: if (strpbrk(cmd, BADCHARS) != NULL) { ! 628: DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL); ! 629: logent(cmd, "NASTY MAGIC CHARACTER FOUND"); ! 630: return FAIL; ! 631: } ! 632: #endif !ALLOK ! 633: ! 634: if (xc[0] != '\0') ! 635: return SUCCESS; ! 636: ! 637: #ifndef ALLOK ! 638: ptr = Cmds; ! 639: DEBUG(9, "Compare %s and\n", cmd); ! 640: while(*ptr != NULL) { ! 641: DEBUG(9, "\t%s\n", *ptr); ! 642: if (strcmp(cmd, *ptr) == SAME) ! 643: break; ! 644: ptr++; ! 645: } ! 646: if (*ptr == NULL) { ! 647: DEBUG(1,"COMMAND NOT FOUND\n", CNULL); ! 648: return FAIL; ! 649: } ! 650: #endif ! 651: strcpy(xc, cmd); ! 652: DEBUG(9, "MATCHED %s\n", xc); ! 653: return SUCCESS; ! 654: } ! 655: ! 656: ! 657: /* ! 658: * if notification should be sent for successful execution of cmd ! 659: * ! 660: * return NT_YES - do notification ! 661: * NT_ERR - do notification if exit status != 0 ! 662: * NT_NO - don't do notification ever ! 663: */ ! 664: ! 665: chknotify(cmd) ! 666: char *cmd; ! 667: { ! 668: register char **ptr; ! 669: register int *nptr; ! 670: ! 671: ptr = Cmds; ! 672: nptr = Notify; ! 673: while (*ptr != NULL) { ! 674: if (strcmp(cmd, *ptr) == SAME) ! 675: return *nptr; ! 676: ptr++; ! 677: nptr++; ! 678: } ! 679: return NT_YES; /* "shouldn't happen" */ ! 680: } ! 681: ! 682: ! 683: ! 684: /* ! 685: * send mail to user giving execution results ! 686: */ ! 687: ! 688: notify(user, rmt, cmd, str) ! 689: char *user, *rmt, *cmd, *str; ! 690: { ! 691: char text[BUFSIZ*2]; ! 692: char ruser[MAXFULLNAME]; ! 693: ! 694: if (strpbrk(user, BADCHARS) != NULL) { ! 695: char lbuf[MAXFULLNAME]; ! 696: sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); ! 697: logent(cmd, lbuf); ! 698: strcpy(user, "postmaster"); ! 699: } ! 700: sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str); ! 701: if (prefix(rmt, Myname)) ! 702: strcpy(ruser, user); ! 703: else ! 704: sprintf(ruser, "%s!%s", rmt, user); ! 705: mailst(ruser, text, CNULL); ! 706: } ! 707: ! 708: /* ! 709: * return mail to sender ! 710: * ! 711: */ ! 712: retosndr(user, rmt, file) ! 713: char *user, *rmt, *file; ! 714: { ! 715: char ruser[MAXFULLNAME]; ! 716: ! 717: if (strpbrk(user, BADCHARS) != NULL) { ! 718: char lbuf[MAXFULLNAME]; ! 719: sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); ! 720: logent(file, lbuf); ! 721: strcpy(user, "postmaster"); ! 722: } ! 723: if (strcmp(rmt, Myname) == SAME) ! 724: strcpy(ruser, user); ! 725: else ! 726: sprintf(ruser, "%s!%s", rmt, user); ! 727: ! 728: if (anyread(file) == 0) ! 729: mailst(ruser, "Mail failed. Letter returned to sender.\n", file); ! 730: else ! 731: mailst(ruser, "Mail failed. Letter returned to sender.\n", CNULL); ! 732: return; ! 733: } ! 734: ! 735: /* ! 736: * execute shell of command with fi and fo as standard input/output ! 737: */ ! 738: ! 739: shio(cmd, fi, fo) ! 740: char *cmd, *fi, *fo; ! 741: { ! 742: int status, f; ! 743: int pid, ret; ! 744: char *args[256]; ! 745: extern int errno; ! 746: ! 747: if (fi == NULL) ! 748: fi = DEVNULL; ! 749: if (fo == NULL) ! 750: fo = DEVNULL; ! 751: ! 752: getargs(cmd, args, 256); ! 753: DEBUG(3, "shio - %s\n", cmd); ! 754: #ifdef SIGCHLD ! 755: signal(SIGCHLD, SIG_IGN); ! 756: #endif SIGCHLD ! 757: if ((pid = fork()) == 0) { ! 758: signal(SIGINT, SIG_IGN); ! 759: signal(SIGHUP, SIG_IGN); ! 760: signal(SIGQUIT, SIG_IGN); ! 761: close(Ifn); ! 762: close(Ofn); ! 763: close(0); ! 764: setuid(getuid()); ! 765: f = open(subfile(fi), 0); ! 766: if (f != 0) { ! 767: logent(fi, "CAN'T READ"); ! 768: exit(-errno); ! 769: } ! 770: close(1); ! 771: f = creat(subfile(fo), 0666); ! 772: if (f != 1) { ! 773: logent(fo, "CAN'T WRITE"); ! 774: exit(-errno); ! 775: } ! 776: execvp(args[0], args); ! 777: exit(100+errno); ! 778: } ! 779: while ((ret = wait(&status)) != pid && ret != -1) ! 780: ; ! 781: DEBUG(3, "status %d\n", status); ! 782: return status; ! 783: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.