Annotation of 43BSDReno/old/berknet/net.c, revision 1.1.1.1

1.1       root        1: static char sccsid[] = "@(#)net.c      4.2     (Berkeley)      9/12/82";
                      2: 
                      3: /* sccs id variable */
                      4: static char *net_sid = "@(#)net.c      1.8";
                      5: 
                      6: # include "defs.h"
                      7: /* must be setuid root */
                      8: /*
                      9:        net - -b -c cmd -f -i file -l name -mmach -n -o file -p passwd
                     10:                -r file -s file -u uid -w -x -y -z command
                     11:                
                     12:        -       take from standard input
                     13:        -b      never send anything back
                     14:        -c cmd  think of this as a "cmd" *
                     15:        -f      force prompting of user name and password
                     16:        -i file remote stdin *
                     17:        -l name remote login name
                     18:        -m Mach remote machine
                     19:        -n      do not write back anything, always mail them back
                     20:        -o file remote stdout & stderr *
                     21:        -p pass remote password
                     22:        -q      quiet option, send back only if rcode !=0 or if there is stdout
                     23:        -r file local response file
                     24:        -s file local stdin file *
                     25:        
                     26:        (super users only, always skip login/passwd check:)
                     27:        -u uid  net queue files should be owned by uid (16 bits)
                     28:        -w      this is a write/mail response cmd *
                     29:        -x      this is being forwarded through us to another machine *
                     30:        -y      skip login/password check *
                     31:        -z      this is a response file being returned *
                     32: 
                     33:        * = not documented in net(NEW)
                     34:        
                     35: */
                     36: /*
                     37:        code    option  reason
                     38:        q               normal request
                     39:        w       -w      message to be written back
                     40:                -x      being forwarded through us
                     41:        y       -y      simply skips login check (used by netlpr)
                     42:        s       -z      normal response
                     43: */
                     44: /* global variables */
                     45: struct userinfo status;
                     46: 
                     47: /* local variables */
                     48: static char dfname[]=          DFNAME;
                     49: 
                     50: main(argc, argv)
                     51:   char **argv; {
                     52:        register int i;
                     53:        int outerror(),uid;
                     54:        char localin[FNS], skey[30];
                     55:        char buf[BUFSIZ], suid[10];
                     56:        char sin =0, zopt = 0, wopt = 0, yopt = 0, xopt = 0;
                     57:        char *s,**sargv;
                     58:        long cnt = 0L, maxfile = MAXFILELARGE;
                     59:        FILE *file, *temp, *rfile;
                     60:        struct utmp *putmp;
                     61:        struct stat statbuf;
                     62:        struct header hd;
                     63: 
                     64:        debugflg = DBV;
                     65:        hd.hd_scmdact[0] = hd.hd_srespfile[0] = hd.hd_soutfile[0] = 0;
                     66:        hd.hd_sinfile[0] = hd.hd_scmdvirt[0] = hd.hd_sttyname[0] = 0;
                     67:        localin[0] = 0;
                     68:        suid[0] = 0;
                     69:        sargv = argv;
                     70: 
                     71:        if(isatty(0)) strcat(hd.hd_sttyname,ttyname(0));
                     72:        else if(isatty(2)) strcat(hd.hd_sttyname,ttyname(2));
                     73:        remote = 0;
                     74:        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
                     75:                signal(SIGHUP, outerror);
                     76:        if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
                     77:                signal(SIGQUIT, outerror);
                     78:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
                     79:                signal(SIGINT, outerror);
                     80:        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
                     81:                signal(SIGTERM, outerror);
                     82: 
                     83:        while(argc > 1 && argv[1][0] == '-'){
                     84:                argc--; argv++;
                     85:                switch(argv[0][1]){
                     86:                case 0:   
                     87:                        sin++; 
                     88:                        break;
                     89:                case 'b': 
                     90:                        status.nonotify++; 
                     91:                        break;
                     92:                case 'c': 
                     93:                        harg(hd.hd_scmdvirt); 
                     94:                        break;
                     95:                case 'f': 
                     96:                        status.force++; 
                     97:                        break;
                     98:                case 'i': 
                     99:                        harg(hd.hd_sinfile); 
                    100:                        break;
                    101:                case 'l': 
                    102:                        harg(status.login); 
                    103:                        break;
                    104:                case 'm': 
                    105:                        harg(buf); 
                    106:                        remote = lookup(buf);
                    107:                        if(remote == 0){
                    108:                                fprintf(stderr,"Unknown machine %s\n",buf);
                    109:                                exit(EX_NOHOST);
                    110:                        }
                    111:                        break;
                    112:                case 'n': 
                    113:                        status.nowrite++; 
                    114:                        break;
                    115:                case 'o': 
                    116:                        harg(hd.hd_soutfile); 
                    117:                        break;
                    118:                case 'p':
                    119:                        harg(status.mpasswd);
                    120:                        if(status.mpasswd[0] == 0)
                    121:                                strcpy(status.mpasswd,"\n\n");
                    122:                        break;
                    123:                case 'q': 
                    124:                        status.quiet++; 
                    125:                        break;
                    126:                case 'r': 
                    127:                        harg(buf); 
                    128:                        addir(hd.hd_srespfile,buf); 
                    129:                        break;
                    130:                case 's': 
                    131:                        harg(localin); 
                    132:                        break;
                    133:                case 'u': 
                    134:                        harg(suid); 
                    135:                        break;
                    136:                case 'w': 
                    137:                        wopt++; 
                    138:                        break;
                    139:                case 'x': 
                    140:                        xopt++; 
                    141:                        break;
                    142:                case 'y': 
                    143:                        yopt++; 
                    144:                        break;
                    145:                case 'z': 
                    146:                        zopt++; 
                    147:                        break;
                    148:                default:
                    149:                        fprintf(stderr,"Unknown option %s\n",argv[0]);
                    150:                        break;
                    151:                }
                    152:                }
                    153:        while(argc > 1){
                    154:                argc--; argv++;
                    155:                strcat(hd.hd_scmdact,argv[0]);
                    156:                strcat(hd.hd_scmdact," ");
                    157:                }
                    158:        sargv[1] = 0;           /* so ps won't show passwd ??? */
                    159:        hd.hd_uidfrom = uid = getuid();
                    160:        hd.hd_gidfrom = getgid();
                    161:        hd.hd_code = 'q';
                    162:        if(zopt || wopt || yopt || xopt || suid[0] != 0){
                    163:                /* check z or w or y or x option permission */
                    164: # ifndef TESTING
                    165:                /* check effective user id ?? */
                    166:                if (uid != SUPERUSER && uid != NUID) {
                    167:                        fprintf(stderr, "Error: Not super-user\n");
                    168:                        fprintf(stderr,"zopt %d wopt %d yopt %d xopt %d suid[0] %s\n", zopt, wopt, yopt, xopt, suid);
                    169:                        fprintf(stderr,"uid %d\n", uid);
                    170:                        debugflg = 1;
                    171:                        printhd(&hd);
                    172:                        outerror(EX_UNAVAILABLE);
                    173:                        }
                    174: # endif
                    175:                hd.hd_code = zopt? 's': 'w';
                    176:                hd.hd_code = yopt? 'y': hd.hd_code;
                    177:                if (status.mpasswd[0] == 0)     /* no passwd required */
                    178:                        strcpy(status.mpasswd, "\n");
                    179:                debug("zopt %d wopt %d yopt %d xopt %d suid[0] %s\n", zopt, wopt, yopt, xopt, suid);
                    180:                debug("uid %d\n", uid);
                    181:                if(xopt)
                    182:                        setuid(SUPERUSER);
                    183:        }
                    184: #ifdef CRN
                    185:        strcpy( status.jobno, MAGICCRN );       /* default (invalid) crn */
                    186: #else
                    187:        strcpy( status.jobno, "XYZZ");          /* default (invalid) crn */
                    188: #endif
                    189: 
                    190:        if(hd.hd_code == 'q' && !xopt){
                    191:                /* read passwd file, get status.localname & crn */
                    192:                passwdent();
                    193:        }
                    194: 
                    195:        /* sets remote,status.login,status.force,status.mpasswd,
                    196:                status.nonotify, status.nowrite */
                    197:        /* may read passwd file if getenv(HOME) reads it */
                    198:        commandfile();
                    199:        if(status.force)status.login[0] = status.mpasswd[0] = 0;
                    200: 
                    201:        /* look up login name and passwd in the environment */
                    202:        envloginpasswd(remote,status.login,status.mpasswd);
                    203: 
                    204: 
                    205:        if(remote == 0)remote = getremote(local);
                    206: # ifndef TESTING
                    207:        if(remote == local){
                    208:                fprintf(stderr,"Request sent to local machine - doesn't make sense\n");
                    209:                /* outerror(); */
                    210:                }
                    211: # endif
                    212:        strcat(status.defcmd," ");
                    213:        if(strlen(hd.hd_scmdact) == 0)strcpy(hd.hd_scmdact,status.defcmd);
                    214:        hd.hd_scmdact[strlen(hd.hd_scmdact)-1] = 0;
                    215:        do {
                    216:                mktemp(dfname); /* make until unique!! */
                    217:        } while(stat(dfname,&statbuf) >= 0);
                    218:        /* determine through machine */
                    219:        i = gothru(local,remote);
                    220:        if(i == 0){
                    221:                s = longname(remote);
                    222:                if(s != 0)fprintf(stderr,"No path to %s machine.\n",s);
                    223:                else fprintf(stderr,"Unknown machine\n");
                    224:                outerror(EX_NOHOST);
                    225:                }
                    226:        dfname[strlen(dfname)-11] = i;          /* set directory */
                    227:        dfname[strlen(dfname)-7] = i;           /* set file (unused) */
                    228:        /* check to see if data files are directories */
                    229:        if(isdirectory(hd.hd_srespfile) || isdirectory(hd.hd_sinfile) || isdirectory(hd.hd_soutfile)){
                    230:                fprintf(stderr,"%s is a directory, must be a file\n",
                    231:                        isdirectory(hd.hd_srespfile)    ? hd.hd_srespfile :
                    232:                        isdirectory(hd.hd_sinfile)  ? hd.hd_sinfile :
                    233:                        hd.hd_soutfile);
                    234:                outerror(EX_USAGE);
                    235:        }
                    236:        if(suid[0] != 0)uid = atoi(suid);
                    237:        if(hd.hd_srespfile[0]){
                    238:                if(strcmp(hd.hd_srespfile,"/dev/tty") == 0){
                    239:                fprintf(stderr,"Can't have /dev/tty as response file.\n");
                    240:                        outerror(EX_USAGE);
                    241:                        }
                    242:                if(stat(hd.hd_srespfile,&statbuf) == -1){
                    243:                        strcpy(buf,hd.hd_srespfile);
                    244:                        s = &buf[0];
                    245:                        s = s + strlen(buf) - 1;
                    246:                        while(*s != '/' && s > &(buf[0]))s--;
                    247:                        *s = 0;
                    248:                        debug("chkdir %s",buf);
                    249:                        if(strlen(buf) == 0)strcpy(buf,".");
                    250:                        if(access(buf,2) == -1){
                    251:                                perror(buf);
                    252:                                outerror(EX_USAGE);
                    253:                                }
                    254:                        if((rfile=fopen(hd.hd_srespfile,"w")) == NULL){
                    255:                                perror(hd.hd_srespfile);
                    256:                                outerror(EX_USAGE);
                    257:                                }
                    258:                        chmod(hd.hd_srespfile,0600);
                    259:                        fclose(rfile);
                    260:                        mchown(hd.hd_srespfile,uid,hd.hd_gidfrom);
                    261:                        }
                    262:                else if(access(hd.hd_srespfile,2) == -1){
                    263:                        perror(hd.hd_srespfile);
                    264:                        outerror(EX_USAGE);
                    265:                        }
                    266:                else if(getsize(&statbuf) != 0L){
                    267:                        fprintf(stderr,"%s must have 0-length or not exist\n",
                    268:                                hd.hd_srespfile);
                    269:                        outerror(EX_USAGE);
                    270:                }
                    271:        }
                    272:        /* go ahead and prompt for login name and passwd, if neccessary,
                    273:           as long as the X option has not been specified */
                    274:        if(hd.hd_code == 'q' && !xopt)promptlogin(remote);
                    275: 
                    276:        /* at this point, we create the dfa... file */
                    277:        file = fopen(dfname,"w");
                    278:        if(file == NULL){
                    279:                perror(dfname);
                    280:                outerror(EX_OSERR);
                    281:                }
                    282:        chmod(dfname,0600);
                    283:        mchown(dfname,uid,getgid());
                    284:        if(xopt)goto stickit;
                    285:        if(status.mpasswd[0] == '\n')
                    286:                status.mpasswd[0] = 0;
                    287:        if(status.mpasswd[0] == 0 && hd.hd_code == 'q' &&
                    288:                strcmp(status.login,"network") != 0){
                    289:                fprintf(stderr,"Zero-length password not allowed\n");
                    290:                outerror(EX_USAGE);
                    291:                }
                    292:        if(hd.hd_code == 'q' && (streql(status.login,"root") == 0 ||
                    293:                streql(status.login,"ruut") == 0)){
                    294:                fprintf(stderr,"Can't login as root through the network\n");
                    295:                outerror(EX_USAGE);
                    296:                }
                    297:        makeuukey(skey,status.login,remote);
                    298:        nbsencrypt(status.mpasswd,skey,hd.hd_sencpasswd);
                    299:        enmask(status.mpasswd);
                    300:        hd.hd_lttytime = 0;
                    301:        if(hd.hd_sttyname[0] && status.nowrite == 0){
                    302:                putmp = getutmp(hd.hd_sttyname);
                    303:                if(putmp != NULL) hd.hd_lttytime = putmp->ut_time;
                    304:        }
                    305: /*
                    306:        debug("p:%s:\n",status.mpasswd);
                    307: */
                    308:        /* write the header info onto 'file' */
                    309:        hd.hd_mchto = remote;
                    310:        hd.hd_mesgid.msg_mch = hd.hd_mchfrom = local;
                    311:        hd.hd_vmajor = VMAJOR;
                    312:        hd.hd_vminor = VMINOR;
                    313:        strcpy(hd.hd_snto,status.login);
                    314:        strcpy(hd.hd_snfrom,status.localname);
                    315:        strcpy(hd.hd_spasswd,status.mpasswd);
                    316:        strcpy(hd.hd_ijobno, status.jobno );
                    317:        hd.hd_mesgid.msg_ltime = hd.hd_ltimesent = gettime();
                    318:        hd.hd_fquiet = status.quiet;
                    319:        hd.hd_fnonotify = status.nonotify;
                    320:        hd.hd_mesgid.msg_pid = getpid();
                    321:        hd.hd_fcompressed = 0;
                    322:        /* handle account pairs, accounts which do not require
                    323:           a passwd if you are logged in on the same one here */
                    324:        hd.hd_facctpair = fisacctpair(&hd);
                    325: 
                    326:        writehdfd(&hd,file);
                    327:        printhd(&hd);
                    328: stickit:
                    329:        if(sin)
                    330:                while((i = fread(buf,1,BUFSIZ,stdin)) > 0){
                    331:                        if(fwrite(buf,1,i,file) != i){
                    332:                                perror("net queue file");
                    333:                                outerror(EX_OSFILE);
                    334:                                }
                    335:                        if((cnt += i) > maxfile)goto toobig;
                    336:                        if(feof(stdin))break;
                    337:                        }
                    338:        else if(localin[0]){
                    339:                if(access(localin,4) == -1){
                    340:                        perror(localin);
                    341:                        outerror(EX_OSFILE);
                    342:                        }
                    343:                temp = fopen(localin,"r");
                    344:                if(temp == NULL){
                    345:                        perror(localin);
                    346:                        outerror(EX_OSFILE);
                    347:                        }
                    348:                while((i = fread(buf,1,BUFSIZ,temp)) > 0){
                    349:                        if((cnt += i) > maxfile)goto toobig;
                    350:                        if(fwrite(buf,1,i,file) != i){
                    351:                                perror("net queue file");
                    352:                                outerror(EX_OSFILE);
                    353:                                }
                    354:                        }
                    355:                fclose(temp);
                    356:                }
                    357:        fclose(file);
                    358:        chmod(dfname,0400);
                    359:        dfname[strlen(dfname)-9] = 'c';
                    360:        file = fopen(dfname,"w");
                    361:        chmod(dfname,0400);
                    362:        fclose(file);
                    363:        mchown(dfname,uid,getgid());
                    364:        exit(EX_OK);
                    365: toobig:
                    366:        fprintf(stderr,"No more than %ld bytes can be sent\n",maxfile);
                    367:        outerror(EX_USAGE);             /* no return */
                    368:        }
                    369: /* 
                    370:    called if there is an error, makes sure that the files created
                    371:    are deleted and the terminal is reset to echo
                    372: */
                    373: outerror(ret){
                    374:        register int i;
                    375:        struct sgttyb stt;
                    376:        signal(SIGHUP,SIG_IGN); signal(SIGINT,SIG_IGN);
                    377:        signal(SIGQUIT,SIG_IGN); signal(SIGTERM,SIG_IGN);
                    378:        unlink(dfname);
                    379:        i = strlen(dfname) - 9;
                    380:        dfname[i] = (dfname[i] == 'c' ? 'd' : 'c');
                    381:        unlink(dfname);
                    382:        if(gtty(0,&stt) >= 0){
                    383:                stt.sg_flags |= ECHO;
                    384:                stty(0,&stt);
                    385:                }
                    386:        exit(ret);
                    387:        }
                    388: enmask(s)
                    389:   register char *s; {
                    390:        while(*s){
                    391:                *s &= 0177;             /* strip quote bites */
                    392:                *s++ ^= 040;            /* invert upper-lower */
                    393:                }
                    394:        }
                    395: addir(s,t)
                    396:   register char *s, *t; {
                    397:        if(t[0] == '/')strcpy(s,t);
                    398:        else {
                    399:                gwd(s);
                    400:                strcat(s,t);
                    401:                }
                    402:        }
                    403: 
                    404: /* returns true if phd is an account pair, false otherwise */
                    405: fisacctpair(phd)
                    406: register struct header *phd; 
                    407: {
                    408:        return(0);
                    409: }
                    410: 
                    411: 
                    412: 
                    413: static struct stat x;
                    414: static struct direct y;
                    415: static int off = -1;
                    416: 
                    417: 
                    418: /* these three routines gwd, cat, ckroot and 
                    419:    data structures x, y, off, do a pwd to string name */
                    420: #ifdef V6
                    421: static FILE *file;
                    422: 
                    423: gwd(name)
                    424:   register char *name; {
                    425:        *name = 0;
                    426:        for(;;){
                    427:                stat(".",&x);
                    428:                if((file = fopen("..","r")) == NULL)break;
                    429:                do {
                    430:                        if(fread(&y,1,sizeof y,file) != sizeof y)break;
                    431:                        } while(y.d_ino != x.st_ino);
                    432:                fclose(file);
                    433:                if(y.d_ino == ROOTINO){
                    434:                        ckroot(name);
                    435:                        break;
                    436:                        }
                    437:                if(cat(name))break;
                    438:                chdir("..");
                    439:                }
                    440:        chdir(name);
                    441:        }
                    442: ckroot(name)
                    443:   char *name; {
                    444:        register int i;
                    445:        if(stat(y.d_name,&x) < 0)return;
                    446:        i = x.st_dev;
                    447:        if(chdir("/") < 0)return;
                    448:        if((file = fopen("/","r")) == NULL)return;
                    449:        do {
                    450:                if(fread(&y,1,sizeof y,file) != sizeof y)return;
                    451:                if(y.d_ino == 0)continue;
                    452:                if(stat(y.d_name,&x) < 0)return;
                    453:                } while(x.st_dev!=i || (x.st_mode&S_IFMT)!=S_IFDIR);
                    454:        if(strcmp(y.d_name,".") != 0 && strcmp(y.d_name,"..") != 0)
                    455:                if(cat(name))return;
                    456:        i = strlen(name);
                    457:        name[i+1] = 0;
                    458:        while(--i >= 0)name[i + 1] = name[i];
                    459:        name[0] = '/';
                    460:        return;
                    461:        }
                    462: #else
                    463: static DIR *file;
                    464: static struct stat xx;
                    465: 
                    466: gwd(name)
                    467:   register char *name;  {
                    468:        int rdev, rino;
                    469:        register int i;
                    470:        register struct direct *dp;
                    471: 
                    472:        *name = 0;
                    473:        stat("/", &x);
                    474:        rdev = x.st_dev;
                    475:        rino = x.st_ino;
                    476:        for (;;) {
                    477:                stat(".", &x);
                    478:                if (x.st_ino == rino && x.st_dev == rdev)
                    479:                        break;
                    480:                if ((file = opendir("..")) == NULL)
                    481:                        break;
                    482:                fstat(file->dd_fd, &xx);
                    483:                chdir("..");
                    484:                if (x.st_dev == xx.st_dev) {
                    485:                        if (x.st_ino == xx.st_ino)
                    486:                                break;
                    487:                        do
                    488:                                if ((dp = readdir(file)) == NULL)
                    489:                                        break;
                    490:                        while (dp->d_ino != x.st_ino);
                    491:                }
                    492:                else do {
                    493:                        if ((dp = readdir(file)) == NULL)
                    494:                                break;
                    495:                        stat(dp->d_name, &xx);
                    496:                } while (xx.st_ino != x.st_ino || xx.st_dev != x.st_dev);
                    497:                blkcpy(dp, &y, DIRSIZ(dp));
                    498:                closedir(file);
                    499:                if (cat(name))
                    500:                        break;
                    501:        }
                    502:        i = strlen(name);
                    503:        name[i+1] = 0;
                    504:        while (--i >= 0) name[i+1] = name[i];
                    505:        name[0] = '/';
                    506: }
                    507: #endif
                    508: 
                    509: cat(name)
                    510:   register char *name; {               /* return 1 to exit */
                    511:        register int i,j;
                    512:        i = -1;
                    513:        while(y.d_name[++i] != 0);
                    514:        if((off+i+2) > 511)return(1);
                    515:        for(j = off +1; j >= 0; --j)name[j+i+1] = name[j];
                    516:        off = i + off + 1;
                    517:        name[i] = '/';
                    518:        for(--i; i>= 0; --i)name[i] = y.d_name[i];
                    519:        return(0);
                    520:        }
                    521: 
                    522: 
                    523: /*
                    524:        this function takes a file name and tells whether it is a 
                    525:        directory or on. Returns 1 if so, 0 otherwise.
                    526:        null strings etc. return 0.
                    527: */
                    528: isdirectory(fn)
                    529:        char *fn;
                    530: {
                    531:        int i,ret=0;
                    532:        if(fn == NULL || *fn == 0)return(0);
                    533:        i = strlen(fn);
                    534:        if(i == 1){
                    535:                if(strcmp(fn,".")       == 0)ret = 1;
                    536:                if(strcmp(fn,"/")       == 0)ret = 1;
                    537:        }
                    538:        else if(i == 2){
                    539:                if(strcmp(fn,"..")      == 0)ret = 1;
                    540:                if(strcmp(fn,"/.")      == 0)ret = 1;
                    541:        }
                    542:        else {
                    543:                if(strcmp(fn+i-2,"/.")  == 0)ret = 1;
                    544:                if(strcmp(fn+i-3,"/..") == 0)ret = 1;
                    545:        }
                    546:        return(ret);
                    547: }
                    548: 
                    549: blkcpy(from, to, size)
                    550:        register *from, *to;
                    551:        register int size;
                    552: {
                    553:        while (size-- > 0)
                    554:                *to++ = *from++;
                    555: }

unix.superglobalmegacorp.com

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