Annotation of researchv9/netb/src/perm.c, revision 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.