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 } 66 67 #ifdef sometime 68 /* 69 * file format is 70 * uid:name:lead:member,member,...\n 71 */ 72 void 73 read_user(void) 74 { 75 int c; 76 77 if((c=fname(ustr))!=':' || (c=fname(name))!=':' || (c=fname(lead))!=':') 78 goto skipline; 79 n = atol(ustr); 80 if(n == 0) 81 goto skipline; 82 if(readu){ 83 o -= strlen(name)+1; 84 if(o < 0) { 85 cprint("conf.uidspace(%ld) too small\n", conf.uidspace); 86 return -1; 87 } 88 strcpy(uidspace+o, name); 89 uid[u].uid = n; 90 uid[u].offset = o; 91 u++; 92 if(u >= conf.nuid) { 93 cprint("conf.nuid(%ld) too small\n", conf.nuid); 94 goto initu; 95 } 96 }else{ 97 o = strtouid1(name); 98 if(o == 0 && strcmp(name, "") != 0) 99 o = n; 100 for(c=0; c<u; c++) 101 if(uid[c].uid == n) { 102 uid[c].lead = o; 103 break; 104 } 105 while(((c=fname(name))==',' || c=='\n') && name[0]){ 106 work here 107 if(c=='\n') 108 break; 109 } 110 } 111 112 skipline: 113 while(c != '\n') 114 fname(ustr); 115 } 116 #endif 117 118 /* 119 -1:adm:adm: 120 0:none:adm: 121 1:tor:tor: 122 10000:sys:: 123 10001:map:map: 124 10002:doc:: 125 10003:upas:upas: 126 10004:font:: 127 10005:bootes:bootes: 128 */ 129 130 struct { 131 int uid; 132 char *name; 133 int leader; 134 } 135 admusers[] = { 136 -1, "adm", -1, 137 0, "none", -1, 138 1, "tor", 1, 139 2, "glenda", 2, 140 10000, "sys", 0, 141 10001, "upas", 10001, 142 10002, "bootes", 10002, 143 0, 0, 0, 144 }; 145 146 147 void 148 cmd_user(void) 149 { 150 int c, n, o, u, g, i; 151 char name[NAMELEN]; 152 153 if(con_clone(FID1, FID2)) 154 goto ainitu; 155 if(con_path(FID2, "/adm/users")) 156 goto ainitu; 157 if(con_open(FID2, 0)){ 158 goto ainitu; 159 } 160 161 wlock(&uidgc.uidlock); 162 uidgc.uidbuf = malloc(MAXDAT); 163 164 memset(uid, 0, conf.nuid * sizeof(*uid)); 165 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 166 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 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 ainitu: 306 wlock(&uidgc.uidlock); 307 uidgc.uidbuf = malloc(MAXDAT); 308 309 initu: 310 cprint("initializing minimal user table\n"); 311 memset(uid, 0, conf.nuid * sizeof(*uid)); 312 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 313 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 314 o = conf.uidspace; 315 u = 0; 316 317 for(i=0; admusers[i].name; i++){ 318 o -= strlen(admusers[i].name)+1; 319 strcpy(uidspace+o, admusers[i].name); 320 uid[u].uid = admusers[i].uid; 321 uid[u].lead = admusers[i].leader; 322 uid[u].offset = o; 323 u++; 324 } 325 326 out: 327 free(uidgc.uidbuf); 328 writegroup = strtouid1("write"); 329 wunlock(&uidgc.uidlock); 330 331 } 332 333 void 334 uidtostr(char *name, int id) 335 { 336 rlock(&uidgc.uidlock); 337 uidtostr1(name, id); 338 runlock(&uidgc.uidlock); 339 } 340 341 void 342 uidtostr1(char *name, int id) 343 { 344 Uid *u; 345 int i; 346 347 if(id == 0){ 348 strncpy(name, "none", NAMELEN); 349 return; 350 } 351 for(i=0, u=uid; i<conf.nuid; i++,u++) { 352 if(u->uid == id) { 353 strncpy(name, uidspace+u->offset, NAMELEN); 354 return; 355 } 356 } 357 strncpy(name, "none", NAMELEN); 358 } 359 360 int 361 strtouid(char *s) 362 { 363 int i; 364 365 rlock(&uidgc.uidlock); 366 i = strtouid1(s); 367 runlock(&uidgc.uidlock); 368 return i; 369 } 370 371 int 372 strtouid1(char *s) 373 { 374 Uid *u; 375 int i; 376 377 for(i=0, u=uid; i<conf.nuid; i++,u++) 378 if(!strcmp(s, uidspace+u->offset)) 379 return u->uid; 380 return 0; 381 } 382 383 int 384 ingroup(int u, int g) 385 { 386 short *p; 387 388 if(u == g) 389 return 1; 390 rlock(&uidgc.uidlock); 391 for(p=gidspace; *p;) { 392 if(*p != g) { 393 for(p++; *p++;) 394 ; 395 continue; 396 } 397 for(p++; *p; p++) 398 if(*p == u) { 399 runlock(&uidgc.uidlock); 400 return 1; 401 } 402 } 403 runlock(&uidgc.uidlock); 404 return 0; 405 } 406 407 int 408 leadgroup(int ui, int gi) 409 { 410 Uid *u; 411 int i; 412 413 rlock(&uidgc.uidlock); 414 for(i=0, u=uid; i<conf.nuid; i++,u++) { 415 if(u->uid == gi) { 416 i = u->lead; 417 runlock(&uidgc.uidlock); 418 if(i == ui) 419 return 1; 420 if(i == 0) 421 return ingroup(ui, gi); 422 return 0; 423 } 424 } 425 runlock(&uidgc.uidlock); 426 return 0; 427 } 428