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_fcompress = 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: }

Defined functions

addir defined in line 350; used 1 times
cat defined in line 395; used 2 times
ckroot defined in line 408; used 1 times
enmask defined in line 343; used 1 times
fisacctpair defined in line 360; used 1 times
gwd defined in line 375; used 1 times
isdirectory defined in line 433; used 5 times
main defined in line 45; never used
outerror defined in line 328; used 21 times

Defined variables

dfname defined in line 43; used 20 times
off defined in line 370; used 4 times
status defined in line 40; used 37 times
x defined in line 367; used 7 times
y defined in line 368; used 15 times
Last modified: 1980-07-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1281
Valid CSS Valid XHTML 1.0 Strict