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