Annotation of 40BSD/cmd/berknet/net.c, revision 1.1

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

unix.superglobalmegacorp.com

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