|
|
1.1 ! root 1: /* ! 2: sub.c ! 3: ! 4: support procedures ! 5: ! 6: the following procedures end up reading the passwd file ! 7: or the passwdf file and are to be avoided. ! 8: ! 9: getpwuid(uid) ! 10: getpwnam(sn) ! 11: PwdCurrent() ! 12: getenv("HOME") maybe if hget, hgethome don't work ! 13: SnFromUid(uid) maybe if hashed passwd stuff doesn't work ! 14: SnCurrent() maybe if getlogin fails calls SnFromUid(uid) ! 15: getpwf() ! 16: passwdent(uid,sn) ! 17: */ ! 18: ! 19: # include "defs.h" ! 20: # include "config.h" ! 21: ! 22: int debugflg = DBV; /* debug flag */ ! 23: char local = LOCAL; /* the machine we're on */ ! 24: ! 25: char netcmd[] = NETCMD; ! 26: char resfile[] = RESFILE; ! 27: char senddir[] = SENDDIR; ! 28: char Bsh[] = BINSH; ! 29: ! 30: char shomedir[BUFSIZ]; ! 31: ! 32: /* ! 33: passwdent() ! 34: ! 35: Read the password file looking for current user's entry. ! 36: Fill in the status structure. ! 37: Has the (dangerous) side effect of giving a value to getenv("HOME"). ! 38: */ ! 39: passwdent() ! 40: { ! 41: register char *u; ! 42: register struct passwd *pwd; ! 43: pwd = PwdCurrent(); ! 44: if(pwd == NULL){ ! 45: err("Bad uid/username\n"); ! 46: return; ! 47: } ! 48: strcpy(status.localname,pwd->pw_name); ! 49: status.muid = guid(pwd->pw_uid,pwd->pw_gid); ! 50: status.mgid = pwd->pw_gid; ! 51: if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos); ! 52: else status.jobno = 32767; ! 53: strcpy(status.dir,pwd->pw_dir); ! 54: strcpy(shomedir,pwd->pw_dir); /* side effect */ ! 55: u = pwd->pw_shell; ! 56: if(u[0] == 0)u= Bsh; ! 57: strcpy(status.loginshell,u); ! 58: } ! 59: /* ! 60: promptlogin(mchto) ! 61: ! 62: ask user for login and passwd on mchto. ! 63: make sure status.localname has a value before calling ! 64: this. One way is to call passwdent(), another is to ! 65: strcpy(status.localname,SnCurrent()). ! 66: */ ! 67: promptlogin(mchto) ! 68: char mchto; ! 69: { ! 70: char buf[BUFSIZ], mch; ! 71: FILE *wf; ! 72: int c; ! 73: if(status.mpasswd[0] == 0 || status.login[0] == 0 || status.force){ ! 74: wf = fopen("/dev/tty","r"); ! 75: if(wf != NULL){ ! 76: if(status.login[0]==0 || status.force){ ! 77: printf("Name (%s:%s): ",longname(mchto), ! 78: status.localname); ! 79: if(fgets(buf, BUFSIZ, wf) != buf){ ! 80: perror("fgets"); ! 81: exit(1); ! 82: } ! 83: c = strlen(buf); ! 84: buf[c > 0 ? c-1 : 0] = 0; ! 85: if(c > 10){ ! 86: err("Login name too long.\n"); ! 87: exit(1); ! 88: } ! 89: if(FMemberSCh(buf,' ')){ ! 90: err("Login names don't have blanks in them.\n"); ! 91: exit(1); ! 92: } ! 93: if(buf[0] == 0)strcpy(buf,status.localname); ! 94: mch = MchSFromAddr(status.login,buf); ! 95: if(mch != local && mch != mchto){ ! 96: err( ! 97: "Must specify login name on %s machine\n", ! 98: longname(mchto)); ! 99: exit(1); ! 100: } ! 101: } ! 102: if(strcmp(status.login,"network") != 0 ! 103: && (status.mpasswd[0]== 0 || status.force)){ ! 104: sprintf(buf,"Password (%s:%s):", ! 105: longname(mchto), status.login); ! 106: strcpy(status.mpasswd,getpass(buf)); ! 107: } ! 108: fclose(wf); ! 109: } ! 110: } ! 111: if(status.login[0] == 0) strcpy(status.login,status.localname); ! 112: if(status.mpasswd[0] == 0)strcpy(status.mpasswd,"\"\""); ! 113: status.force = 0; ! 114: } ! 115: ! 116: /* determine through machine */ ! 117: gothru(from,to){ ! 118: register int i; ! 119: switch(from){ ! 120: case 'a': i = configA[to-'a']; break; ! 121: case 'b': i = configB[to-'a']; break; ! 122: case 'c': i = configC[to-'a']; break; ! 123: case 'd': i = configD[to-'a']; break; ! 124: case 'e': i = configE[to-'a']; break; ! 125: case 'f': i = configF[to-'a']; break; ! 126: case 'i': i = configI[to-'a']; break; ! 127: case 'j': i = configJ[to-'a']; break; ! 128: case 'm': i = configM[to-'a']; break; ! 129: case 'o': i = configO[to-'a']; break; ! 130: case 'q': i = configQ[to-'a']; break; ! 131: case 's': i = configS[to-'a']; break; ! 132: case 'v': i = configV[to-'a']; break; ! 133: case 'y': i = configY[to-'a']; break; ! 134: case 'z': i = configZ[to-'a']; break; ! 135: default: i = 0; break; ! 136: } ! 137: return(i); ! 138: } ! 139: /* ! 140: harg(string,pargc,pargv) ! 141: ! 142: A curious procedure which takes a pointer to an argc, and a ! 143: pointer to an argv, and parses them so that the ! 144: argument following the flag is copied into string. ! 145: pargv[0] must be the flag argument. ! 146: handles both ! 147: -my ! 148: and ! 149: -m y ! 150: for the net command. ! 151: */ ! 152: harg(ans,pargc,pargv) ! 153: char *ans,*pargc,***pargv;{ ! 154: if((*pargv)[0][2]) /* no space */ ! 155: strcpy(ans,(*pargv)[0] + 2); ! 156: else { /* space, get next arg */ ! 157: strcpy(ans,(*pargv)[1]); ! 158: (*pargc)--; ! 159: (*pargv)++; ! 160: } ! 161: } ! 162: ! 163: /* prints out commands before executing them */ ! 164: /*VARARGS0*/ ! 165: mexecl(s) ! 166: char *s;{ ! 167: int *p = (int *)&s; ! 168: register int i; ! 169: if(debugflg){ ! 170: for(i=0; p[i]; i++)err("%s ",p[i]); ! 171: putc('\n',stderr); ! 172: } ! 173: execl(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11], ! 174: p[12],p[13],p[14],p[15],0); ! 175: perror(p[0]); ! 176: } ! 177: /* prints out commands before executing them */ ! 178: mexecv(s,p) ! 179: register char *s, **p;{ ! 180: register int i; ! 181: if(debugflg){ ! 182: err("%s ",s); ! 183: for(i=0; p[i]; i++)err("%s ",p[i]); ! 184: putc('\n',stderr); ! 185: } ! 186: execv(s,p); ! 187: perror(s); ! 188: } ! 189: ! 190: /*VARARGS0*/ ! 191: /* fills in -l - -p from commands like rcp */ ! 192: /* must be called with at least two arguments */ ! 193: kexecl(s) ! 194: char *s; { ! 195: char *a[20], i = 2, j = 2; ! 196: char **p = (char **)&s; ! 197: a[0] = p[0]; ! 198: a[1] = p[1]; ! 199: if(status.login[0]){ ! 200: a[i++] = "-l"; ! 201: a[i++] = status.login; ! 202: } ! 203: if(status.mpasswd[0]){ ! 204: a[i++] = "-p"; ! 205: a[i++] = status.mpasswd; ! 206: } ! 207: if(status.nonotify)a[i++] = "-b"; ! 208: if(status.force) a[i++] = "-f"; ! 209: if(status.quiet) a[i++] = "-q"; ! 210: if(status.nowrite) a[i++] = "-n"; ! 211: while(p[j])a[i++] = p[j++]; ! 212: a[i] = 0; ! 213: mexecl(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11], ! 214: a[12],a[13],a[14],a[15],0); ! 215: } ! 216: ! 217: /* ! 218: MchSFromAddr(sn,addr) ! 219: ! 220: take an address of the form "mach:username" ! 221: and return mch as the 1 char code of "mach" and ! 222: in sn put "username". ! 223: If addr has no colon in it, return mch==local, sn==addr. ! 224: */ ! 225: MchSFromAddr(sn,addr) ! 226: char *sn, *addr; ! 227: { ! 228: char fcolon = 0, *s, mch, stemp[BUFSIZ]; ! 229: ! 230: /* assume addr is a local address */ ! 231: ! 232: strcpy(stemp,addr); ! 233: s = stemp; ! 234: while(*s){ ! 235: if(*s == ':'){ ! 236: fcolon = 1; ! 237: *s++ = 0; ! 238: break; ! 239: } ! 240: s++; ! 241: } ! 242: if(fcolon != 1){ ! 243: /* sn better be the right size for addr */ ! 244: mch = local; ! 245: strcpy(sn,addr); ! 246: return(mch); ! 247: } ! 248: ! 249: /* addr has a colon in it, s pts to name */ ! 250: mch = lookup(stemp); ! 251: strcpy(sn,s); ! 252: return(mch); ! 253: } ! 254: ! 255: ! 256: /* returns a single character for machine S */ ! 257: lookup(s) ! 258: register char *s; { ! 259: register struct tt *t; ! 260: if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s); ! 261: for(t = table; t->bigname; t++) ! 262: if(streql(s,t->bigname) == 0)return(t->lname); ! 263: return(0); ! 264: } ! 265: ! 266: /* returns a long name (string) for single character machine c */ ! 267: char *longname(c) ! 268: register char c; ! 269: { ! 270: register struct tt *t; ! 271: if(c == 0)return("UNKNOWN"); ! 272: for(t = table; t->bigname; t++) ! 273: if(c == t->lname)return(t->bigname); ! 274: return("UNKNOWN"); ! 275: } ! 276: /*VARARGS0*/ ! 277: debug(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t) ! 278: char *s; { ! 279: if(debugflg){ ! 280: printf(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t); ! 281: putchar('\n'); ! 282: } ! 283: } ! 284: ! 285: /* ! 286: FMemberSCh(s,ch) ! 287: ! 288: return 1 if ch is a character in string s. ! 289: 0 otherwise. ! 290: */ ! 291: FMemberSCh(s,ch) ! 292: register char *s, ch; ! 293: { ! 294: while(*s)if(*s++ == ch)return(1); ! 295: return(0); ! 296: } ! 297: ! 298: /* return a static string with the form "X hrs X mins X secs" */ ! 299: /* t is # of secs */ ! 300: char *comptime(t) ! 301: long t; { ! 302: static char str[30]; ! 303: char buf[20]; ! 304: long w; ! 305: str[0] = 0; ! 306: w = t/3600L; ! 307: if(w > 0L){ ! 308: sprintf(buf,"%ld hr ",w); ! 309: strcat(str,buf); ! 310: } ! 311: t = t % 3600L; ! 312: w = t/60L; ! 313: if(w > 0L){ ! 314: sprintf(buf,"%ld min ",w); ! 315: strcat(str,buf); ! 316: } ! 317: t = t % 60L; ! 318: sprintf(buf,"%ld sec",t); ! 319: strcat(str,buf); ! 320: return(str); ! 321: } ! 322: /* ! 323: parseparmlist(string) ! 324: ! 325: parses variable parameter lists in string, ! 326: as defined in genparmlist in net.c ! 327: */ ! 328: parseparmlist(parmlist) ! 329: char *parmlist; ! 330: { ! 331: while(*parmlist && *parmlist != '(')parmlist++; ! 332: } ! 333: ! 334: /* ! 335: PwdCurrent() ! 336: ! 337: Read the password file and return pwd to ! 338: entry for current user. ! 339: Return NULL if error. ! 340: ! 341: This code is a little screwed up because of the conventions ! 342: regarding the state of the utmp file after someone su's-- ! 343: either to root or to another person. ! 344: The final decision was to return getpwuid(getuid) if ! 345: the machine has one login name per userid, ! 346: and if there are multiple login names per userid, to ! 347: search the passwd file for the getlogin() name and return ! 348: the passwd file entry for that. ! 349: If there is no utmp entry, just use the userid. ! 350: This means that people who su on machine with multiple ! 351: user-id's will get the passwd entry for the account recorded ! 352: in the utmp file, not their current userid. ! 353: */ ! 354: struct passwd * ! 355: PwdCurrent() ! 356: { ! 357: register struct passwd *pwd; ! 358: register char *sn; ! 359: ! 360: # ifdef MULTNAMS ! 361: sn = getlogin(); ! 362: if(sn != NULL && sn[0] != 0 && sn[0] != ' '){ ! 363: pwd = getpwnam(sn); ! 364: if(pwd != NULL)return(pwd); ! 365: } ! 366: # endif ! 367: ! 368: return(getpwuid(uidmask(getuid()))); ! 369: } ! 370: /* ! 371: SnCurrent() ! 372: ! 373: Return the name of the current user. ! 374: If not in the /etc/utmp file, will read the passwd file. ! 375: Returns NULL if error. ! 376: Note that detached processes on V7 have getlogin() return ! 377: a pointer to a null string, not NULL. ! 378: */ ! 379: char *SnCurrent() ! 380: { ! 381: static char snBuf[NS]; ! 382: register char *sn; ! 383: ! 384: sn = getlogin(); ! 385: if(sn == NULL || sn[0] == 0 || sn[0] == ' ') ! 386: sn = SnFromUid(getuid()); ! 387: if(sn != NULL){ ! 388: strcpy(snBuf,sn); ! 389: sn = snBuf; ! 390: } ! 391: return(sn); ! 392: } ! 393: /* just like strcmp except upper- and lower-case are ignored */ ! 394: streql(s1,s2) ! 395: char *s1, *s2; { ! 396: char a,b; ! 397: while(*s1 && *s2){ ! 398: a = isupper(*s1) ? tolower(*s1) : *s1; ! 399: b = isupper(*s2) ? tolower(*s2) : *s2; ! 400: if(a < b)return(-1); ! 401: if(a > b)return(1); ! 402: s1++, s2++; ! 403: } ! 404: if(*s2)return(-1); ! 405: if(*s1)return(1); ! 406: return(0); ! 407: } ! 408: /* VARARGS0 */ ! 409: err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) { ! 410: fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r); ! 411: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.