Annotation of 41BSD/cmd/berknet/net.c, revision 1.1.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.