|
|
1.1 ! root 1: /* ! 2: * permission-mapping primitives ! 3: * ! 4: * for each of user- and group-ids, ! 5: * there is a map of (client, server) id pairs ! 6: * ids not in the map are mapped to RFNOID ! 7: * if rfotherdeny != -0, RFNOID is denied all access ! 8: * RFNOID may not create files in any case (who would own them?) ! 9: * (answer: defaultuser and defaultgroup.) ! 10: */ ! 11: ! 12: #include "rf.h" ! 13: #include "perm.h" ! 14: ! 15: #define NULL 0 ! 16: ! 17: #define SUSER 0 /* super-user ID */ ! 18: ! 19: int rfotherdeny; ! 20: int rfuid = RFNOID; /* mapped uid of the client */ ! 21: int rfgid = RFNOID; /* mapped gid of the client */ ! 22: int cuid; /* client's uid (unmapped) */ ! 23: int cgid; ! 24: ! 25: ! 26: Tuid *_rfuids, *_rfgids; ! 27: int _rfuhp, _rfghp; /* hash primes */ ! 28: int *_rfsu, *_rfsg, *_rfcu, *_rfcg; /* hash tables */ ! 29: ! 30: extern char *malloc(); ! 31: extern int defaultuid; ! 32: extern int defaultgid; ! 33: ! 34: /* ! 35: * high-level routines to check particular sorts of access ! 36: * return nonzero if access OK ! 37: */ ! 38: ! 39: /* ! 40: * read access to a regular file ! 41: * -- execute implies read; ! 42: * a file server can't tell the difference, ! 43: * and the data ends up inside the client anyway ! 44: */ ! 45: _rfpread(f, u, g) ! 46: register Rfile *f; ! 47: int u, g; ! 48: { ! 49: register int bits; ! 50: ! 51: bits = RFPRD|RFPEX; ! 52: if (u == RFNOID && defaultuid != RFNOID) ! 53: u = defaultuid; ! 54: if (g == RFNOID && defaultgid != RFNOID) ! 55: g = defaultgid; ! 56: if (u == RFNOID && rfotherdeny) ! 57: return (0); ! 58: if (f->uid == u && u != RFNOID) ! 59: bits <<= RFPOWNER; ! 60: else if (f->gid == g && g != RFNOID) ! 61: bits <<= RFPGROUP; ! 62: else ! 63: bits <<= RFPOTHER; ! 64: return (f->mode & bits); ! 65: } ! 66: ! 67: /* ! 68: * read entries from a directory ! 69: * -- only read access is relevant ! 70: */ ! 71: _rfpdread(f, u, g) ! 72: register Rfile *f; ! 73: int u, g; ! 74: { ! 75: register int bits; ! 76: ! 77: if (u == SUSER) ! 78: return (1); ! 79: if (u == RFNOID && defaultuid != RFNOID) ! 80: u = defaultuid; ! 81: if (g == RFNOID && defaultgid != RFNOID) ! 82: g = defaultgid; ! 83: bits = RFPRD; ! 84: if (u == RFNOID && rfotherdeny) ! 85: return (0); ! 86: if (f->uid == u && u != RFNOID) ! 87: bits <<= RFPOWNER; ! 88: else if (f->gid == g && g != RFNOID) ! 89: bits <<= RFPGROUP; ! 90: else ! 91: bits <<= RFPOTHER; ! 92: return (f->mode & bits); ! 93: } ! 94: ! 95: /* ! 96: * write a regular file ! 97: */ ! 98: _rfpwrite(f, u, g) ! 99: register Rfile *f; ! 100: int u, g; ! 101: { ! 102: register int bits; ! 103: ! 104: if (u == SUSER) ! 105: return (1); ! 106: if (u == RFNOID && defaultuid != RFNOID) ! 107: u = defaultuid; ! 108: if (g == RFNOID && defaultgid != RFNOID) ! 109: g = defaultgid; ! 110: bits = RFPWR; ! 111: if (u == RFNOID && rfotherdeny) ! 112: return (0); ! 113: if (f->uid == u && u != RFNOID) ! 114: bits <<= RFPOWNER; ! 115: else if (f->gid == g && g != RFNOID) ! 116: bits <<= RFPGROUP; ! 117: else ! 118: bits <<= RFPOTHER; ! 119: return (f->mode & bits); ! 120: } ! 121: ! 122: /* ! 123: * write a directory (change entries therein) ! 124: */ ! 125: _rfpdwrite(f, u, g) ! 126: register Rfile *f; ! 127: int u, g; ! 128: { ! 129: register int bits; ! 130: ! 131: if (u == SUSER) ! 132: return (1); ! 133: if (u == RFNOID && defaultuid != RFNOID) ! 134: u = defaultuid; ! 135: if (g == RFNOID && defaultgid != RFNOID) ! 136: g = defaultgid; ! 137: bits = RFPWR; ! 138: if (u == RFNOID && rfotherdeny) ! 139: return (0); ! 140: if (f->uid == u && u != RFNOID) ! 141: bits <<= RFPOWNER; ! 142: else if (f->gid == g && g != RFNOID) ! 143: bits <<= RFPGROUP; ! 144: else ! 145: bits <<= RFPOTHER; ! 146: return (f->mode & bits); ! 147: } ! 148: ! 149: /* ! 150: * search a directory for a single entry ! 151: */ ! 152: _rfpdsearch(f, u, g) ! 153: register Rfile *f; ! 154: int u, g; ! 155: { ! 156: register int bits; ! 157: ! 158: if (u == SUSER) ! 159: return (1); ! 160: if (u == RFNOID && defaultuid != RFNOID) ! 161: u = defaultuid; ! 162: if (g == RFNOID && defaultgid != RFNOID) ! 163: g = defaultgid; ! 164: bits = RFPDS; ! 165: if (u == RFNOID && rfotherdeny) ! 166: return (0); ! 167: if (f->uid == u && u != RFNOID) ! 168: bits <<= RFPOWNER; ! 169: else if (f->gid == g && g != RFNOID) ! 170: bits <<= RFPGROUP; ! 171: else ! 172: bits <<= RFPOTHER; ! 173: return (f->mode & bits); ! 174: } ! 175: ! 176: /* ! 177: * is this the file's owner? ! 178: * only the owner may change attribute like the mode ! 179: */ ! 180: _rfpowner(f, u, g) ! 181: register Rfile *f; ! 182: int u, g; ! 183: { ! 184: if (u == SUSER) ! 185: return (1); ! 186: if (u == RFNOID && defaultuid != RFNOID) ! 187: u = defaultuid; ! 188: if (g == RFNOID && defaultgid != RFNOID) ! 189: g = defaultgid; ! 190: if (u == RFNOID) ! 191: return (0); ! 192: return (f->uid == u); ! 193: } ! 194: ! 195: /* ! 196: * is this a privileged user? ! 197: */ ! 198: int ! 199: _rfpsuper(f, u, g) ! 200: Rfile *f; ! 201: int u, g; ! 202: { ! 203: return (u == SUSER); ! 204: } ! 205: ! 206: /* ! 207: * given one kind of id (password or group, client or server) ! 208: * return another ! 209: */ ! 210: ! 211: int ! 212: _rfcuid(id) ! 213: int id; ! 214: { ! 215: register int i; ! 216: ! 217: if (id < 0) /* safety */ ! 218: return (RFNOID); ! 219: for (i = id % _rfuhp; _rfsu[i] != RFNOID; i++) ! 220: if (_rfuids[_rfsu[i]].sid == id) ! 221: return (_rfuids[_rfsu[i]].cid); ! 222: return (RFNOID); ! 223: } ! 224: ! 225: int ! 226: _rfcgid(id) ! 227: int id; ! 228: { ! 229: register int i; ! 230: ! 231: if (id < 0) /* safety */ ! 232: return (RFNOID); ! 233: for (i = id % _rfghp; _rfsg[i] != RFNOID; i++) ! 234: if (_rfgids[_rfsg[i]].sid == id) ! 235: return (_rfgids[_rfsg[i]].cid); ! 236: return (RFNOID); ! 237: } ! 238: ! 239: int ! 240: _rfsuid(id) ! 241: int id; ! 242: { ! 243: register int i; ! 244: ! 245: if (id < 0) /* safety */ ! 246: return (RFNOID); ! 247: for (i = id % _rfuhp; _rfcu[i] != RFNOID; i++) ! 248: if (_rfuids[_rfcu[i]].cid == id) ! 249: return (_rfuids[_rfcu[i]].sid); ! 250: return (RFNOID); ! 251: } ! 252: ! 253: int ! 254: _rfsgid(id) ! 255: int id; ! 256: { ! 257: register int i; ! 258: ! 259: if (id < 0) /* safety */ ! 260: return (RFNOID); ! 261: for (i = id % _rfghp; _rfcg[i] != RFNOID; i++) ! 262: if (_rfgids[_rfcg[i]].cid == id) ! 263: return (_rfgids[_rfcg[i]].sid); ! 264: return (RFNOID); ! 265: } ! 266: ! 267: /* ! 268: * make hash tables ! 269: */ ! 270: ! 271: #define SLOP 4 ! 272: ! 273: static short primes[] = {23, 47, 97, 199, 397, 797, 1597, 3191, 6397, 12799, 31991, 0}; ! 274: ! 275: _rfmkhash(tab, size, php, pchash, phhash) ! 276: Tuid *tab; ! 277: int size; ! 278: int *php; ! 279: int **pchash, **phhash; ! 280: { ! 281: register int i, j, hp; ! 282: register int *ch, *cc; ! 283: int max; ! 284: ! 285: for (i = 0; primes[i] && primes[i] < size * 2; i++) ! 286: ; ! 287: hp = primes[i]; ! 288: *php = hp; ! 289: max = hp + SLOP; ! 290: if ((ch = (int *)malloc(max*sizeof(int))) == NULL ! 291: || (cc = (int *)malloc(max*sizeof(int))) == NULL) ! 292: rfpanic("no memory for hash tables (%d ints)\n", hp); ! 293: *phhash = ch; ! 294: *pchash = cc; ! 295: for (i = 0; i < max; i++) ! 296: ch[i] = cc[i] = RFNOID; ! 297: for (i = 0; tab[i].sid != RFNOID; i++) { ! 298: j = tab[i].sid % hp; ! 299: while (ch[j] != RFNOID && j < max) ! 300: j++; ! 301: if (j >= max) ! 302: rfpanic("hash overflow\n"); ! 303: ch[j] = i; ! 304: j = tab[i].cid % hp; ! 305: while (cc[j] != RFNOID && j < max) ! 306: j++; ! 307: if (j >= max) ! 308: rfpanic("hash overflow\n"); ! 309: cc[j] = i; ! 310: } ! 311: } ! 312: ! 313: /* ! 314: * look up a name in an Idmap list ! 315: * used only in building id tables ! 316: */ ! 317: int ! 318: _rflookid(p, s) ! 319: register Idmap *p; ! 320: register char *s; ! 321: { ! 322: ! 323: for (; p->name[0]; p++) { ! 324: if (p->name[0] != s[0]) /* shortcut */ ! 325: continue; ! 326: if (strncmp(p->name, s, sizeof(p->name)-1) == 0) ! 327: return (p->id); ! 328: } ! 329: return (RFNOID); ! 330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.