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