|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.