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