1: #ifndef lint
   2: static char sccsid[] = "@(#)uuxqt.c	5.2 (Berkeley) 7/2/83";
   3: #endif
   4: 
   5: #include "uucp.h"
   6: #include <sys/types.h>
   7: #include <sys/stat.h>
   8: #ifdef  NDIR
   9: #include "ndir.h"
  10: #else
  11: #include <sys/dir.h>
  12: #endif
  13: 
  14: #define APPCMD(d) {\
  15: char *p;\
  16: for (p = d; *p != '\0';) *cmdp++ = *p++;\
  17: *cmdp++ = ' ';\
  18: *cmdp = '\0';}
  19: 
  20: /*
  21:  *	uuxqt will execute commands set up by a uux command,
  22:  *	usually from a remote machine - set by uucp.
  23:  */
  24: 
  25: #define NCMDS   50
  26: char *Cmds[NCMDS];
  27: 
  28: int notiok = 1;
  29: int nonzero = 0;
  30: 
  31: char PATH[MAXFULLNAME] = "PATH=/bin:/usr/bin";
  32: /*  to remove restrictions from uuxqt
  33:  *  define ALLOK 1
  34:  *
  35:  *  to add allowable commands, add to the file CMDFILE
  36:  *  A line of form "PATH=..." changes the search path
  37:  */
  38: 
  39: 
  40: main(argc, argv)
  41: char *argv[];
  42: {
  43:     char xcmd[MAXFULLNAME];
  44:     int argnok;
  45:     char xfile[MAXFULLNAME], user[32], buf[BUFSIZ];
  46:     char lbuf[30];
  47:     char cfile[NAMESIZE], dfile[MAXFULLNAME];
  48:     char file[NAMESIZE];
  49:     char fin[MAXFULLNAME], sysout[NAMESIZE], fout[MAXFULLNAME];
  50:     register FILE *xfp, *fp;
  51:     FILE *dfp;
  52:     char path[MAXFULLNAME];
  53:     char cmd[BUFSIZ];
  54:     /* set size of prm to something large -- cmcl2!salkind */
  55:     char *cmdp, prm[1000], *ptr;
  56:     char *getprm(), *lastpart();
  57:     int uid, ret, badfiles;
  58:     register int i;
  59:     int stcico = 0;
  60:     char retstat[30];
  61:     int orig_uid = getuid();
  62: 
  63:     strcpy(Progname, "uuxqt");
  64:     uucpname(Myname);
  65: 
  66:     /* Try to run as uucp -- rti!trt */
  67:     setgid(getegid());
  68:     setuid(geteuid());
  69: 
  70:     umask(WFMASK);
  71:     Ofn = 1;
  72:     Ifn = 0;
  73:     while (argc>1 && argv[1][0] == '-') {
  74:         switch(argv[1][1]){
  75:         case 'x':
  76:             chkdebug(orig_uid);
  77:             Debug = atoi(&argv[1][2]);
  78:             if (Debug <= 0)
  79:                 Debug = 1;
  80:             break;
  81:         default:
  82:             fprintf(stderr, "unknown flag %s\n", argv[1]);
  83:                 break;
  84:         }
  85:         --argc;  argv++;
  86:     }
  87: 
  88:     DEBUG(4, "\n\n** %s **\n", "START");
  89:     subchdir(Spool);
  90:     strcpy(Wrkdir, Spool);
  91:     uid = getuid();
  92:     guinfo(uid, User, path);
  93:     DEBUG(4, "User - %s\n", User);
  94:     if (ulockf(X_LOCK, (time_t)  X_LOCKTIME) != 0)
  95:         exit(0);
  96: 
  97:     fp = fopen(CMDFILE, "r");
  98:     if (fp == NULL) {
  99:         /* Fall-back if CMDFILE missing. Sept 1982, rti!trt */
 100:         logent("CAN'T OPEN", CMDFILE);
 101:         Cmds[0] = "rmail";
 102:         Cmds[1] = "rnews";
 103:         Cmds[2] = "ruusend";
 104:         Cmds[3] = NULL;
 105:         goto doprocess;
 106:     }
 107:     DEBUG(5, "%s opened\n", CMDFILE);
 108:     for (i=0; i<NCMDS-1 && cfgets(xcmd, sizeof(xcmd), fp) != NULL; i++) {
 109:         xcmd[strlen(xcmd)-1] = '\0';
 110:         if (strncmp(xcmd, "PATH=", 5) == 0) {
 111:             strcpy(PATH, xcmd);
 112:             i--; /* kludge */
 113:             continue;
 114:         }
 115:         DEBUG(5, "xcmd = %s\n", xcmd);
 116:         Cmds[i] = malloc((unsigned)(strlen(xcmd)+1));
 117:         strcpy(Cmds[i], xcmd);
 118:     }
 119:     Cmds[i] = 0;
 120:     fclose(fp);
 121: 
 122: doprocess:
 123:     DEBUG(4, "process %s\n", "");
 124:     while (gtxfile(xfile) > 0) {
 125:         ultouch();  /* rti!trt */
 126:         DEBUG(4, "xfile - %s\n", xfile);
 127: 
 128:         xfp = fopen(subfile(xfile), "r");
 129:         ASSERT(xfp != NULL, "CAN'T OPEN", xfile, 0);
 130: 
 131:         /*  initialize to default  */
 132:         strcpy(user, User);
 133:         strcpy(fin, "/dev/null");
 134:         strcpy(fout, "/dev/null");
 135:         sprintf(sysout, "%.7s", Myname);
 136:         badfiles = 0;   /* this was missing -- rti!trt */
 137:         while (fgets(buf, BUFSIZ, xfp) != NULL) {
 138:             switch (buf[0]) {
 139:             case X_USER:
 140:                 sscanf(&buf[1], "%s%s", user, Rmtname);
 141:                 break;
 142:             case X_STDIN:
 143:                 sscanf(&buf[1], "%s", fin);
 144:                 i = expfile(fin);
 145:                 /* rti!trt: do not check permissions of
 146: 				 * vanilla spool file */
 147:                 if (i != 0
 148:                  && (chkpth("", "", fin) || anyread(fin) != 0))
 149:                     badfiles = 1;
 150:                 break;
 151:             case X_STDOUT:
 152:                 sscanf(&buf[1], "%s%s", fout, sysout);
 153:                 sysout[7] = '\0';
 154:                 /* rti!trt: do not check permissions of
 155: 				 * vanilla spool file.  DO check permissions
 156: 				 * of writing on a non-vanilla file */
 157:                 i = 1;
 158:                 if (fout[0] != '~' || prefix(sysout, Myname))
 159:                     i = expfile(fout);
 160:                 if (i != 0
 161:                  && (chkpth("", "", fout)
 162:                     || chkperm(fout, (char *)1)))
 163:                     badfiles = 1;
 164:                 break;
 165:             case X_CMD:
 166:                 strcpy(cmd, &buf[2]);
 167:                 if (*(cmd + strlen(cmd) - 1) == '\n')
 168:                     *(cmd + strlen(cmd) - 1) = '\0';
 169:                 break;
 170:             case X_NONOTI:
 171:                 notiok = 0;
 172:                 break;
 173:             case X_NONZERO:
 174:                 nonzero = 1;
 175:                 break;
 176:             default:
 177:                 break;
 178:             }
 179:         }
 180: 
 181:         fclose(xfp);
 182:         DEBUG(4, "fin - %s, ", fin);
 183:         DEBUG(4, "fout - %s, ", fout);
 184:         DEBUG(4, "sysout - %s, ", sysout);
 185:         DEBUG(4, "user - %s\n", user);
 186:         DEBUG(4, "cmd - %s\n", cmd);
 187: 
 188:         /*  command execution  */
 189:         if (strcmp(fout, "/dev/null") == SAME)
 190:             strcpy(dfile,"/dev/null");
 191:         else
 192:             gename(DATAPRE, sysout, 'O', dfile);
 193: 
 194:         /* expand file names where necessary */
 195:         expfile(dfile);
 196:         strcpy(buf, PATH);
 197:         strcat(buf, ";export PATH;");
 198:         cmdp = buf + strlen(buf);
 199:         ptr = cmd;
 200:         xcmd[0] = '\0';
 201:         argnok = 0;
 202:         while ((ptr = getprm(ptr, prm)) != NULL) {
 203:             if (prm[0] == ';' || prm[0] == '^'
 204:               || prm[0] == '&'  || prm[0] == '|') {
 205:                 xcmd[0] = '\0';
 206:                 APPCMD(prm);
 207:                 continue;
 208:             }
 209: 
 210:             if ((argnok = argok(xcmd, prm)) != 0)
 211:                 /*  command not valid  */
 212:                 break;
 213: 
 214:             if (prm[0] == '~')
 215:                 expfile(prm);
 216:             APPCMD(prm);
 217:         }
 218:         if (argnok || badfiles) {
 219:             sprintf(lbuf, "%s XQT DENIED", user);
 220:             logent(cmd, lbuf);
 221:             DEBUG(4, "bad command %s\n", prm);
 222:             notify(user, Rmtname, cmd, "DENIED");
 223:             goto rmfiles;
 224:         }
 225:         sprintf(lbuf, "%s XQT", user);
 226:         logent(buf, lbuf);
 227:         DEBUG(4, "cmd %s\n", buf);
 228: 
 229:         mvxfiles(xfile);
 230:         subchdir(XQTDIR);
 231:         ret = shio(buf, fin, dfile, (char *)NULL);
 232: /* watcgl.11, dmmartindale, signal and exit values were reversed */
 233:         sprintf(retstat, "signal %d, exit %d", ret & 0377,
 234:           (ret>>8) & 0377);
 235:         if (strcmp(xcmd, "rmail") == SAME)
 236:             notiok = 0;
 237:         if (strcmp(xcmd, "rnews") == SAME)
 238:             nonzero = 1;
 239:          if (notiok && (!nonzero || (nonzero && ret != 0)))
 240:             notify(user, Rmtname, cmd, retstat);
 241:         else if (ret != 0 && strcmp(xcmd, "rmail") == SAME) {
 242:             /* mail failed - return letter to sender  */
 243:             retosndr(user, Rmtname, fin);
 244:             sprintf(buf, "ret (%o) from %s!%s", ret, Rmtname, user);
 245:             logent("MAIL FAIL", buf);
 246:         }
 247:         DEBUG(4, "exit cmd - %d\n", ret);
 248:         subchdir(Spool);
 249:         rmxfiles(xfile);
 250:         if (ret != 0) {
 251:             /*  exit status not zero */
 252:             dfp = fopen(subfile(dfile), "a");
 253:             ASSERT(dfp != NULL, "CAN'T OPEN", dfile, 0);
 254:             fprintf(dfp, "exit status %d", ret);
 255:             fclose(dfp);
 256:         }
 257:         if (strcmp(fout, "/dev/null") != SAME) {
 258:             if (prefix(sysout, Myname)) {
 259:                 xmv(dfile, fout);
 260:                 chmod(fout, BASEMODE);
 261:             }
 262:             else {
 263:                 gename(CMDPRE, sysout, 'O', cfile);
 264:                 fp = fopen(subfile(cfile), "w");
 265:                 ASSERT(fp != NULL, "OPEN", cfile, 0);
 266:                 fprintf(fp, "S %s %s %s - %s 0666\n",
 267:                 dfile, fout, user, lastpart(dfile));
 268:                 fclose(fp);
 269:             }
 270:         }
 271:     rmfiles:
 272:         xfp = fopen(subfile(xfile), "r");
 273:         ASSERT(xfp != NULL, "CAN'T OPEN", xfile, 0);
 274:         while (fgets(buf, BUFSIZ, xfp) != NULL) {
 275:             if (buf[0] != X_RQDFILE)
 276:                 continue;
 277:             sscanf(&buf[1], "%s", file);
 278:             unlink(subfile(file));
 279:         }
 280:         unlink(subfile(xfile));
 281:         fclose(xfp);
 282:     }
 283: 
 284:     if (stcico)
 285:         xuucico("");
 286:     cleanup(0);
 287: }
 288: 
 289: 
 290: cleanup(code)
 291: int code;
 292: {
 293:     logcls();
 294:     rmlock(CNULL);
 295:     exit(code);
 296: }
 297: 
 298: 
 299: /*******
 300:  *	gtxfile(file)	get a file to execute
 301:  *	char *file;
 302:  *
 303:  *	return codes:  0 - no file  |  1 - file to execute
 304:  * Mod to recheck for X-able files. Sept 1982, rti!trt.
 305:  * Suggested by utzoo.2458 (utzoo!henry)
 306:  * Uses iswrk/gtwrkf to keep files in sequence, May 1983.
 307:  */
 308: 
 309: gtxfile(file)
 310: register char *file;
 311: {
 312:     char pre[3];
 313:     register int rechecked;
 314: 
 315:     pre[0] = XQTPRE;
 316:     pre[1] = '.';
 317:     pre[2] = '\0';
 318:     rechecked = 0;
 319: retry:
 320:     if (!gtwrkf(Spool, file)) {
 321:         if (rechecked)
 322:             return(0);
 323:         rechecked = 1;
 324:         DEBUG(4, "iswrk\n", "");
 325:         if (!iswrk(file, "get", Spool, pre))
 326:             return(0);
 327:     }
 328:     DEBUG(4, "file - %s\n", file);
 329: #ifndef UUDIR
 330:     /* skip spurious subdirectories */
 331:     if (strcmp(pre, file) == SAME)
 332:         goto retry;
 333: #endif
 334:     if (gotfiles(file))
 335:         return(1);
 336:     goto retry;
 337: }
 338: 
 339: 
 340: /***
 341:  *	gotfiles(file)		check for needed files
 342:  *	char *file;
 343:  *
 344:  *	return codes:  0 - not ready  |  1 - all files ready
 345:  */
 346: 
 347: gotfiles(file)
 348: register char *file;
 349: {
 350:     struct stat stbuf;
 351:     register FILE *fp;
 352:     char buf[BUFSIZ], rqfile[MAXFULLNAME];
 353: 
 354:     fp = fopen(subfile(file), "r");
 355:     if (fp == NULL)
 356:         return(0);
 357: 
 358:     while (fgets(buf, BUFSIZ, fp) != NULL) {
 359:         DEBUG(4, "%s\n", buf);
 360:         if (buf[0] != X_RQDFILE)
 361:             continue;
 362:         sscanf(&buf[1], "%s", rqfile);
 363:         expfile(rqfile);
 364:         if (stat(subfile(rqfile), &stbuf) == -1) {
 365:             fclose(fp);
 366:             return(0);
 367:         }
 368:     }
 369: 
 370:     fclose(fp);
 371:     return(1);
 372: }
 373: 
 374: 
 375: /***
 376:  *	rmxfiles(xfile)		remove execute files to x-directory
 377:  *	char *xfile;
 378:  *
 379:  *	return codes - none
 380:  */
 381: 
 382: rmxfiles(xfile)
 383: register char *xfile;
 384: {
 385:     register FILE *fp;
 386:     char buf[BUFSIZ], file[NAMESIZE], tfile[NAMESIZE];
 387:     char tfull[MAXFULLNAME];
 388: 
 389:     if((fp = fopen(subfile(xfile), "r")) == NULL)
 390:         return;
 391: 
 392:     while (fgets(buf, BUFSIZ, fp) != NULL) {
 393:         if (buf[0] != X_RQDFILE)
 394:             continue;
 395:         if (sscanf(&buf[1], "%s%s", file, tfile) < 2)
 396:             continue;
 397:         sprintf(tfull, "%s/%s", XQTDIR, tfile);
 398:         unlink(subfile(tfull));
 399:     }
 400:     fclose(fp);
 401:     return;
 402: }
 403: 
 404: 
 405: /***
 406:  *	mvxfiles(xfile)		move execute files to x-directory
 407:  *	char *xfile;
 408:  *
 409:  *	return codes - none
 410:  */
 411: 
 412: mvxfiles(xfile)
 413: char *xfile;
 414: {
 415:     register FILE *fp;
 416:     char buf[BUFSIZ], ffile[MAXFULLNAME], tfile[NAMESIZE];
 417:     char tfull[MAXFULLNAME];
 418:     int ret;
 419: 
 420:     if((fp = fopen(subfile(xfile), "r")) == NULL)
 421:         return;
 422: 
 423:     while (fgets(buf, BUFSIZ, fp) != NULL) {
 424:         if (buf[0] != X_RQDFILE)
 425:             continue;
 426:         if (sscanf(&buf[1], "%s%s", ffile, tfile) < 2)
 427:             continue;
 428:         expfile(ffile);
 429:         sprintf(tfull, "%s/%s", XQTDIR, tfile);
 430:         /* duke!rti, ncsu!mcm: use xmv, not link(II) */
 431:         unlink(subfile(tfull));
 432:         ret = xmv(ffile, tfull);
 433:         ASSERT(ret == 0, "XQTDIR ERROR", "", ret);
 434:     }
 435:     fclose(fp);
 436:     return;
 437: }
 438: 
 439: 
 440: /***
 441:  *	argok(xc, cmd)		check for valid command/argumanet
 442:  *			*NOTE - side effect is to set xc to the
 443:  *				command to be executed.
 444:  *	char *xc, *cmd;
 445:  *
 446:  *	return 0 - ok | 1 nok
 447:  */
 448: 
 449: argok(xc, cmd)
 450: register char *xc, *cmd;
 451: {
 452:     register char **ptr;
 453: 
 454: #ifndef ALLOK
 455:     /* don't allow sh command strings `....` */
 456:     /* don't allow redirection of standard in or out  */
 457:     /* don't allow other funny stuff */
 458:     /* but there are probably total holes here */
 459:     /* post-script.  ittvax!swatt has a uuxqt that solves this. */
 460:     /* This version of uuxqt will shortly disappear */
 461:     if (index(cmd, '`') != NULL
 462:       || index(cmd, '>') != NULL
 463:       || index(cmd, ';') != NULL
 464:       || index(cmd, '^') != NULL
 465:       || index(cmd, '&') != NULL
 466:       || index(cmd, '|') != NULL
 467:       || index(cmd, '<') != NULL)
 468:         return(1);
 469: #endif
 470: 
 471:     if (xc[0] != '\0')
 472:         return(0);
 473: 
 474: #ifndef ALLOK
 475:     ptr = Cmds;
 476:     while(*ptr != NULL) {
 477:         if (strcmp(cmd, *ptr) == SAME)
 478:             break;
 479:     ptr++;
 480:     }
 481:     if (*ptr == NULL)
 482:         return(1);
 483: #endif
 484:     strcpy(xc, cmd);
 485:     return(0);
 486: }
 487: 
 488: 
 489: /***
 490:  *	notify	send mail to user giving execution results
 491:  *	return code - none
 492:  *	This program assumes new mail command - send remote mail
 493:  */
 494: 
 495: notify(user, rmt, cmd, str)
 496: char *user, *rmt, *cmd, *str;
 497: {
 498:     char text[MAXFULLNAME];
 499:     char ruser[MAXFULLNAME];
 500: 
 501:     sprintf(text, "uuxqt cmd (%.50s) status (%s)", cmd, str);
 502:     if (prefix(rmt, Myname))
 503:         strcpy(ruser, user);
 504:     else
 505:         sprintf(ruser, "%s!%s", rmt, user);
 506:     mailst(ruser, text, "");
 507:     return;
 508: }
 509: 
 510: /***
 511:  *	retosndr - return mail to sender
 512:  *
 513:  *	return code - none
 514:  */
 515: 
 516: retosndr(user, rmt, file)
 517: char *user, *rmt, *file;
 518: {
 519:     char ruser[100];
 520: 
 521:     if (strcmp(rmt, Myname) == SAME)
 522:         strcpy(ruser, user);
 523:     else
 524:         sprintf(ruser, "%s!%s", rmt, user);
 525: 
 526:     if (anyread(file) == 0)
 527:         mailst(ruser, "Mail failed.  Letter returned to sender.\n", file);
 528:     else
 529:         mailst(ruser, "Mail failed.  Letter returned to sender.\n", "");
 530:     return;
 531: }

Defined functions

argok defined in line 449; used 1 times
cleanup defined in line 290; used 1 times
gotfiles defined in line 347; used 1 times
gtxfile defined in line 309; used 1 times
main defined in line 40; never used
mvxfiles defined in line 412; used 1 times
notify defined in line 495; used 2 times
retosndr defined in line 516; used 1 times
rmxfiles defined in line 382; used 1 times

Defined variables

Cmds defined in line 26; used 8 times
PATH defined in line 31; used 2 times
nonzero defined in line 29; used 4 times
notiok defined in line 28; used 3 times
sccsid defined in line 2; never used

Defined macros

APPCMD defined in line 14; used 2 times
NCMDS defined in line 25; used 2 times
Last modified: 1983-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1318
Valid CSS Valid XHTML 1.0 Strict