|
|
1.1 ! root 1: /* ! 2: The daemon program that runs the network. ! 3: ! 4: netdaemon mach readfd writefd ! 5: ! 6: Must be started by root. ! 7: */ ! 8: ! 9: # include "defs.h" ! 10: ! 11: /* global variables */ ! 12: extern char **environ; ! 13: short masterseqno, lastseqno; ! 14: struct dumpstruc dump; ! 15: struct bstruct btable[]; ! 16: int onlyuid; ! 17: ! 18: /* local variables */ ! 19: static long length; ! 20: static char nsendfail; ! 21: static FILE *dir; ! 22: static char header[] = "ABCDE"; ! 23: static char tempfile[]= TEMPFILE; ! 24: static char publogfile[]= PUBLOGFILE; ! 25: static char dumpfile[]= DUMPFILE; ! 26: static char namefile[]= NAMEFILE; ! 27: static struct stat statbuf; ! 28: static struct direct dirbuf; ! 29: int handlekill(); ! 30: static char frommach; ! 31: static char buf[BUFSIZ]; ! 32: /* addrfrom is the person who sent this to us, ! 33: addrto is the person who received the command, i.e. ! 34: addrto is on this machine */ ! 35: static char addrto[BUFSIZ], addrfrom[BUFSIZ]; ! 36: ! 37: main(argc,argv) ! 38: char **argv; { ! 39: register int i; ! 40: long ltime,t; ! 41: ! 42: signal(SIGTRM,handlekill); ! 43: debugflg = DBV; ! 44: setupdaemon(argc,argv); ! 45: /* now running alone as a daemon */ ! 46: /* ! 47: for(i=0; i<15; i++)close(i); ! 48: signal(SIGHUP,SIG_IGN); ! 49: signal(SIGQUIT,SIG_IGN); ! 50: signal(SIGINT,SIG_IGN); ! 51: */ ! 52: senddir[strlen(senddir)-1] = remote; /* choose dir */ ! 53: if(chdir(senddir) < 0){ ! 54: perror(senddir); ! 55: exit(1); ! 56: } ! 57: dir = fopen(senddir,"r"); ! 58: if(dir == NULL){ ! 59: perror(senddir); ! 60: exit(1); ! 61: } ! 62: mktemp(tempfile); ! 63: tempfile[strlen(tempfile) - 7] = remote; ! 64: ltime = gettime(); ! 65: sprintf(buf,"net restarted to %s %d %s",longname(remote), ! 66: getpid(),ctime(<ime)); ! 67: dump.longtime = dump.shorttime = ltime; ! 68: addtolog(remote,buf); ! 69: addtodump(remote,buf); ! 70: addtopublic(buf); ! 71: fprintf(stderr,buf); ! 72: if(!debugflg)fclose(stderr); ! 73: sendpurge(); ! 74: nsendfail = 0; ! 75: for(;;){ /* begin reading file */ ! 76: debug("daemon %c %d\nreceive",remote,getpid()); ! 77: i = getreset(); ! 78: dump.waittime = 0L; ! 79: if(i == BROKENREAD){ ! 80: if(nsendfail < NSEND) netsend(); ! 81: else nsendfail++; ! 82: } ! 83: else { ! 84: i = netrcv(); ! 85: if(i >= 0){ ! 86: nsendfail = 0; /* it sent, it is up */ ! 87: dump.waittot += dump.waittime; ! 88: } ! 89: if(i == -1)dump.nabnormal++; ! 90: } ! 91: t = gettime(); ! 92: if(t - dump.shorttime > SAMPL)pload(t); ! 93: if(t - dump.longtime > BIGSAMPL)dumpit(t); ! 94: dump.nloop++; ! 95: /* count up to NSEND, sending, then wait NSEND */ ! 96: if(nsendfail >= NSEND*2)nsendfail = 0; ! 97: } ! 98: } ! 99: netsend(){ ! 100: static long lasttime = 0; ! 101: static char nleft = 1; ! 102: long lFileLen,diff; ! 103: double drate; ! 104: int uid,uidBest; ! 105: char *sdate,*sn,*swait; ! 106: long ot,nt,filesize; ! 107: register int i; ! 108: char stemp[20]; ! 109: static char jname[FNS]; ! 110: ! 111: debug("ck send"); ! 112: if(stat(senddir,&statbuf) < 0){ ! 113: error("%s %s",senddir,sys_errlist[errno]); ! 114: return; ! 115: } ! 116: if(statbuf.st_mtime == lasttime && nleft == 0)return; /* no need to search */ ! 117: lasttime = statbuf.st_mtime; ! 118: fseek(dir,0L,0); ! 119: lFileLen = 10000000L; ! 120: nleft = 0; ! 121: while(fread(&dirbuf,1,sizeof dirbuf,dir) == sizeof dirbuf){ ! 122: if(dirbuf.d_ino == 0 ! 123: || dirbuf.d_name[0] != 'c' ! 124: || dirbuf.d_name[1] != 'f' ! 125: || dirbuf.d_name[2] != remote ! 126: || stat(dirbuf.d_name,&statbuf) < 0 ! 127: || statbuf.st_mode == 0) ! 128: continue; ! 129: dirbuf.d_name[0] = 'd'; ! 130: if(stat(dirbuf.d_name,&statbuf) < 0 || statbuf.st_mode == 0) ! 131: continue; ! 132: uid = guid(statbuf.st_uid,statbuf.st_gid); ! 133: if(onlyuid != 0 && uid != onlyuid && uid != SUPERUSER)continue; ! 134: nleft++; ! 135: filesize = getsize(&statbuf); ! 136: if(lFileLen > filesize){ ! 137: lFileLen = filesize; ! 138: for(i=0; i<DIRSIZ; i++) ! 139: jname[i] = dirbuf.d_name[i]; ! 140: uidBest = uid; ! 141: } ! 142: } ! 143: if(lFileLen == 10000000L)return; ! 144: strcpy(stemp,jname); ! 145: stemp[0] = 'c'; ! 146: sn = SnFromUid(uidBest); ! 147: if(sn == NULL){ ! 148: addtolog(remote,"Unknown userid %d\n",uidBest); ! 149: return; ! 150: } ! 151: addtolog(remote,"^S %s %c: %s ",sn,remote,jname+2); ! 152: ot = gettime(); ! 153: dump.waittime = 0L; ! 154: if(send(jname) == 0)return; ! 155: nt = gettime(); ! 156: dump.waittot += dump.waittime; ! 157: filesize = getsize(&statbuf); ! 158: unlink(jname); ! 159: unlink(stemp); ! 160: diff = nt - ot; ! 161: if(diff < 1)diff = 1; /* avoid dividing by zero */ ! 162: sdate = ctime(&nt)+4; ! 163: sdate[strlen(sdate) -9] = 0; ! 164: drate = (double)filesize / (double)diff; ! 165: swait = comptime(ot - statbuf.st_mtime); ! 166: jname[3] = jname[2]; ! 167: addtolog(remote,"^T%c(%s, %ldb, %ldsec, %4.1fb/sec, w %s)\n", ! 168: remote,sdate,filesize, diff,drate, swait); ! 169: addtopublic("%s: sent %-8s to %c (%s, %ld b, wait %s)\n", ! 170: sdate,sn,remote,jname+3,filesize,swait); ! 171: dump.nsend++; ! 172: dump.bytetot += filesize; ! 173: dump.elaptot += diff; ! 174: /* add this users name to /usr/net/usernames */ ! 175: addtoname(sn); ! 176: } ! 177: send(jname) ! 178: char *jname; ! 179: { /* push those bytes */ ! 180: /* returns 0 if send fails, 1 otherwise */ ! 181: register int n; ! 182: int i; ! 183: long lsize; ! 184: char mbuf[BUFSIZ]; ! 185: register char *p; ! 186: FILE *jfile; ! 187: ! 188: debug("send %s",jname); ! 189: if(stat(jname,&statbuf) < 0)goto sfail; ! 190: lsize = getsize(&statbuf); ! 191: if(lsize < MINSIZE){ /* all files are at least this long */ ! 192: unlink(jname); ! 193: jname[0] = 'c'; ! 194: unlink(jname); ! 195: return(1); ! 196: } ! 197: jfile = fopen(jname,"r"); ! 198: if(jfile == NULL)goto sfail; ! 199: strcpy(mbuf,header); ! 200: i = strlen(header); ! 201: p = (char *)&lsize; ! 202: lsize = fixuplong(lsize); ! 203: mbuf[i] = *p++; ! 204: mbuf[i+1] = *p++; ! 205: mbuf[i+2] = *p++; ! 206: mbuf[i+3] = *p++; ! 207: i = i + 4; ! 208: sendreset(); ! 209: masterseqno = 1; ! 210: lastseqno = 0; ! 211: if(xwrite(mbuf,1,i) == WRITEFAIL)goto bwrite; ! 212: while((n=fread(buf,1,BLOCKSIZE,jfile)) > 0) ! 213: if(xwrite(buf,1,n) == WRITEFAIL)goto bwrite; ! 214: fclose(jfile); ! 215: debug("end send"); ! 216: nsendfail = 0; ! 217: return(1); ! 218: bwrite: ! 219: nsendfail++; ! 220: dump.nsendfail++; ! 221: fclose(jfile); ! 222: addtolog(remote,"^F%c\n",remote); ! 223: return(0); ! 224: sfail: ! 225: error("%s: %s",jname,sys_errlist[errno]); ! 226: dump.nsendfail++; ! 227: return(0); ! 228: } ! 229: netrcv(){ ! 230: /* returns -2 in normal fail, -1 in abnormal fail, >= 0 otherwise */ ! 231: char code, sin; ! 232: char tmach, fmach; ! 233: char mgetc(), cflag, *s; ! 234: register int n,i; ! 235: char vmajor, vminor, c; ! 236: int rcode, dummy, pid, uid; ! 237: char buf1[BUFSIZ], cmdstr[BUFSIZ]; ! 238: static char parmlist[PARMLIST]; ! 239: long timesent,otime,olength,diff,rcvfinish,nt,maxfile = MAXFILE; ! 240: double r; ! 241: static char resp[FNS], infile[FNS], outfile[FNS]; ! 242: static char hbuf[10]; ! 243: static FILE *temp; ! 244: ! 245: n = nread(hbuf,1,strlen(header)); ! 246: if(n == BROKENREAD)return(-2); ! 247: if(n != strlen(header) || strcmp(header,hbuf) != 0){ ! 248: error("wrong head %d %s",n,hbuf); ! 249: return(-1); ! 250: } ! 251: n = nread(&length,1,4); ! 252: if(n == BROKENREAD)return(-2); ! 253: if(n != 4){ ! 254: error("bad length nread %d",n); ! 255: return(-1); ! 256: } ! 257: length = fixuplong(length); ! 258: olength = length; ! 259: otime = gettime(); ! 260: debug("length = %ld\n",length); ! 261: i = 0; ! 262: ! 263: /* ! 264: begin parsing header ! 265: ! 266: from local to remote (requests) ! 267: code net option reason ! 268: q normal request ! 269: y -y simply skips login check (used by netlpr) ! 270: ! 271: from remote to local ! 272: code net option reason ! 273: w -w message to be written/mailed back ! 274: s -z normal response ! 275: */ ! 276: ! 277: code = mgetc(); ! 278: tmach = mgetc(); ! 279: if(tmach < 'a' || 'z' < tmach){ ! 280: error("bad tmach"); ! 281: return(-1); ! 282: } ! 283: if(tmach != local)goto forw; /* being forwarded through us */ ! 284: fmach = mgetc(); ! 285: vmajor = mgetc(); ! 286: vminor = mgetc(); ! 287: i += mgets(status.login,NS); ! 288: i += mgets(status.mpasswd,20); ! 289: demask(status.mpasswd); ! 290: i += mgets(infile,FNS); ! 291: i += mgets(outfile,FNS); ! 292: i += mgets(resp,FNS); ! 293: i += mgets(status.localname,NS); ! 294: ! 295: /* addrfrom is the person who sent this to us, ! 296: addrto is the person who received the command, i.e. ! 297: addrto is on this machine */ ! 298: if(status.localname[0] == 0)strcpy(status.localname,"root"); ! 299: sprintf(addrfrom, "%s:%s",longname(fmach),status.localname); ! 300: sprintf(addrto, "%s:%s",longname(tmach),status.login); ! 301: ! 302: i += mgets(status.sTtyname,20); ! 303: if(status.sTtyname[0] == 0)strcpy(status.sTtyname,"/dev/ttyx"); ! 304: cflag = mgetc(); ! 305: if(!fmach || !code || !cflag || !vmajor || !vminor){ ! 306: error("mgetc fails"); ! 307: return(-1); ! 308: } ! 309: cflag -= 'a'; ! 310: vmajor -= 'a'; ! 311: vminor -= 'a'; ! 312: if(vmajor != VMAJOR || vminor != VMINOR){ ! 313: /* ! 314: error("versions dont agree (%d,%d) vs. (%d,%d) remote", ! 315: VMAJOR,VMINOR,vmajor,vminor); ! 316: return(-1); ! 317: */ ! 318: } ! 319: i += mgets(buf,BUFSIZ); ! 320: status.lTtytime = 0; ! 321: sscanf(buf,"%lo",&status.lTtytime); ! 322: ! 323: i += mgets(parmlist,PARMLIST); ! 324: status.jobno = atoi(parmlist); ! 325: /* keep variable parameter list in jobno slot */ ! 326: parseparmlist(parmlist); ! 327: ! 328: i += mgets(buf1,BUFSIZ); /* time sent */ ! 329: sscanf(buf1,"%ld",×ent); ! 330: i += mgetcmd(status.sCmdAct); ! 331: i += mgetcmd(status.sCmdVirt); ! 332: if(i != 0){error("mgets fails"); return(-1);} ! 333: if(status.sCmdVirt[0] == 0)strcpy(status.sCmdVirt,status.sCmdAct); ! 334: s = status.sCmdVirt; ! 335: while(*s && *s != ' ')s++; ! 336: c = *s; ! 337: *s = 0; ! 338: if(strcmp(status.sCmdVirt,"netlpr") == 0)dump.nnetlpr++; ! 339: else if(strcmp(status.sCmdVirt,"netmail") == 0)dump.nnetmail++; ! 340: else if(strcmp(status.sCmdVirt,"mail") == 0)dump.nsmail++; ! 341: else if(strcmp(status.sCmdVirt,"netcp") == 0)dump.nnetcp++; ! 342: else if(strcmp(status.sCmdVirt,"response") == 0)dump.nresp++; ! 343: else dump.nnet++; ! 344: *s = c; ! 345: debug("%c %c %c (%c,%c) %s %s %s %s (%s) %s %c %lo %d %s\n", ! 346: code,tmach,fmach,vmajor+'a',vminor+'a',status.login, ! 347: infile,outfile,resp,status.localname, ! 348: status.sTtyname,cflag+'a',status.lTtytime,status.jobno,status.sCmdAct); ! 349: ! 350: ! 351: /* any chars left are data */ ! 352: forw: ! 353: sin = 0; ! 354: if(length > 0){ /* make a temp input file */ ! 355: increment(tempfile); ! 356: temp = fopen(tempfile,"w"); ! 357: if(temp == NULL){ ! 358: error("%s %s",tempfile,sys_errlist[errno]); ! 359: return(-1); ! 360: } ! 361: chmod(tempfile,0600); ! 362: if(tmach != local)fprintf(temp,"%c :%c :",code,tmach); ! 363: while((n = mread(buf,1,BLOCKSIZE)) > 0) ! 364: if(fwrite(buf,1,n,temp) != n){ ! 365: error("%s %s",tempfile,sys_errlist[errno]); ! 366: fclose(temp); ! 367: unlink(tempfile); ! 368: return(-1); ! 369: }; ! 370: fclose(temp); ! 371: if(n == BROKENREAD || length > 0){ ! 372: unlink(tempfile); ! 373: return(-2); ! 374: } ! 375: sin = 1; ! 376: if(tmach != local){ ! 377: diff = gettime() - otime; ! 378: if(diff < 1)diff = 1; /* avoid dividing by 0 */ ! 379: r = olength; ! 380: r = r/diff; ! 381: addtolog(remote,"^P(to %c, %ldb, %ldsec, %4.1fb/sec)\n", ! 382: tmach,olength,diff,r); ! 383: dump.npass++; ! 384: dump.bytetot += olength; ! 385: dump.elaptot += diff; ! 386: while((pid = fork()) == -1)sleep(2); ! 387: if(pid == 0){ ! 388: execl(netcmd,"net","-x","-m",longname(tmach), ! 389: "-s",tempfile,buf,0); ! 390: exit(1); ! 391: } ! 392: wait(&dummy); ! 393: unlink(tempfile); ! 394: return(1); ! 395: } ! 396: } ! 397: if(length > 0){error("file too short"); return(-1); } ! 398: rcvfinish = gettime(); ! 399: ! 400: while((pid = fork()) == -1)sleep(2); ! 401: if(pid > 0){ ! 402: wait(&dummy); ! 403: return(1); /* normal return */ ! 404: } ! 405: ! 406: while((pid = fork()) == -1)sleep(2); ! 407: if(pid != 0)exit(0); ! 408: ! 409: /* child process which forks and waits */ ! 410: mktemp(resfile); ! 411: while((pid = fork()) == -1)sleep(2); ! 412: if(pid == 0){ ! 413: /* child */ ! 414: strcpy(status.loginshell,Bsh); ! 415: frommach = fmach; ! 416: n = check(status.login,status.mpasswd,(code == 'q')); ! 417: if(!n)errormsg(fmach,"Bad remote login/password '%s'",status.login); ! 418: temp = fopen(resfile,"w"); ! 419: if(temp == NULL) ! 420: errormsg(fmach,"creat %s %s",resfile,sys_errlist[errno]); ! 421: chmod(resfile,0600); ! 422: fclose(temp); ! 423: mchown(resfile,status.muid,status.mgid); ! 424: if(sin) ! 425: mchown(tempfile,status.muid,status.mgid); ! 426: setuid(status.muid); ! 427: setgid(status.mgid); ! 428: uid = getuid(); ! 429: uid = uidmask(uid); ! 430: status.muid = uidmask(status.muid); ! 431: if(uid != status.muid)error("setuid fails"); ! 432: debug("uid: %o\n",uid); ! 433: /* check for allowed root commands, for security reasons */ ! 434: if(uid == SUPERUSER){ ! 435: s = status.sCmdAct; ! 436: while(*s && *s != ' ')s++; ! 437: c = *s; ! 438: *s = 0; ! 439: /* these are the only commands root may execute */ ! 440: if(strcmp(status.sCmdAct,"cat") != 0 ! 441: && strcmp(status.sCmdAct,CATCMD) != 0 ! 442: && strcmp(status.sCmdAct,FILECAT) != 0 ! 443: && strcmp(status.sCmdAct,MWRITECMD) != 0 ! 444: && strcmp(status.sCmdAct,"/usr/lib/tq") != 0 ! 445: && strcmp(status.sCmdAct,"/usr/lib/rtrrm") != 0 ! 446: && strcmp(status.sCmdAct,"lpr") != 0) ! 447: errormsg(fmach, ! 448: "Not allowed to execute '%s' as root", ! 449: status.sCmdAct); ! 450: *s = c; ! 451: } ! 452: if(chdir(status.dir) < 0) ! 453: errormsg(fmach,"chdir %s %s",status.dir,sys_errlist[errno]); ! 454: setenv(status.dir); /* set up v7 environment */ ! 455: if(sin)mreopen(fmach,tempfile,"r",stdin); ! 456: else if(infile[0])mreopen(fmach,infile,"r",stdin); ! 457: else mreopen(fmach,"/dev/null","r",stdin); ! 458: if(code == 's' && outfile[0]){ ! 459: if(stat(outfile,&statbuf) < 0 ! 460: || getsize(&statbuf) != 0 ! 461: || !(statbuf.st_mode&0600)) ! 462: errormsg(local,"Bad result file '%s'",outfile); ! 463: mreopen(fmach,outfile,"w",stdout); ! 464: } ! 465: else if(outfile[0]){ ! 466: temp = fopen(outfile,"w"); ! 467: if(temp == NULL) ! 468: errormsg(fmach,"fopen %s %s",outfile,sys_errlist[errno]); ! 469: fclose(temp); ! 470: mreopen(fmach,outfile,"w",stdout); ! 471: } ! 472: else mreopen(fmach,resfile,"a",stdout); ! 473: debug("exec '%s'\n",status.sCmdAct); ! 474: if(debugflg == 0){ ! 475: /* cheat */ ! 476: close(2); ! 477: dup(1); ! 478: /* ! 479: mreopen(fmach,resfile,"a",stderr); ! 480: */ ! 481: } ! 482: for(i=3;i<15;i++)close(i); ! 483: do { ! 484: mexecl(status.loginshell,"sh","-c",status.sCmdAct,0); ! 485: sleep(2); ! 486: } while(errno == ETXTBSY); ! 487: exit(1); ! 488: } ! 489: /* parent */ ! 490: wait(&rcode); ! 491: rcode >>= 8; ! 492: /* ! 493: fclose(stdin); ! 494: fclose(stdout); ! 495: fclose(stderr); ! 496: */ ! 497: if(sin)unlink(tempfile); ! 498: /* ! 499: now send something back to the sender ! 500: unless this was a response (file or message) ! 501: */ ! 502: if((code == 'q' || code == 'y') && (resp[0] || !(cflag&F_NONOTIFY))){ ! 503: /* send response back if a response file ! 504: was given or if mail/write is allowed */ ! 505: /* should give an error message for non-zero return codes */ ! 506: if(stat(resfile,&statbuf) < 0){ ! 507: error("%s %s",resfile,sys_errlist[errno]); ! 508: goto next; ! 509: } ! 510: /* allow larger files between the Ingres machines */ ! 511: if(machtype[local - 'a'] == M_INGRES ! 512: && machtype[remote - 'a'] == M_INGRES) ! 513: maxfile = MAXFILELARGE; ! 514: if(getsize(&statbuf) >= maxfile){ ! 515: errormsg(fmach,"Result file too large - not sent"); ! 516: goto next; ! 517: } ! 518: if(getsize(&statbuf) == 0){ ! 519: /* response file specified, no output generated */ ! 520: if(resp[0] != 0) goto next; ! 521: /* quiet option - no output and a rcode of 0 */ ! 522: if(rcode == 0 && (cflag&F_QUIET))goto next; ! 523: } ! 524: /* use both old and new mwrite parm lists */ ! 525: ! 526: if(resp[0])sprintf(cmdstr,"-o %s %s",resp,CATCMD); ! 527: else sprintf(cmdstr, ! 528: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -c \"'%s'\" -y %s -e %ld -r %d", ! 529: MWRITECMD, status.localname,status.sTtyname,status.lTtytime,tmach,status.login, status.sCmdVirt,timesent, ! 530: addrfrom, addrto, status.lTtytime, status.sCmdVirt, status.sTtyname, timesent, rcode); ! 531: sprintf(buf,"%s -m%c -z -b -l %s -s %s -c response %s", ! 532: netcmd,fmach,status.localname,resfile,cmdstr); ! 533: dummy = system(buf); /* execute command buf */ ! 534: } ! 535: next: ! 536: unlink(resfile); ! 537: s = ctime(&rcvfinish); ! 538: s += 4; ! 539: s[strlen(s) -8] = 0; ! 540: diff = rcvfinish - otime; ! 541: if(diff < 1)diff = 1; /* avoid dividing by zero */ ! 542: r = olength; ! 543: r = r/diff; ! 544: dump.bytetot += olength; ! 545: dump.elaptot += diff; ! 546: sprintf(buf,"%s rcv %c:%-8s (%s)", ! 547: s,fmach,status.localname,status.login); ! 548: addtolog(remote,"%s C: %s\n",buf,status.sCmdVirt); ! 549: addtopublic("%s R: %d C: %s\n",buf,rcode,status.sCmdVirt); ! 550: nt = rcvfinish - timesent - TIMEBASE; ! 551: buf[0] = 0; ! 552: if(nt > 0L)sprintf(buf," took (%s)",comptime(nt)); ! 553: addtolog(remote,"\t\tR: %d%s %ldb %ldsec %4.1fb/sec\n", ! 554: rcode,buf,olength,diff,r); ! 555: exit(0); ! 556: /*UNREACHED*/ ! 557: } ! 558: ! 559: /* ! 560: check() -- verify login name and password ! 561: snTo = login, ! 562: pass = passwd, ! 563: verify = 1 if password must check ! 564: Returns 1 if password is ok, 0 if not. ! 565: */ ! 566: check(snTo,pass,verify) /* 1 if OK, 0 if not */ ! 567: int verify; ! 568: char *snTo, *pass; { ! 569: int ver; ! 570: char *s, *u, *nullstr = ""; ! 571: struct passwd *pwd; ! 572: ver = (verify == 0); /* ver is true if password verification ! 573: was not requested */ ! 574: if(snTo[0] == 0)return(ver); ! 575: if(!goodacctname(snTo))return(ver); ! 576: pwd = getpwnam(snTo); ! 577: if(pwd == NULL)return(ver); ! 578: # ifndef NEWPROT ! 579: if(machtype[local-'a'] == M_CC && machtype[frommach-'a'] == M_CC) ! 580: s = pass; ! 581: else ! 582: # endif ! 583: if(*pass)s = crypt(pass,pwd->pw_passwd); ! 584: else s = nullstr; ! 585: status.muid = guid(pwd->pw_uid,pwd->pw_gid); ! 586: status.mgid = pwd->pw_gid; ! 587: if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos); ! 588: else status.jobno = 32767; ! 589: strcpy(status.dir,pwd->pw_dir); ! 590: strcpy(status.loginshell,pwd->pw_shell); ! 591: u = status.loginshell; ! 592: if(u[0] == 0 /* || strcmp("sh",u+strlen(u)-2) != 0 */) strcpy(u,Bsh); ! 593: ! 594: getpwdf(pwd); ! 595: /* ignore network passwd */ ! 596: if(!spacct(status.login,s,status.localname,status.muid,status.mgid) ! 597: && strcmp(pwd->pw_passwd,s) && verify) ! 598: return(0); ! 599: return(1); ! 600: } ! 601: mread(b,i,n) ! 602: register int n; { ! 603: if(length <= 0)return(0); ! 604: if(length < n)n = length; ! 605: n = nread(b,i,n); ! 606: if(n != BROKENREAD)length -= n; ! 607: return(n); ! 608: } ! 609: char mgetc(){ /* returns 0 if fail */ ! 610: register char c; ! 611: register int n; ! 612: char buf[3]; ! 613: if((n=nread(buf,1,3)) == BROKENREAD)return(0); ! 614: if(n != 3){error("bad read %d",n); return(0); } ! 615: c = buf[0]; ! 616: if(buf[1] != ' ' && buf[1] != ':'){error("Bad char %c",buf[1]); return(0); } ! 617: length -= 3; ! 618: if(length < 0){error("length wrong2 %ld",length); return(0); } ! 619: return(c); ! 620: } ! 621: /* read in string over the network wire */ ! 622: /* put string in s, max length is maxlen */ ! 623: mgets(s,maxlen) /* returns 0 if ok, 1 if not */ ! 624: int maxlen; ! 625: register char *s; { ! 626: register char *q; ! 627: register int n; ! 628: char c; ! 629: q = s; ! 630: for(;;) { ! 631: if((n=nread(&c,1,1)) == BROKENREAD){ ! 632: *s = 0; ! 633: error("mgets %s",s); ! 634: return(1); ! 635: } ! 636: if(n == 0)break; ! 637: if(c == '\\'){ ! 638: if((n=nread(&c,1,1)) == BROKENREAD){ ! 639: *s = 0; ! 640: error("mgets %s",s); ! 641: return(1); ! 642: } ! 643: if(n == 0)break; ! 644: } ! 645: if(c == ' ')break; ! 646: if(maxlen-- > 0) *s++ = c; ! 647: } ! 648: *s = 0; ! 649: if(nread(&c,1,1) == BROKENREAD){ ! 650: error("mgets %s",s); ! 651: return(1); ! 652: } ! 653: length -= (s - q + 2); ! 654: if(length < 0){error("length wrong1 %ld %s",length,q); return(-1); } ! 655: if(maxlen < 0) ! 656: error("mgets - string too long"); ! 657: return(0); ! 658: } ! 659: mgetcmd(s) /* returns 0 if succeed, 1 otherwise */ ! 660: char *s; { ! 661: int i,n; ! 662: char c; ! 663: i = 0; ! 664: for(;;){ ! 665: if((n=nread(&c,1,1)) == BROKENREAD){ ! 666: s[i] = 0; ! 667: error("mgetcmd %s",s); ! 668: return(1); ! 669: } ! 670: if(n <= 0 || c == '\n')break; ! 671: if(c == '\\'){ ! 672: if(nread(&c,1,1) == BROKENREAD){ ! 673: s[i] = 0; ! 674: error("mgetcmd %s",s); ! 675: return(1); ! 676: } ! 677: length--; ! 678: } ! 679: s[i++] = c; ! 680: length--; ! 681: } ! 682: s[i] = 0; ! 683: length--; ! 684: return(0); ! 685: } ! 686: increment(s) ! 687: char *s; { ! 688: int i; ! 689: char *p; ! 690: i = strlen(s) - 1; ! 691: while(s[i] == '9')i--; ! 692: if(s[i] < '0' || s[i] > '9'){ ! 693: p = s+i+1; ! 694: while(*p)*p++ = '0'; ! 695: return; ! 696: } ! 697: (s[i])++; ! 698: i++; ! 699: while(s[i])s[i++] = '0'; ! 700: return; ! 701: } ! 702: pload(currt) ! 703: long currt; { ! 704: struct tms tbf; ! 705: static long out = 0L, ocut = 0L, ost = 0L, ocst = 0L; ! 706: long u, s, elapt; ! 707: double br,r,ru,rs; ! 708: char *str,buf[BUFSIZ]; ! 709: currt = gettime(); ! 710: elapt = currt - dump.shorttime; ! 711: times(&tbf); ! 712: u = tbf.tms_utime-out + tbf.tms_cutime-ocut; ! 713: s = tbf.tms_stime-ost + tbf.tms_cstime-ocst; ! 714: dump.outime += u; ! 715: dump.ostime += s; ! 716: r = u + s; ! 717: if(elapt > 0)r = (r/elapt)*100.0; ! 718: else r = 0.0; ! 719: /* adjust to be seconds */ ! 720: r = r/60.0; ! 721: ru = u/60.0; ! 722: rs = s/60.0; ! 723: str = ctime(&currt); ! 724: str[strlen(str) - 5] = 0; ! 725: sprintf(buf,"%s (%s):\t%4.1fu\t%4.1fs\t%5.2f\t%s\n", ! 726: str,longname(remote),ru,rs,r,comptime(elapt)); ! 727: addtodump(remote,"%s",buf); ! 728: br = dump.bytetot; ! 729: if(dump.elaptot > 0)br = br/dump.elaptot; ! 730: else br = 0.0; ! 731: addtodump(remote, "\tTrans.\t%.6ld bytes\t%4.1f bytes/sec\t%s", ! 732: dump.bytetot,br,comptime(dump.elaptot)); ! 733: addtodump(remote," %s\n",comptime(dump.waittot)); ! 734: dump.shorttime = currt; ! 735: dump.waittot = dump.elaptot = dump.bytetot = 0L; ! 736: out = tbf.tms_utime; ! 737: ocut = tbf.tms_cutime; ! 738: ost = tbf.tms_stime; ! 739: ocst = tbf.tms_cstime; ! 740: sprintf(buf,"%s %c",NETQSTAT,remote); ! 741: system(buf); /* gather stats on netq len. */ ! 742: } ! 743: /* should also gather stats on # error msgs */ ! 744: dumpit(currt) ! 745: long currt; { ! 746: register int ntot; ! 747: long elapt; ! 748: double r,ru,rs; ! 749: register struct dumpstruc *p = &dump; ! 750: register char *tt; ! 751: tt = ctime(&currt); ! 752: tt[strlen(tt) - 9] = 0; ! 753: elapt = currt - dump.longtime; ! 754: r = dump.outime + dump.ostime; ! 755: if(elapt > 0)r = (r/elapt) * 100.0; ! 756: else r = 0.0; ! 757: ru = dump.outime/60.0; ! 758: rs = dump.ostime/60.0; ! 759: r = r/60.0; ! 760: dump.longtime = dump.shorttime; ! 761: ntot = p->nnetcp + p->nnetmail + p->nsmail + p->nnetlpr ! 762: + p->nresp + p->nnet; ! 763: addtodump(remote,"Daily statisics\t(%s):\nSummary:\n",tt); ! 764: addtodump(remote,"\t# sent %d\t# pass-thru %d\t# rcv %d:\t# netcp %d\n", ! 765: p->nsend,p->npass,ntot,p->nnetcp); ! 766: addtodump(remote,"\t# netlpr %d\t# netmail %d\t# sendmail %d\t# resp %d\n", ! 767: p->nnetlpr,p->nnetmail,p->nsmail,p->nresp); ! 768: addtodump(remote,"Protocol summary:\n"); ! 769: addtodump(remote,"\t# pk sent %d\t# pk rcv %d\t# b sent %ld\t# b rcv %ld\n", ! 770: p->npacksent,p->npackrcv,p->nbytesent, p->nbytercv); ! 771: addtodump(remote, ! 772: "\t# send fails %d\t# retrans %d\t# abn %d\t\t# cksum errs %d\n", ! 773: p->nsendfail,p->nretrans, p->nabnormal,p->ncksum); ! 774: addtodump(remote,"Load:\t\t\t\t%4.1fu\t%4.1fs\t%5.2f%%\t%s\n", ! 775: ru,rs,r,comptime(elapt)); ! 776: p->nbytesent = p->nbytercv = p->outime = p->ostime = 0L; ! 777: p->nretrans = p->nloop = p->nabnormal = p->ncksum = 0; ! 778: p->npacksent = p->npackrcv = p->nnetcp = p->nnetmail = 0; ! 779: p->nsmail = p->nnetlpr = p->nnet = p->npass = 0; ! 780: p->nsend = p->nsendfail = 0; ! 781: } ! 782: /* returns 1 if n is ok, 0 if not */ ! 783: goodacctname(n) ! 784: char *n; { ! 785: int i; ! 786: i = -1; ! 787: while(btable[++i].bname) ! 788: if(strcmp(btable[i].bname,n) == 0 && ! 789: local == btable[i].bmach)return(0); ! 790: return(1); ! 791: } ! 792: demask(s) ! 793: register char *s; { ! 794: # ifdef NEWPROT ! 795: static char buf[20]; ! 796: strcpy(s,nbsdecrypt(s,THEKEY,buf)); ! 797: # else ! 798: while(*s){ ! 799: *s &= 0177; /* strip quote bites */ ! 800: *s++ ^= 040; /* invert upper-lower */ ! 801: } ! 802: # endif ! 803: } ! 804: /*VARARGS0*/ ! 805: mreopen(f,a,b,c){ ! 806: /* simply handles errors by giving error msg */ ! 807: if(freopen(a,b,c) == NULL)errormsg(f,"%s: %s",a,sys_errlist[errno]); ! 808: } ! 809: /* ! 810: addtopub(string, args) ! 811: ! 812: add a message to the public logfile /usr/net/logfile. ! 813: note that the file must be writeable by everyone ! 814: if error messages from the netrcv subroutine ! 815: such as chdir errors are to be noticed. ! 816: */ ! 817: /*VARARGS0*/ ! 818: addtopublic(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n) ! 819: char *s; ! 820: { ! 821: static FILE *log = NULL; ! 822: if(log == NULL){ ! 823: if(stat(publogfile,&statbuf) < 0)return; ! 824: log = fopen(publogfile,"a"); ! 825: if(log == NULL)return; ! 826: } ! 827: fseek(log,0L,2); ! 828: fprintf(log,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n); ! 829: fflush(log); ! 830: } ! 831: /*VARARGS0*/ ! 832: addtodump(mach,str,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t,u) ! 833: char *str; ! 834: { ! 835: static FILE *log = NULL; ! 836: dumpfile[strlen(dumpfile)-1] = mach; ! 837: if(log == NULL){ ! 838: if(stat(dumpfile,&statbuf) < 0)return; ! 839: log = fopen(dumpfile,"a"); ! 840: if(log == NULL)return; ! 841: } ! 842: fseek(log,0L,2); ! 843: fprintf(log,str,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t,u); ! 844: fflush(log); ! 845: } ! 846: /* set up a dummy environment for v7 /bin/sh */ ! 847: setenv(home) ! 848: char *home; { ! 849: static char *env[3],benv[2][50]; ! 850: env[0] = benv[0]; ! 851: env[1] = benv[1]; ! 852: strcpy(env[0],"PATH=:/bin:/usr/bin"); ! 853: sprintf(env[1],"HOME=%s",home); ! 854: env[2] = 0; ! 855: environ = env; ! 856: } ! 857: /* errormsg- sends error message to user- ! 858: may be on local or remote machine. ! 859: Sends to addrfrom if fmach != local, ! 860: or to addrto if fmach=local, on the assumption ! 861: that addrfrom is where it came from and addrto is where it ! 862: was destined on this machine. The only time fmach=local is ! 863: if the result file is screwed up. ! 864: ! 865: Note that errormsg can be called by the netrcv subroutine ! 866: after the setuid() call to the specific user, so the ! 867: user must be able to get off an error msg back to him, ! 868: and to write in the two log files. ! 869: Can't use -w,-x,-y,-z for the net cmd because must be root for those. ! 870: */ ! 871: /*VARARGS0*/ ! 872: errormsg(fmach,s,a,b,c,d,e,f,g,h) ! 873: char *s; ! 874: { ! 875: int rcode; ! 876: char errstr[BUFSIZ], cmdstr[BUFSIZ], rcmd[BUFSIZ]; ! 877: char toadd[FNS], fromadd[FNS], mchto, mchfrom; ! 878: ! 879: if(fmach < 'a' || 'z' < fmach)fmach = local; ! 880: if(status.sTtyname[0] == 0)strcpy(status.sTtyname,"/dev/ttyx"); ! 881: /* will send to toadd, from fromadd */ ! 882: if(fmach == local || strcmp(status.sCmdVirt,"response") == 0){ ! 883: /* send to local mach, thus send to toaddr. */ ! 884: /* if this is an error during a response, send to local mach. */ ! 885: strcpy(toadd, addrto); ! 886: strcpy(fromadd,addrfrom); ! 887: } ! 888: else { /* send to remote mach, thus send back to addrfrom*/ ! 889: strcpy(toadd, addrfrom); ! 890: strcpy(fromadd,addrto); ! 891: } ! 892: sprintf(errstr,"Error: "); ! 893: sprintf(cmdstr,s,a,b,c,d,e,f,g,h); ! 894: strcat(errstr,cmdstr); ! 895: strcat(errstr,"\n"); ! 896: addtolog(remote,errstr); ! 897: addtopublic(errstr); ! 898: ! 899: mchto = MchSFromAddr(status.localname,toadd); ! 900: mchfrom = MchSFromAddr(status.login, fromadd); ! 901: ! 902: sprintf(rcmd, ! 903: "%s %s %s %lo %c %s \"'%s'\" %ld -t %s -f %s -x %ld -y %s -c \"'%s'\" -e %ld", ! 904: MWRITECMD, ! 905: status.localname, status.sTtyname, status.lTtytime, local, status.login,status.sCmdVirt, gettime(), ! 906: toadd, fromadd, status.lTtytime, status.sTtyname, status.sCmdVirt, gettime()); ! 907: if(fmach == local) ! 908: sprintf(cmdstr, "echo \"%s\" | %s", errstr,rcmd); ! 909: else sprintf(cmdstr, ! 910: "echo \"%s\" | %s -m%c -b -c errormessage -l network - %s", ! 911: errstr,netcmd,fmach,rcmd); ! 912: rcode = system(cmdstr); ! 913: exit(1); ! 914: } ! 915: handlekill(){ /* SIGTRM signal */ ! 916: long t; ! 917: addtodump(remote,"Netdaemon terminated.\n"); ! 918: t = gettime(); ! 919: pload(t); ! 920: dumpit(t); ! 921: exit(0); /* kill myself */ ! 922: } ! 923: spacct(log,pass,localname,luid,lgid) /* returns 1 if login ok, 0 if not */ ! 924: char *log,*pass,*localname; { ! 925: long lt; ! 926: int u,g; ! 927: if(strcmp(log,"network") == 0)return(1); ! 928: /* experimental */ ! 929: # ifdef SPACCT ! 930: if(strcmp(log,localname) == 0 && luid != 0 && lgid == 0 ! 931: && isdigit(pass[0]) && ( ! 932: strcmp(log,"source") == 0 ! 933: || strcmp(log,"daemon") == 0) ! 934: ){ ! 935: /* login name is same on both machines, userid is group 0, ! 936: non-root, the password is numeric ! 937: and the login name is one of a select few */ ! 938: lt = atol(pass); ! 939: u = (lt & 0177777); ! 940: g = (lt >> 16); ! 941: if((luid == u) && (lgid == g))return(1); ! 942: } ! 943: # endif ! 944: return(0); ! 945: } ! 946: /* add the user's name to our name list */ ! 947: /*VARARGS0*/ ! 948: addtoname(name) ! 949: char *name; ! 950: { ! 951: static FILE *log = NULL; ! 952: if(name == NULL || ! 953: name[0] == 0 || ! 954: strcmp(name,"root") == 0 || ! 955: strcmp(name,"network") == 0 || ! 956: strcmp(name,"schmidt") == 0)return; ! 957: if(log == NULL){ ! 958: if(stat(namefile,&statbuf) < 0)return; ! 959: log = fopen(namefile,"a"); ! 960: if(log == NULL)return; ! 961: } ! 962: fseek(log,0L,2); ! 963: fprintf(log,"%s:%s\n",longname(local),name); ! 964: fflush(log); ! 965: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.