113697Ssam #ifndef lint 2*44709Strent static char sccsid[] = "@(#)uuxqt.c 5.13 (Berkeley) 06/29/90"; 313697Ssam #endif 413697Ssam 513697Ssam #include "uucp.h" 613697Ssam #include <sys/stat.h> 713697Ssam #ifdef NDIR 813697Ssam #include "ndir.h" 913697Ssam #else 1013702Ssam #include <sys/dir.h> 1113697Ssam #endif 1217846Sralph #include <signal.h> 1313697Ssam 1418628Sralph #define BADCHARS "&^|(`\\<>;\"{}\n'" 1518628Sralph #define RECHECKTIME 60*10 /* 10 minutes */ 1617870Sralph 1713697Ssam #define APPCMD(d) {\ 1813697Ssam char *p;\ 1917846Sralph for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';} 2013697Ssam 2133579Srick extern char Filent[LLEN][NAMESIZE]; 2233579Srick 2313697Ssam /* 2413697Ssam * uuxqt will execute commands set up by a uux command, 2513697Ssam * usually from a remote machine - set by uucp. 2613697Ssam */ 2713697Ssam 2813697Ssam #define NCMDS 50 2917846Sralph char *Cmds[NCMDS+1]; 3017846Sralph int Notify[NCMDS+1]; 3117846Sralph #define NT_YES 0 /* if should notify on execution */ 3217846Sralph #define NT_ERR 1 /* if should notify if non-zero exit status (-z equivalent) */ 3317846Sralph #define NT_NO 2 /* if should not notify ever (-n equivalent) */ 3413697Ssam 3517846Sralph extern int Nfiles; 3617846Sralph 3718628Sralph int TransferSucceeded = 1; 3813697Ssam int notiok = 1; 3913697Ssam int nonzero = 0; 4013697Ssam 4125147Sbloom struct timeb Now; 4225147Sbloom 43*44709Strent char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin"; 4433966Srick char UU_MACHINE[MAXFULLNAME]; 4518628Sralph char Shell[MAXFULLNAME]; 4618628Sralph char HOME[MAXFULLNAME]; 4717846Sralph 4818628Sralph extern char **environ; 4918628Sralph char *nenv[] = { 5018628Sralph PATH, 5118628Sralph Shell, 5218628Sralph HOME, 5333966Srick UU_MACHINE, 5418628Sralph 0 5518628Sralph }; 5617846Sralph 5713697Ssam /* to remove restrictions from uuxqt 5813697Ssam * define ALLOK 1 5913697Ssam * 6013697Ssam * to add allowable commands, add to the file CMDFILE 6113697Ssam * A line of form "PATH=..." changes the search path 6213697Ssam */ 6313697Ssam main(argc, argv) 6413697Ssam char *argv[]; 6513697Ssam { 6633579Srick char xcmd[BUFSIZ*2]; 6713697Ssam int argnok; 6817846Sralph int notiflg; 6933579Srick char xfile[MAXFULLNAME], user[MAXFULLNAME], buf[BUFSIZ*2]; 7017846Sralph char lbuf[MAXFULLNAME]; 7113697Ssam char cfile[NAMESIZE], dfile[MAXFULLNAME]; 7213697Ssam char file[NAMESIZE]; 7313697Ssam char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME]; 7413697Ssam register FILE *xfp, *fp; 7513697Ssam FILE *dfp; 7613697Ssam char path[MAXFULLNAME]; 7733579Srick char cmd[BUFSIZ*2]; 7813697Ssam char *cmdp, prm[1000], *ptr; 7913697Ssam char *getprm(), *lastpart(); 8033966Srick int uid, ret, badfiles; 8113697Ssam register int i; 8213697Ssam int stcico = 0; 8318628Sralph time_t xstart, xnow; 8413697Ssam char retstat[30]; 8533966Srick extern char *optarg; 8633966Srick extern int optind; 8713697Ssam 8813697Ssam strcpy(Progname, "uuxqt"); 8913697Ssam uucpname(Myname); 9034176Srick strcpy(Rmtname, Myname); 9113697Ssam 9213697Ssam umask(WFMASK); 9313697Ssam Ofn = 1; 9413697Ssam Ifn = 0; 9533966Srick while ((i = getopt(argc, argv, "x:S:")) != EOF) 9633966Srick switch(i) { 9713697Ssam case 'x': 9817846Sralph chkdebug(); 9933966Srick Debug = atoi(optarg); 10013697Ssam if (Debug <= 0) 10113697Ssam Debug = 1; 10213697Ssam break; 10333579Srick case 'S': 10433966Srick Spool = optarg; 10533579Srick DEBUG(1, "Spool set to %s", Spool); 10633579Srick break; 10733966Srick case '?': 10813697Ssam default: 10933966Srick fprintf(stderr, "unknown flag %s\n", argv[optind-1]); 11013697Ssam break; 11113697Ssam } 11213697Ssam 11318628Sralph DEBUG(4, "\n\n** START **\n", CNULL); 11433966Srick if (subchdir(Spool) < 0) { 11533966Srick syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool); 11633966Srick cleanup(1); 11733966Srick } 11813697Ssam strcpy(Wrkdir, Spool); 11913697Ssam uid = getuid(); 12033579Srick if (guinfo(uid, User, path) != SUCCESS) { 12133966Srick syslog(LOG_WARNING, "Can't find username for uid %d", uid); 12233579Srick DEBUG(1, "Using username", "uucp"); 12333579Srick strcpy(User, "uucp"); 12433579Srick } 12517846Sralph setgid(getegid()); 12617846Sralph setuid(geteuid()); 12717846Sralph 12813697Ssam DEBUG(4, "User - %s\n", User); 12923692Sbloom if (ulockf(X_LOCK, X_LOCKTIME) != 0) 13013697Ssam exit(0); 13113697Ssam 13213697Ssam fp = fopen(CMDFILE, "r"); 13313697Ssam if (fp == NULL) { 13417846Sralph logent(CANTOPEN, CMDFILE); 13513697Ssam Cmds[0] = "rmail"; 13613697Ssam Cmds[1] = "rnews"; 13713697Ssam Cmds[2] = "ruusend"; 13813697Ssam Cmds[3] = NULL; 13913697Ssam goto doprocess; 14013697Ssam } 14113697Ssam DEBUG(5, "%s opened\n", CMDFILE); 14217846Sralph for (i=0; i<NCMDS && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) { 14317846Sralph int j; 14417846Sralph /* strip trailing whitespace */ 14517846Sralph for (j = strlen(xcmd)-1; j >= 0; --j) 14617846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 14717846Sralph xcmd[j] = '\0'; 14817846Sralph else 14917846Sralph break; 15017846Sralph /* look for imbedded whitespace */ 15117846Sralph for (; j >= 0; --j) 15217846Sralph if (xcmd[j] == '\n' || xcmd[j] == ' ' || xcmd[j] == '\t') 15317846Sralph break; 15417846Sralph /* skip this entry if it has embedded whitespace */ 15517846Sralph /* This defends against a bad PATH=, for example */ 15617846Sralph if (j >= 0) { 15717846Sralph logent(xcmd, "BAD WHITESPACE"); 15817846Sralph continue; 15917846Sralph } 16013697Ssam if (strncmp(xcmd, "PATH=", 5) == 0) { 16113697Ssam strcpy(PATH, xcmd); 16217846Sralph i--; /*kludge */ 16313697Ssam continue; 16413697Ssam } 16513697Ssam DEBUG(5, "xcmd = %s\n", xcmd); 16617846Sralph 16717846Sralph if ((ptr = index(xcmd, ',')) != NULL) { 16817846Sralph *ptr++ = '\0'; 16917846Sralph if (strncmp(ptr, "Err", 3) == SAME) 17017846Sralph Notify[i] = NT_ERR; 17117846Sralph else if (strcmp(ptr, "No") == SAME) 17217846Sralph Notify[i] = NT_NO; 17317846Sralph else 17417846Sralph Notify[i] = NT_YES; 17517846Sralph } else 17617846Sralph Notify[i] = NT_YES; 17717846Sralph if ((Cmds[i] = malloc((unsigned)(strlen(xcmd)+1))) == NULL) { 17817846Sralph DEBUG(1, "MALLOC FAILED", CNULL); 17917846Sralph break; 18017846Sralph } 18113697Ssam strcpy(Cmds[i], xcmd); 18213697Ssam } 18317846Sralph Cmds[i] = CNULL; 18413697Ssam fclose(fp); 18513697Ssam 18613697Ssam doprocess: 18718628Sralph 18818628Sralph (void) sprintf(HOME, "HOME=%s", Spool); 18918628Sralph (void) sprintf(Shell, "SHELL=%s", SHELL); 19018628Sralph environ = nenv; /* force use if our environment */ 19118628Sralph 19218628Sralph DEBUG(11,"path = %s\n", getenv("PATH")); 19318628Sralph 19417846Sralph DEBUG(4, "process %s\n", CNULL); 19533579Srick 19618628Sralph time(&xstart); 19713697Ssam while (gtxfile(xfile) > 0) { 19825147Sbloom /* if /etc/nologin exists, exit cleanly */ 19925147Sbloom #if defined(BSD4_2) || defined(USG) 20025147Sbloom if (access(NOLOGIN) == 0) { 20125147Sbloom #else !BSD4_2 && ! USG 20217846Sralph ultouch(); 20317846Sralph if (nologinflag) { 20425147Sbloom #endif !BSD4_2 && !USG 20517846Sralph logent(NOLOGIN, "UUXQT SHUTDOWN"); 20617846Sralph if (Debug) 20717846Sralph logent("debugging", "continuing anyway"); 20817846Sralph else 20917846Sralph break; 21017846Sralph } 21113697Ssam DEBUG(4, "xfile - %s\n", xfile); 21213697Ssam 21313697Ssam xfp = fopen(subfile(xfile), "r"); 21433966Srick if (xfp == NULL) { 21533966Srick syslog(LOG_ERR, "fopen(%s) failed: %m", subfile(xfile)); 21633966Srick cleanup(1); 21733966Srick } 21813697Ssam 21913697Ssam /* initialize to default */ 22013697Ssam strcpy(user, User); 22117846Sralph strcpy(fin, DEVNULL); 22217846Sralph strcpy(fout, DEVNULL); 22323692Sbloom strcpy(sysout, Myname); 22417846Sralph badfiles = 0; 22513697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 22634267Srick if(buf[0] != '\0' && buf[0] != '#' && 22734267Srick buf[1] != ' ' && buf[1] != '\0' && buf[1] != '\n') { 22834267Srick char *bnp, cfilename[BUFSIZ]; 22934267Srick DEBUG(4, "uuxqt: buf = %s\n", buf); 23034267Srick bnp = rindex(xfile, '/'); 23134267Srick sprintf(cfilename, "%s/%s", CORRUPT, 23234267Srick bnp ? bnp + 1 : xfile); 23334267Srick DEBUG(4, "uuxqt: move %s to ", xfile); 23434267Srick DEBUG(4, "%s\n", cfilename); 23534267Srick xmv(xfile, cfilename); 23634267Srick syslog(LOG_WARNING, "%s: X. FILE CORRUPTED", 23734267Srick xfile); 23834267Srick fclose(xfp); 23934267Srick goto doprocess; 24034267Srick } 24113697Ssam switch (buf[0]) { 24234267Srick case X_USER: { 24334267Srick char ORmtname[MAXFULLNAME]; 24434267Srick strcpy(ORmtname, Rmtname); 24517846Sralph sscanf(&buf[1], "%s %s", user, Rmtname); 24633966Srick sprintf(UU_MACHINE, "UU_MACHINE=%s", Rmtname); 24734267Srick if (strcmp(ORmtname, Rmtname) != 0) 24834267Srick logcls(); 24934267Srick break;} 25017846Sralph case X_RETURNTO: 25117846Sralph sscanf(&buf[1], "%s", user); 25217846Sralph break; 25313697Ssam case X_STDIN: 25413697Ssam sscanf(&buf[1], "%s", fin); 25513697Ssam i = expfile(fin); 25613697Ssam /* rti!trt: do not check permissions of 25713697Ssam * vanilla spool file */ 25813697Ssam if (i != 0 25913697Ssam && (chkpth("", "", fin) || anyread(fin) != 0)) 26013697Ssam badfiles = 1; 26113697Ssam break; 26213697Ssam case X_STDOUT: 26313697Ssam sscanf(&buf[1], "%s%s", fout, sysout); 26423692Sbloom sysout[MAXBASENAME] = '\0'; 26513697Ssam /* rti!trt: do not check permissions of 26613697Ssam * vanilla spool file. DO check permissions 26713697Ssam * of writing on a non-vanilla file */ 26813697Ssam i = 1; 26913697Ssam if (fout[0] != '~' || prefix(sysout, Myname)) 27013697Ssam i = expfile(fout); 27113697Ssam if (i != 0 27213697Ssam && (chkpth("", "", fout) 27313697Ssam || chkperm(fout, (char *)1))) 27413697Ssam badfiles = 1; 27513697Ssam break; 27613697Ssam case X_CMD: 27713697Ssam strcpy(cmd, &buf[2]); 27813697Ssam if (*(cmd + strlen(cmd) - 1) == '\n') 27913697Ssam *(cmd + strlen(cmd) - 1) = '\0'; 28013697Ssam break; 28113697Ssam case X_NONOTI: 28213697Ssam notiok = 0; 28313697Ssam break; 28413697Ssam case X_NONZERO: 28513697Ssam nonzero = 1; 28613697Ssam break; 28713697Ssam default: 28813697Ssam break; 28913697Ssam } 29013697Ssam } 29113697Ssam 29213697Ssam fclose(xfp); 29313697Ssam DEBUG(4, "fin - %s, ", fin); 29413697Ssam DEBUG(4, "fout - %s, ", fout); 29513697Ssam DEBUG(4, "sysout - %s, ", sysout); 29613697Ssam DEBUG(4, "user - %s\n", user); 29713697Ssam DEBUG(4, "cmd - %s\n", cmd); 29813697Ssam 29913697Ssam /* command execution */ 30017846Sralph if (strcmp(fout, DEVNULL) == SAME) 30117846Sralph strcpy(dfile,DEVNULL); 30213697Ssam else 30313697Ssam gename(DATAPRE, sysout, 'O', dfile); 30413697Ssam 30513697Ssam /* expand file names where necessary */ 30613697Ssam expfile(dfile); 30718628Sralph cmdp = buf; 30813697Ssam ptr = cmd; 30913697Ssam xcmd[0] = '\0'; 31013697Ssam argnok = 0; 31113697Ssam while ((ptr = getprm(ptr, prm)) != NULL) { 31213697Ssam if (prm[0] == ';' || prm[0] == '^' 31313697Ssam || prm[0] == '&' || prm[0] == '|') { 31413697Ssam xcmd[0] = '\0'; 31513697Ssam APPCMD(prm); 31613697Ssam continue; 31713697Ssam } 31813697Ssam 31917846Sralph if ((argnok = argok(xcmd, prm)) != SUCCESS) 32013697Ssam /* command not valid */ 32113697Ssam break; 32213697Ssam 32313697Ssam if (prm[0] == '~') 32413697Ssam expfile(prm); 32513697Ssam APPCMD(prm); 32613697Ssam } 32717846Sralph /* 32817846Sralph * clean up trailing ' ' in command. 32917846Sralph */ 33017846Sralph if (cmdp > buf && cmdp[0] == '\0' && cmdp[-1] == ' ') 33117846Sralph *--cmdp = '\0'; 33213697Ssam if (argnok || badfiles) { 33313697Ssam sprintf(lbuf, "%s XQT DENIED", user); 33413697Ssam logent(cmd, lbuf); 33513697Ssam DEBUG(4, "bad command %s\n", prm); 33613697Ssam notify(user, Rmtname, cmd, "DENIED"); 33713697Ssam goto rmfiles; 33813697Ssam } 33913697Ssam sprintf(lbuf, "%s XQT", user); 34013697Ssam logent(buf, lbuf); 34113697Ssam DEBUG(4, "cmd %s\n", buf); 34213697Ssam 34313697Ssam mvxfiles(xfile); 34433966Srick if (subchdir(XQTDIR) < 0) { 34533966Srick syslog(LOG_ERR, "chdir(%s) failed: %m", XQTDIR); 34633966Srick cleanup(1); 34733966Srick } 34818628Sralph ret = shio(buf, fin, dfile); 34913697Ssam sprintf(retstat, "signal %d, exit %d", ret & 0377, 35013697Ssam (ret>>8) & 0377); 35113697Ssam if (strcmp(xcmd, "rmail") == SAME) 35213697Ssam notiok = 0; 35313697Ssam if (strcmp(xcmd, "rnews") == SAME) 35413697Ssam nonzero = 1; 35517846Sralph notiflg = chknotify(xcmd); 35617846Sralph if (notiok && notiflg != NT_NO && 35717846Sralph (ret != 0 || (!nonzero && notiflg == NT_YES))) 35813697Ssam notify(user, Rmtname, cmd, retstat); 35913697Ssam else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) { 36013697Ssam /* mail failed - return letter to sender */ 36117846Sralph #ifdef DANGEROUS 36217846Sralph /* NOT GUARANTEED SAFE!!! */ 36317846Sralph if (!nonzero) 36417846Sralph retosndr(user, Rmtname, fin); 36517846Sralph #else 36617846Sralph notify(user, Rmtname, cmd, retstat); 36717846Sralph #endif 36817846Sralph sprintf(buf, "%s (%s) from %s!%s", buf, retstat, Rmtname, user); 36913697Ssam logent("MAIL FAIL", buf); 37013697Ssam } 37113697Ssam DEBUG(4, "exit cmd - %d\n", ret); 37233966Srick if (subchdir(Spool) < 0) { 37333966Srick syslog(LOG_ERR, "chdir(%s) failed: %m", Spool); 37433966Srick cleanup(1); 37533966Srick } 37613697Ssam rmxfiles(xfile); 37713697Ssam if (ret != 0) { 37813697Ssam /* exit status not zero */ 37913697Ssam dfp = fopen(subfile(dfile), "a"); 38033966Srick if (dfp == NULL) { 38133966Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 38233966Srick subfile(dfile)); 38333966Srick cleanup(1); 38433966Srick } 38513697Ssam fprintf(dfp, "exit status %d", ret); 38613697Ssam fclose(dfp); 38713697Ssam } 38817846Sralph if (strcmp(fout, DEVNULL) != SAME) { 38913697Ssam if (prefix(sysout, Myname)) { 39013697Ssam xmv(dfile, fout); 39113697Ssam chmod(fout, BASEMODE); 39218628Sralph } else { 39317846Sralph char *cp = rindex(user, '!'); 39413697Ssam gename(CMDPRE, sysout, 'O', cfile); 39513697Ssam fp = fopen(subfile(cfile), "w"); 39633966Srick if (fp == NULL) { 39733966Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 39833966Srick subfile(cfile)); 39933966Srick cleanup(1); 40033966Srick } 40117846Sralph fprintf(fp, "S %s %s %s - %s 0666\n", dfile, 40217846Sralph fout, cp ? cp : user, lastpart(dfile)); 40313697Ssam fclose(fp); 40413697Ssam } 40513697Ssam } 40613697Ssam rmfiles: 40713697Ssam xfp = fopen(subfile(xfile), "r"); 40833966Srick if (xfp == NULL) { 40933966Srick syslog(LOG_ERR, "fopen(%s) failed: %m", 41033966Srick subfile(xfile)); 41133966Srick cleanup(1); 41233966Srick } 41313697Ssam while (fgets(buf, BUFSIZ, xfp) != NULL) { 41413697Ssam if (buf[0] != X_RQDFILE) 41513697Ssam continue; 41613697Ssam sscanf(&buf[1], "%s", file); 41713697Ssam unlink(subfile(file)); 41813697Ssam } 41913697Ssam unlink(subfile(xfile)); 42013697Ssam fclose(xfp); 42118628Sralph 42218628Sralph /* rescan X. for new work every RECHECKTIME seconds */ 42318628Sralph time(&xnow); 42418628Sralph if (xnow > (xstart + RECHECKTIME)) { 42518628Sralph extern int Nfiles; 42618628Sralph Nfiles = 0; /*force rescan for new work */ 42718628Sralph } 42818628Sralph xstart = xnow; 42913697Ssam } 43013697Ssam 43113697Ssam if (stcico) 43213697Ssam xuucico(""); 43313697Ssam cleanup(0); 43413697Ssam } 43513697Ssam 43613697Ssam 43713697Ssam cleanup(code) 43813697Ssam int code; 43913697Ssam { 44013697Ssam logcls(); 44113697Ssam rmlock(CNULL); 44217846Sralph #ifdef VMS 44317846Sralph /* 44417846Sralph * Since we run as a BATCH job we must wait for all processes to 44517846Sralph * to finish 44617846Sralph */ 44718628Sralph while(wait(0) != -1) 44818628Sralph ; 44917846Sralph #endif VMS 45013697Ssam exit(code); 45113697Ssam } 45213697Ssam 45313697Ssam 45418628Sralph /* 45518628Sralph * get a file to execute 45613697Ssam * 45713697Ssam * return codes: 0 - no file | 1 - file to execute 45813697Ssam */ 45913697Ssam 46013697Ssam gtxfile(file) 46113697Ssam register char *file; 46213697Ssam { 46313697Ssam char pre[3]; 46433579Srick register int rechecked, i; 46517846Sralph time_t ystrdy; /* yesterday */ 46617846Sralph struct stat stbuf; /* for X file age */ 46713697Ssam 46813697Ssam pre[0] = XQTPRE; 46913697Ssam pre[1] = '.'; 47013697Ssam pre[2] = '\0'; 47113697Ssam rechecked = 0; 47213697Ssam retry: 47333579Srick if (Nfiles-- <= 0) { 47433579Srick Nfiles = 0; 47513697Ssam if (rechecked) 47617846Sralph return 0; 47713697Ssam rechecked = 1; 47817846Sralph DEBUG(4, "iswrk\n", CNULL); 47933579Srick return iswrk(file, "get", Spool, pre); 48013697Ssam } 48133579Srick sprintf(file, "%s/%s", Spool, Filent[0]); 48233579Srick for (i=0; i<Nfiles;i++) 48333579Srick strcpy(Filent[i], Filent[i+1]); 48433579Srick 48513697Ssam DEBUG(4, "file - %s\n", file); 48613697Ssam /* skip spurious subdirectories */ 48713697Ssam if (strcmp(pre, file) == SAME) 48813697Ssam goto retry; 48913697Ssam if (gotfiles(file)) 49017846Sralph return 1; 49117846Sralph /* check for old X. file with no work files and remove them. */ 49217846Sralph if (Nfiles > LLEN/2) { 49317846Sralph time(&ystrdy); 49417846Sralph ystrdy -= (4 * 3600L); /* 4 hours ago */ 49517846Sralph DEBUG(4, "gtxfile: Nfiles > LLEN/2\n", CNULL); 49633579Srick while (Nfiles-- > 0) { 49733579Srick sprintf(file, "%s/%s", Spool, Filent[0]); 49833579Srick for (i=0; i<Nfiles; i++) 49933579Srick strcpy(Filent[i], Filent[i+1]); 50033579Srick 50133579Srick if (gotfiles(file)) 50233579Srick return 1; 50317846Sralph if (stat(subfile(file), &stbuf) == 0) 50417846Sralph if (stbuf.st_mtime <= ystrdy) { 50517846Sralph char *bnp, cfilename[NAMESIZE]; 50617846Sralph DEBUG(4, "gtxfile: move %s to CORRUPT \n", file); 50733579Srick bnp = rindex(file, '/'); 50817846Sralph sprintf(cfilename, "%s/%s", CORRUPT, 50933579Srick bnp ? bnp + 1 : file); 51033579Srick xmv(file, cfilename); 51133966Srick syslog(LOG_WARNING, "%s: X. FILE MISSING FILES", file); 51217846Sralph } 51317846Sralph } 51433579Srick Nfiles = 0; 51517846Sralph DEBUG(4, "iswrk\n", CNULL); 51617846Sralph if (!iswrk(file, "get", Spool, pre)) 51717846Sralph return 0; 51817846Sralph } 51913697Ssam goto retry; 52013697Ssam } 52113697Ssam 52218628Sralph /* 52318628Sralph * check for needed files 52413697Ssam * 52513697Ssam * return codes: 0 - not ready | 1 - all files ready 52613697Ssam */ 52713697Ssam 52813697Ssam gotfiles(file) 52913697Ssam register char *file; 53013697Ssam { 53113697Ssam struct stat stbuf; 53213697Ssam register FILE *fp; 53313697Ssam char buf[BUFSIZ], rqfile[MAXFULLNAME]; 53413697Ssam 53513697Ssam fp = fopen(subfile(file), "r"); 53613697Ssam if (fp == NULL) 53717846Sralph return 0; 53813697Ssam 53913697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 54013697Ssam DEBUG(4, "%s\n", buf); 54113697Ssam if (buf[0] != X_RQDFILE) 54213697Ssam continue; 54313697Ssam sscanf(&buf[1], "%s", rqfile); 54413697Ssam expfile(rqfile); 54513697Ssam if (stat(subfile(rqfile), &stbuf) == -1) { 54613697Ssam fclose(fp); 54717846Sralph return 0; 54813697Ssam } 54913697Ssam } 55013697Ssam 55113697Ssam fclose(fp); 55217846Sralph return 1; 55313697Ssam } 55413697Ssam 55513697Ssam 55618628Sralph /* 55718628Sralph * remove execute files to x-directory 55813697Ssam */ 55913697Ssam 56013697Ssam rmxfiles(xfile) 56113697Ssam register char *xfile; 56213697Ssam { 56313697Ssam register FILE *fp; 56413697Ssam char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE]; 56513697Ssam char tfull[MAXFULLNAME]; 56613697Ssam 56713697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 56813697Ssam return; 56913697Ssam 57013697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 57113697Ssam if (buf[0] != X_RQDFILE) 57213697Ssam continue; 57313697Ssam if (sscanf(&buf[1], "%s%s", file, tfile) < 2) 57413697Ssam continue; 57513697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 57613697Ssam unlink(subfile(tfull)); 57713697Ssam } 57813697Ssam fclose(fp); 57913697Ssam return; 58013697Ssam } 58113697Ssam 58213697Ssam 58318628Sralph /* 58418628Sralph * move execute files to x-directory 58513697Ssam */ 58613697Ssam 58713697Ssam mvxfiles(xfile) 58813697Ssam char *xfile; 58913697Ssam { 59013697Ssam register FILE *fp; 59113697Ssam char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE]; 59213697Ssam char tfull[MAXFULLNAME]; 59313697Ssam 59413697Ssam if((fp = fopen(subfile(xfile), "r")) == NULL) 59513697Ssam return; 59613697Ssam 59713697Ssam while (fgets(buf, BUFSIZ, fp) != NULL) { 59813697Ssam if (buf[0] != X_RQDFILE) 59913697Ssam continue; 60013697Ssam if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2) 60113697Ssam continue; 60213697Ssam expfile(ffile); 60313697Ssam sprintf(tfull, "%s/%s", XQTDIR, tfile); 60413697Ssam unlink(subfile(tfull)); 60533966Srick if (xmv(ffile, tfull) != 0) { 60633966Srick syslog(LOG_WARNING, "xmv(%s,%s) failed: %m", 60733966Srick ffile, tfull); 60833966Srick cleanup(1); 60933966Srick } 61013697Ssam } 61113697Ssam fclose(fp); 61213697Ssam } 61313697Ssam 61418628Sralph /* 61518628Sralph * check for valid command/argument 61618628Sralph * *NOTE - side effect is to set xc to the command to be executed. 61713697Ssam * 61813697Ssam * return 0 - ok | 1 nok 61913697Ssam */ 62013697Ssam 62113697Ssam argok(xc, cmd) 62213697Ssam register char *xc, *cmd; 62313697Ssam { 62413697Ssam register char **ptr; 62513697Ssam 62613697Ssam #ifndef ALLOK 62718628Sralph if (strpbrk(cmd, BADCHARS) != NULL) { 62817846Sralph DEBUG(1,"MAGIC CHARACTER FOUND\n", CNULL); 62918628Sralph logent(cmd, "NASTY MAGIC CHARACTER FOUND"); 63017846Sralph return FAIL; 63117846Sralph } 63217846Sralph #endif !ALLOK 63313697Ssam 63413697Ssam if (xc[0] != '\0') 63517846Sralph return SUCCESS; 63613697Ssam 63713697Ssam #ifndef ALLOK 63813697Ssam ptr = Cmds; 63917846Sralph DEBUG(9, "Compare %s and\n", cmd); 64013697Ssam while(*ptr != NULL) { 64117846Sralph DEBUG(9, "\t%s\n", *ptr); 64213697Ssam if (strcmp(cmd, *ptr) == SAME) 64313697Ssam break; 64417846Sralph ptr++; 64513697Ssam } 64617846Sralph if (*ptr == NULL) { 64717846Sralph DEBUG(1,"COMMAND NOT FOUND\n", CNULL); 64817846Sralph return FAIL; 64917846Sralph } 65013697Ssam #endif 65113697Ssam strcpy(xc, cmd); 65217846Sralph DEBUG(9, "MATCHED %s\n", xc); 65317846Sralph return SUCCESS; 65413697Ssam } 65513697Ssam 65613697Ssam 65718628Sralph /* 65818628Sralph * if notification should be sent for successful execution of cmd 65917846Sralph * 66017846Sralph * return NT_YES - do notification 66117846Sralph * NT_ERR - do notification if exit status != 0 66217846Sralph * NT_NO - don't do notification ever 66317846Sralph */ 66417846Sralph 66517846Sralph chknotify(cmd) 66617846Sralph char *cmd; 66717846Sralph { 66817846Sralph register char **ptr; 66917846Sralph register int *nptr; 67017846Sralph 67117846Sralph ptr = Cmds; 67217846Sralph nptr = Notify; 67317846Sralph while (*ptr != NULL) { 67417846Sralph if (strcmp(cmd, *ptr) == SAME) 67517846Sralph return *nptr; 67617846Sralph ptr++; 67717846Sralph nptr++; 67817846Sralph } 67917846Sralph return NT_YES; /* "shouldn't happen" */ 68017846Sralph } 68117846Sralph 68217846Sralph 68317846Sralph 68418628Sralph /* 68518628Sralph * send mail to user giving execution results 68613697Ssam */ 68713697Ssam 68813697Ssam notify(user, rmt, cmd, str) 68913697Ssam char *user, *rmt, *cmd, *str; 69013697Ssam { 69133579Srick char text[BUFSIZ*2]; 69213697Ssam char ruser[MAXFULLNAME]; 69313697Ssam 69425968Sbloom if (strpbrk(user, BADCHARS) != NULL) { 69525968Sbloom char lbuf[MAXFULLNAME]; 69625968Sbloom sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 69725968Sbloom logent(cmd, lbuf); 69825968Sbloom strcpy(user, "postmaster"); 69925968Sbloom } 70017846Sralph sprintf(text, "uuxqt cmd (%s) status (%s)", cmd, str); 70113697Ssam if (prefix(rmt, Myname)) 70213697Ssam strcpy(ruser, user); 70313697Ssam else 70413697Ssam sprintf(ruser, "%s!%s", rmt, user); 70517846Sralph mailst(ruser, text, CNULL); 70613697Ssam } 70713697Ssam 70818628Sralph /* 70918628Sralph * return mail to sender 71013697Ssam * 71113697Ssam */ 71213697Ssam retosndr(user, rmt, file) 71313697Ssam char *user, *rmt, *file; 71413697Ssam { 71517846Sralph char ruser[MAXFULLNAME]; 71613697Ssam 71725968Sbloom if (strpbrk(user, BADCHARS) != NULL) { 71825968Sbloom char lbuf[MAXFULLNAME]; 71925968Sbloom sprintf(lbuf, "%s INVALID CHARACTER IN USERNAME", user); 72025968Sbloom logent(file, lbuf); 72125968Sbloom strcpy(user, "postmaster"); 72225968Sbloom } 72313697Ssam if (strcmp(rmt, Myname) == SAME) 72413697Ssam strcpy(ruser, user); 72513697Ssam else 72613697Ssam sprintf(ruser, "%s!%s", rmt, user); 72713697Ssam 72813697Ssam if (anyread(file) == 0) 72913697Ssam mailst(ruser, "Mail failed. Letter returned to sender.\n", file); 73013697Ssam else 73117846Sralph mailst(ruser, "Mail failed. Letter returned to sender.\n", CNULL); 73213697Ssam return; 73313697Ssam } 73417870Sralph 73517870Sralph /* 73618628Sralph * execute shell of command with fi and fo as standard input/output 73718628Sralph */ 73818628Sralph 73918628Sralph shio(cmd, fi, fo) 74018628Sralph char *cmd, *fi, *fo; 74118628Sralph { 74218628Sralph int status, f; 74333966Srick int pid, ret; 74433579Srick char *args[256]; 74518628Sralph extern int errno; 74618628Sralph 74718628Sralph if (fi == NULL) 74818628Sralph fi = DEVNULL; 74918628Sralph if (fo == NULL) 75018628Sralph fo = DEVNULL; 75118628Sralph 75233579Srick getargs(cmd, args, 256); 75318628Sralph DEBUG(3, "shio - %s\n", cmd); 75418628Sralph #ifdef SIGCHLD 75518628Sralph signal(SIGCHLD, SIG_IGN); 75618628Sralph #endif SIGCHLD 75718628Sralph if ((pid = fork()) == 0) { 75818628Sralph signal(SIGINT, SIG_IGN); 75918628Sralph signal(SIGHUP, SIG_IGN); 76018628Sralph signal(SIGQUIT, SIG_IGN); 76118628Sralph close(Ifn); 76218628Sralph close(Ofn); 76318628Sralph close(0); 76418628Sralph setuid(getuid()); 76518628Sralph f = open(subfile(fi), 0); 76618628Sralph if (f != 0) { 76718628Sralph logent(fi, "CAN'T READ"); 76818628Sralph exit(-errno); 76918628Sralph } 77018628Sralph close(1); 77118628Sralph f = creat(subfile(fo), 0666); 77218628Sralph if (f != 1) { 77318628Sralph logent(fo, "CAN'T WRITE"); 77418628Sralph exit(-errno); 77518628Sralph } 77618628Sralph execvp(args[0], args); 77718628Sralph exit(100+errno); 77818628Sralph } 77918628Sralph while ((ret = wait(&status)) != pid && ret != -1) 78018628Sralph ; 78118628Sralph DEBUG(3, "status %d\n", status); 78218628Sralph return status; 78318628Sralph } 784