uid.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "all.h"
  10. struct
  11. {
  12. RWLock uidlock;
  13. char* uidbuf;
  14. int flen;
  15. int find;
  16. } uidgc;
  17. int
  18. byuid(const void *a1, const void *a2)
  19. {
  20. Uid *u1, *u2;
  21. u1 = a1;
  22. u2 = a2;
  23. return u2->uid - u1->uid;
  24. }
  25. int
  26. byname(const void *a1, const void *a2)
  27. {
  28. Uid *u1, *u2;
  29. u1 = a1;
  30. u2 = a2;
  31. return strcmp(uidspace+u2->offset, uidspace+u1->offset);
  32. }
  33. int
  34. fchar(void)
  35. {
  36. if(uidgc.find >= uidgc.flen) {
  37. uidgc.find = 0;
  38. uidgc.flen = con_read(FID2, uidgc.uidbuf, cons.offset, MAXDAT);
  39. if(uidgc.flen <= 0)
  40. return 0;
  41. cons.offset += uidgc.flen;
  42. }
  43. return uidgc.uidbuf[uidgc.find++];
  44. }
  45. int
  46. fname(char *name)
  47. {
  48. int i, c;
  49. memset(name, 0, NAMELEN);
  50. for(i=0;; i++) {
  51. c = fchar();
  52. switch(c) {
  53. case ':':
  54. case '\n':
  55. case ',':
  56. case ' ':
  57. case '#':
  58. case 0:
  59. return c;
  60. }
  61. if(i < NAMELEN-1)
  62. name[i] = c;
  63. }
  64. }
  65. #ifdef sometime
  66. /*
  67. * file format is
  68. * uid:name:lead:member,member,...\n
  69. */
  70. void
  71. read_user(void)
  72. {
  73. int c;
  74. if((c=fname(ustr))!=':' || (c=fname(name))!=':' || (c=fname(lead))!=':')
  75. goto skipline;
  76. n = atol(ustr);
  77. if(n == 0)
  78. goto skipline;
  79. if(readu){
  80. o -= strlen(name)+1;
  81. if(o < 0) {
  82. cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
  83. return -1;
  84. }
  85. strcpy(uidspace+o, name);
  86. uid[u].uid = n;
  87. uid[u].offset = o;
  88. u++;
  89. if(u >= conf.nuid) {
  90. cprint("conf.nuid(%ld) too small\n", conf.nuid);
  91. goto initu;
  92. }
  93. }else{
  94. o = strtouid1(name);
  95. if(o == 0 && strcmp(name, "") != 0)
  96. o = n;
  97. for(c=0; c<u; c++)
  98. if(uid[c].uid == n) {
  99. uid[c].lead = o;
  100. break;
  101. }
  102. while(((c=fname(name))==',' || c=='\n') && name[0]){
  103. work here
  104. if(c=='\n')
  105. break;
  106. }
  107. }
  108. skipline:
  109. while(c != '\n')
  110. fname(ustr);
  111. }
  112. #endif
  113. /*
  114. -1:adm:adm:
  115. 0:none:adm:
  116. 1:tor:tor:
  117. 10000:sys::
  118. 10001:map:map:
  119. 10002:doc::
  120. 10003:upas:upas:
  121. 10004:font::
  122. 10005:bootes:bootes:
  123. */
  124. struct {
  125. int uid;
  126. char *name;
  127. int leader;
  128. }
  129. admusers[] = {
  130. -1, "adm", -1,
  131. 0, "none", -1,
  132. 1, "tor", 1,
  133. 2, "glenda", 2,
  134. 10000, "sys", 0,
  135. 10001, "upas", 10001,
  136. 10002, "bootes", 10002,
  137. 0, 0, 0,
  138. };
  139. void
  140. cmd_user(void)
  141. {
  142. int c, n, o, u, g, i;
  143. char name[NAMELEN];
  144. if(con_clone(FID1, FID2))
  145. goto ainitu;
  146. if(con_path(FID2, "/adm/users"))
  147. goto ainitu;
  148. if(con_open(FID2, 0)){
  149. goto ainitu;
  150. }
  151. wlock(&uidgc.uidlock);
  152. uidgc.uidbuf = malloc(MAXDAT);
  153. memset(uid, 0, conf.nuid * sizeof(*uid));
  154. memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
  155. memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
  156. uidgc.flen = 0;
  157. uidgc.find = 0;
  158. cons.offset = 0;
  159. u = 0;
  160. o = conf.uidspace;
  161. ul1:
  162. c = fname(name);
  163. if(c != ':')
  164. goto uskip;
  165. n = atol(name);
  166. if(n == 0)
  167. goto uskip;
  168. c = fname(name);
  169. if(c != ':')
  170. goto uskip;
  171. o -= strlen(name)+1;
  172. if(o < 0) {
  173. cprint("conf.uidspace(%ld) too small\n", conf.uidspace);
  174. goto initu;
  175. }
  176. strcpy(uidspace+o, name);
  177. uid[u].uid = n;
  178. uid[u].offset = o;
  179. u++;
  180. if(u >= conf.nuid) {
  181. cprint("conf.nuid(%ld) too small\n", conf.nuid);
  182. goto initu;
  183. }
  184. uskip:
  185. if(c == '\n')
  186. goto ul1;
  187. if(c) {
  188. c = fname(name);
  189. goto uskip;
  190. }
  191. /* cprint("%d uids read\n", u);*/
  192. qsort(uid, u, sizeof(uid[0]), byuid);
  193. for(c=u-1; c>0; c--)
  194. if(uid[c].uid == uid[c-1].uid) {
  195. cprint("duplicate uids: %d\n", uid[c].uid);
  196. cprint(" %s", uidspace+uid[c].offset);
  197. cprint(" %s\n", uidspace+uid[c-1].offset);
  198. }
  199. qsort(uid, u, sizeof(uid[0]), byname);
  200. for(c=u-1; c>0; c--)
  201. if(!strcmp(uidspace+uid[c].offset,
  202. uidspace+uid[c-1].offset)) {
  203. cprint("kfs: duplicate names: %s\n", uidspace+uid[c].offset);
  204. cprint(" %d", uid[c].uid);
  205. cprint(" %d\n", uid[c-1].uid);
  206. }
  207. if(cons.flags & Fuid)
  208. for(c=0; c<u; c++)
  209. cprint("%6d %s\n", uid[c].uid, uidspace+uid[c].offset);
  210. uidgc.flen = 0;
  211. uidgc.find = 0;
  212. cons.offset = 0;
  213. g = 0;
  214. gl1:
  215. c = fname(name);
  216. if(c != ':')
  217. goto gskip;
  218. n = atol(name); /* number */
  219. if(n == 0)
  220. goto gskip;
  221. c = fname(name); /* name */
  222. if(c != ':')
  223. goto gskip;
  224. c = fname(name); /* leader */
  225. if(c != ':')
  226. goto gskip;
  227. o = strtouid1(name);
  228. if(o == 0 && strcmp(name, "") != 0)
  229. o = n;
  230. for(c=0; c<u; c++)
  231. if(uid[c].uid == n) {
  232. uid[c].lead = o;
  233. break;
  234. }
  235. c = fname(name); /* list of members */
  236. if(c != ',' && c != '\n')
  237. goto gskip;
  238. if(!name[0])
  239. goto gskip;
  240. gidspace[g++] = n;
  241. gl2:
  242. n = strtouid1(name);
  243. if(n)
  244. gidspace[g++] = n;
  245. if(g >= conf.gidspace-2) {
  246. cprint("conf.gidspace(%ld) too small\n", conf.gidspace);
  247. goto initu;
  248. }
  249. if(c == '\n')
  250. goto gl3;
  251. c = fname(name);
  252. if(c == ',' || c == '\n')
  253. goto gl2;
  254. cprint("gid truncated\n");
  255. gl3:
  256. gidspace[g++] = 0;
  257. gskip:
  258. if(c == '\n')
  259. goto gl1;
  260. if(c) {
  261. c = fname(name);
  262. goto gskip;
  263. }
  264. if(cons.flags & Fuid) {
  265. o = 0;
  266. for(c=0; c<g; c++) {
  267. n = gidspace[c];
  268. if(n == 0) {
  269. o = 0;
  270. continue;
  271. }
  272. uidtostr1(name, n);
  273. if(o) {
  274. if(o > 6) {
  275. cprint("\n %s", name);
  276. o = 1;
  277. } else
  278. cprint(" %s", name);
  279. } else
  280. cprint("\n%6s", name);
  281. o++;
  282. }
  283. cprint("\n");
  284. }
  285. goto out;
  286. ainitu:
  287. wlock(&uidgc.uidlock);
  288. uidgc.uidbuf = malloc(MAXDAT);
  289. initu:
  290. cprint("initializing minimal user table\n");
  291. memset(uid, 0, conf.nuid * sizeof(*uid));
  292. memset(uidspace, 0, conf.uidspace * sizeof(*uidspace));
  293. memset(gidspace, 0, conf.gidspace * sizeof(*gidspace));
  294. o = conf.uidspace;
  295. u = 0;
  296. for(i=0; admusers[i].name; i++){
  297. o -= strlen(admusers[i].name)+1;
  298. strcpy(uidspace+o, admusers[i].name);
  299. uid[u].uid = admusers[i].uid;
  300. uid[u].lead = admusers[i].leader;
  301. uid[u].offset = o;
  302. u++;
  303. }
  304. out:
  305. free(uidgc.uidbuf);
  306. writegroup = strtouid1("write");
  307. wunlock(&uidgc.uidlock);
  308. }
  309. void
  310. uidtostr(char *name, int id)
  311. {
  312. rlock(&uidgc.uidlock);
  313. uidtostr1(name, id);
  314. runlock(&uidgc.uidlock);
  315. }
  316. void
  317. uidtostr1(char *name, int id)
  318. {
  319. Uid *u;
  320. int i;
  321. if(id == 0){
  322. strncpy(name, "none", NAMELEN);
  323. return;
  324. }
  325. for(i=0, u=uid; i<conf.nuid; i++,u++) {
  326. if(u->uid == id) {
  327. strncpy(name, uidspace+u->offset, NAMELEN);
  328. return;
  329. }
  330. }
  331. strncpy(name, "none", NAMELEN);
  332. }
  333. int
  334. strtouid(char *s)
  335. {
  336. int i;
  337. rlock(&uidgc.uidlock);
  338. i = strtouid1(s);
  339. runlock(&uidgc.uidlock);
  340. return i;
  341. }
  342. int
  343. strtouid1(char *s)
  344. {
  345. Uid *u;
  346. int i;
  347. for(i=0, u=uid; i<conf.nuid; i++,u++)
  348. if(!strcmp(s, uidspace+u->offset))
  349. return u->uid;
  350. return 0;
  351. }
  352. int
  353. ingroup(int u, int g)
  354. {
  355. int16_t *p;
  356. if(u == g)
  357. return 1;
  358. rlock(&uidgc.uidlock);
  359. for(p=gidspace; *p;) {
  360. if(*p != g) {
  361. for(p++; *p++;)
  362. ;
  363. continue;
  364. }
  365. for(p++; *p; p++)
  366. if(*p == u) {
  367. runlock(&uidgc.uidlock);
  368. return 1;
  369. }
  370. }
  371. runlock(&uidgc.uidlock);
  372. return 0;
  373. }
  374. int
  375. leadgroup(int ui, int gi)
  376. {
  377. Uid *u;
  378. int i;
  379. rlock(&uidgc.uidlock);
  380. for(i=0, u=uid; i<conf.nuid; i++,u++) {
  381. if(u->uid == gi) {
  382. i = u->lead;
  383. runlock(&uidgc.uidlock);
  384. if(i == ui)
  385. return 1;
  386. if(i == 0)
  387. return ingroup(ui, gi);
  388. return 0;
  389. }
  390. }
  391. runlock(&uidgc.uidlock);
  392. return 0;
  393. }