Annotation of 42BSD/usr.bin/uucp/uuxqt.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.