|
|
1.1 ! root 1: /* all the permission stuff. */ ! 2: #include "share.h" ! 3: #include "pwd.h" ! 4: #include "grp.h" ! 5: ! 6: typedef struct { ! 7: int huid, cuid; ! 8: } tuid; ! 9: tuid *t, *g; ! 10: int tcnt, gcnt; ! 11: int primes[] = {23, 47, 97, 199, 397, 797, 1597, 3191, 6397, 12799, 31991, 0}; ! 12: int *uhhash, *uchash, uhp, *ghhash, *gchash, ghp; ! 13: int otherok = 1; /* default policy */ ! 14: int pfd; /* temporary file descriptor */ ! 15: char *exbf, *realexbf; /* exception buffer */ ! 16: char clientname[128] = "\n"; /* the client's name, newline terminated */ ! 17: ! 18: clientuid() /* from client to host */ ! 19: { int j; ! 20: if(client.uid < 0) ! 21: return(-1); ! 22: for(j = client.uid % uhp; uchash[j] != -1; j++) ! 23: if(t[uchash[j]].cuid == client.uid) ! 24: return(t[uchash[j]].huid); ! 25: return(-1); ! 26: } ! 27: ! 28: clientgid() /* from client to host */ ! 29: { int j; ! 30: if(client.gid < 0) ! 31: return(-1); ! 32: for(j = client.gid % ghp; gchash[j] != -1; j++) ! 33: if(g[gchash[j]].cuid == client.gid) ! 34: return(g[gchash[j]].huid); ! 35: return(-1); ! 36: } ! 37: ! 38: hostuid(n) /* host to client */ ! 39: { int j; ! 40: if(n < 0) ! 41: return(-1); ! 42: for(j = n % uhp; uhhash[j] != -1; j++) ! 43: if(t[uhhash[j]].huid == n) ! 44: return(t[uhhash[j]].cuid); ! 45: return(-1); ! 46: } ! 47: ! 48: hostgid(n) /* host to client */ ! 49: { int j; ! 50: if(n < 0) ! 51: return(-1); ! 52: for(j = n % ghp; ghhash[j] != -1; j++) ! 53: if(g[ghhash[j]].huid == n) ! 54: return(g[ghhash[j]].cuid); ! 55: return(-1); ! 56: } ! 57: ! 58: isowner(p) ! 59: struct stat *p; ! 60: { ! 61: if(clientuid() == p->st_uid) ! 62: return(1); ! 63: return(0); ! 64: } ! 65: ! 66: searchperm() ! 67: { struct stat stb; ! 68: if(stat(nmbuf, &stb) < 0) { ! 69: client.errno = errno; ! 70: return(1); ! 71: } ! 72: if(clientuid() == stb.st_uid && (stb.st_mode & 0100)) ! 73: return(0); ! 74: if(clientgid() == stb.st_gid && (stb.st_mode & 010)) ! 75: return(0); ! 76: if((stb.st_mode & 1) && (otherok || clientuid() != -1)) ! 77: return(0); ! 78: return(1); ! 79: } ! 80: ! 81: writeperm() ! 82: { struct stat stb; ! 83: if(stat(nmbuf, &stb) < 0) { ! 84: client.errno = errno; ! 85: return(1); ! 86: } ! 87: if(clientuid() == stb.st_uid && (stb.st_mode & 0200)) ! 88: return(0); ! 89: if(clientgid() == stb.st_gid && (stb.st_mode & 020)) ! 90: return(0); ! 91: if((stb.st_mode & 2) && (otherok || clientuid() != -1)) ! 92: return(0); ! 93: client.errno = EPERM; ! 94: return(1); ! 95: } ! 96: ! 97: dirwriteperm() ! 98: { int n; ! 99: error("dw (%d,%d)\n", clientuid(), clientgid()); ! 100: if(!slash) ! 101: return(1); /* this can't happen? */ ! 102: if(clientuid() == -1 || clientgid() == -1) { ! 103: client.errno = EPERM; ! 104: return(1); /* too bad bozo */ ! 105: } ! 106: *slash = 0; ! 107: n = writeperm(); ! 108: *slash = '/'; ! 109: return(n); ! 110: } ! 111: ! 112: /* hostdev translates from host's devs to client's */ ! 113: hostdev(n) ! 114: { int i; ! 115: for(i = 0; i < ndev; i++) ! 116: if(devs[i].hdev == n) ! 117: return(devs[i].cdev); ! 118: error("hostdev: 0x%x not found\n", n); ! 119: client.errno = ENXIO; ! 120: return(0); ! 121: } ! 122: ! 123: /* clientdev translates from client's to host's */ ! 124: clientdev(n) ! 125: { int i; ! 126: for(i = 0; i < ndev; i++) ! 127: if(devs[i].cdev == n) ! 128: return(devs[i].hdev); ! 129: debug("clientdev: 0x%x not found\n", n); ! 130: client.errno = ENXIO; ! 131: return(0); ! 132: } ! 133: ! 134: getuids() ! 135: { int i, j; ! 136: char msg[16]; ! 137: /* scan host passwd file for count */ ! 138: tcnt = cntpasswd(); ! 139: t = (tuid *) malloc(tcnt * sizeof(tuid)); ! 140: i = xread(cfd, inbuf, inlen); ! 141: if(i != inlen) ! 142: fatal("getuids read %d (%d)\n", i, errno); ! 143: /* decode and ack */ ! 144: msg[0] = 2; ! 145: if(write(cfd, msg, 1) != 1) ! 146: fatal("getuid ack failed (%d)\n", errno); ! 147: /* and match with host passwd */ ! 148: fillpasswd(); ! 149: for(i = 0; primes[i] && primes[i] < 2 * tcnt; i++) ! 150: ; ! 151: if(primes[i] == 0) ! 152: fatal("tcnt %d too big for hashtable %d\n", tcnt, primes[i-1]); ! 153: uhp = primes[i]; ! 154: uhhash = (int *) malloc((uhp + 4) * sizeof(int)); ! 155: uchash = (int *) malloc((uhp + 4) * sizeof(int)); ! 156: /* what's the chance the last 3 items will fill? */ ! 157: for(i = 0; i < uhp + 4; i++) ! 158: uhhash[i] = uchash[i] = -1; ! 159: for(i = 0; i < tcnt; i++) { ! 160: j = t[i].huid % uhp; ! 161: while(uhhash[j] != -1) ! 162: j++; ! 163: if(j >= uhp + 3) /* guarantee sentinel at end of hash tables */ ! 164: fatal("uhhash overflow!\n"); ! 165: uhhash[j] = i; ! 166: ! 167: j = t[i].cuid % uhp; ! 168: while(uchash[j] != -1) ! 169: j++; ! 170: if(j >= uhp + 3) ! 171: fatal("uchash overflow!\n"); ! 172: uchash[j] = i; ! 173: } ! 174: } ! 175: ! 176: getgids() ! 177: { int i, j; ! 178: char msg[16]; ! 179: /* scan host group file for count */ ! 180: gcnt = cntgroups(); ! 181: g = (tuid *) malloc(gcnt * sizeof(tuid)); ! 182: i = xread(cfd, inbuf, inlen); ! 183: if(i != inlen) ! 184: fatal("getgids read %d (%d)\n", i, errno); ! 185: /* decode and ack */ ! 186: msg[0] = 3; ! 187: if(write(cfd, msg, 1) != 1) ! 188: fatal("getgid ack failed (%d)\n", errno); ! 189: /* and match with host passwd */ ! 190: fillgroups(); ! 191: for(i = 0; primes[i] && primes[i] < 2 * gcnt; i++) ! 192: ; ! 193: if(primes[i] == 0) ! 194: fatal("gcnt %d too big for hashtable %d\n", gcnt, primes[i-1]); ! 195: ghp = primes[i]; ! 196: ghhash = (int *) malloc((ghp + 4) * sizeof(int)); ! 197: gchash = (int *) malloc((ghp + 4) * sizeof(int)); ! 198: /* what's the chance the last 3 items will fill? */ ! 199: for(i = 0; i < ghp + 4; i++) ! 200: ghhash[i] = gchash[i] = -1; ! 201: for(i = 0; i < gcnt; i++) { ! 202: j = g[i].huid % ghp; ! 203: while(ghhash[j] != -1) ! 204: j++; ! 205: if(j >= ghp + 3) /* guarantee sentinel at end of hash tables */ ! 206: fatal("ghhash overflow!\n"); ! 207: ghhash[j] = i; ! 208: ! 209: j = g[i].cuid % ghp; ! 210: while(gchash[j] != -1) ! 211: j++; ! 212: if(j >= ghp + 3) ! 213: fatal("gchash overflow!\n"); ! 214: gchash[j] = i; ! 215: } ! 216: } ! 217: ! 218: cntpasswd() ! 219: { struct passwd *p, *getpwent(); ! 220: int m = 0; ! 221: while(p = getpwent()) ! 222: m++; ! 223: setpwent(); /* leave it set for fillpasswd() */ ! 224: return(m); ! 225: } ! 226: ! 227: cntgroups() ! 228: { struct group *g, *getgrent(); ! 229: int m = 0; ! 230: while(g = getgrent()) { ! 231: m++; ! 232: } ! 233: setgrent(); /* leave it set for fillgroups() */ ! 234: return(m); ! 235: } ! 236: ! 237: char * ! 238: clientline(s) ! 239: char *s; ! 240: { char *p; ! 241: if(!s || !*s) ! 242: return(0); ! 243: for(p = s; *p; ) { ! 244: if(strncmp(p, "client ", 7) == 0 || strncmp(p, "client\t", 7) == 0) ! 245: return(p); ! 246: while(*p++ != '\n'); ! 247: ; ! 248: } ! 249: return(p); ! 250: } ! 251: ! 252: getexcepts() ! 253: { char *p, *q, *r; ! 254: struct stat stb; ! 255: pfd = open("/usr/netb/except", 0); ! 256: if(pfd < 0 || fstat(pfd, &stb) < 0) { ! 257: error("danger!!! can't find /usr/netb/except, but proceeding\n"); ! 258: fakeit: ! 259: exbf = (char *) malloc(1); ! 260: realexbf = exbf; ! 261: *exbf = 0; ! 262: return; ! 263: } ! 264: exbf = (char *) malloc(stb.st_size + 1); ! 265: realexbf = exbf; ! 266: if(read(pfd, exbf, stb.st_size) != stb.st_size) { ! 267: error("danger!!! can't read /usr/netb/except, but proceeding\n"); ! 268: free(exbf); ! 269: goto fakeit; ! 270: } ! 271: close(pfd); ! 272: /* now find the section for this client */ ! 273: for(q = 0, p = clientline(exbf); *p; p = clientline(p)) { ! 274: if(q) { ! 275: *p = 0; ! 276: exbf = q; ! 277: error("found excepts for client %s"); ! 278: return; ! 279: } ! 280: r = p + 6; /* skip across "client " */ ! 281: while(*r == ' ' || *r == '\t') ! 282: r++; ! 283: if(strncmp(r, clientname, strlen(clientname)) == 0) ! 284: q = p; ! 285: while(*p++ != '\n') ! 286: ; ! 287: } ! 288: error("warning!!! no match for client %s", clientname); ! 289: /* look for the default client */ ! 290: for(q = 0, p = clientline(exbf); *p && !q; p = clientline(p+1)) { ! 291: r = p + 6; /* skip across "client " */ ! 292: while(*r == ' ' || *r == '\t') ! 293: r++; ! 294: if(*r == '*' && r[1] == '\n') ! 295: q = p; ! 296: } ! 297: if(q) { ! 298: exbf = q; ! 299: error("using default client info\n"); ! 300: return; ! 301: } ! 302: error("warning!!! no default client info, proceeding anyway\n"); ! 303: } ! 304: ! 305: char * ! 306: findexcept(tag, s) ! 307: char *tag, *s; ! 308: { char *p, *q; ! 309: int n; ! 310: n = strlen(tag); ! 311: p = exbf; ! 312: loop: ! 313: if(*p == 0) ! 314: return(s); ! 315: if(strncmp(tag, p, n) != 0) { ! 316: eol: ! 317: while(*p && *p++ != '\n') ! 318: ; ! 319: goto loop; ! 320: } ! 321: for(p += n; *p == ' ' || *p == '\t'; p++) ! 322: ; /* skip the tag and whitespace */ ! 323: for(q = s; *p == *q; p++, q++) ! 324: ; ! 325: if(*q != 0 || *p != '=') ! 326: goto eol; ! 327: if(p[1] == ' ' || p[1] == '\t' || p[1] == '\n') ! 328: return(0); /* client not allowed */ ! 329: return(p+1); ! 330: } ! 331: ! 332: doneexcepts() ! 333: { char *s; ! 334: s = findexcept("param", "otherok"); ! 335: if(s && *s == '0') ! 336: otherok = 0; ! 337: error("otherok %d\n", otherok); ! 338: /* umask could be settable too */ ! 339: umask(0); ! 340: free(realexbf); ! 341: realexbf = exbf = (char *) -1; /* dereference that */ ! 342: } ! 343: ! 344: char * ! 345: findid(t, s) ! 346: char *t, *s; ! 347: { char *p, *q; ! 348: s = findexcept(t, s); ! 349: if(!s) ! 350: return(0); ! 351: p = (char *)inbuf; ! 352: loop: ! 353: if(*p == 0) ! 354: return(0); ! 355: for(q = s; *p == *q; p++, q++) ! 356: ; ! 357: if((*q == 0 || *q == ' ' || *q == '\t' || *q == '\n') && *p == ' ') ! 358: return(p+1); ! 359: while(*p && *p != '\n') ! 360: p++; ! 361: if(*p == '\n') ! 362: p++; ! 363: goto loop; ! 364: } ! 365: ! 366: fillpasswd() /* quadratic */ ! 367: { struct passwd *p, *getpwent(); ! 368: char *s; ! 369: int i = 0; ! 370: while(p = getpwent()) { ! 371: s = findid("uid", p->pw_name); ! 372: if(s == 0) ! 373: continue; ! 374: t[i].huid = p->pw_uid; ! 375: t[i].cuid = atoi(s); ! 376: i++; ! 377: } ! 378: error("matched %d passwds out of %d\n", i, tcnt); ! 379: tcnt = i; ! 380: endpwent(); ! 381: } ! 382: ! 383: fillgroups() /* quadratic */ ! 384: { struct group *p, *getgrent(); ! 385: char *s; ! 386: int i = 0; ! 387: while(p = getgrent()) { ! 388: s = findid("gid", p->gr_name); ! 389: if(s == 0) ! 390: continue; ! 391: g[i].huid = p->gr_gid; ! 392: g[i].cuid = atoi(s); ! 393: i++; ! 394: } ! 395: error("matched %d groups out of %d\n", i, gcnt); ! 396: gcnt = i; ! 397: endgrent(); ! 398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.