|
|
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.