Annotation of researchv9/netb/src/perm.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.