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 if(con_clone(FID1, FID2)) 155 goto ainitu; 156 if(con_path(FID2, "/adm/users")) 157 goto ainitu; 158 if(con_open(FID2, 0)){ 159 goto ainitu; 160 } 161 162 wlock(&uidgc.uidlock); 163 uidgc.uidbuf = malloc(MAXDAT); 164 165 memset(uid, 0, conf.nuid * sizeof(*uid)); 166 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 167 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 168 169 uidgc.flen = 0; 170 uidgc.find = 0; 171 cons.offset = 0; 172 u = 0; 173 o = conf.uidspace; 174 175 ul1: 176 c = fname(name); 177 if(c != ':') 178 goto uskip; 179 n = atol(name); 180 if(n == 0) 181 goto uskip; 182 c = fname(name); 183 if(c != ':') 184 goto uskip; 185 o -= strlen(name)+1; 186 if(o < 0) { 187 cprint("conf.uidspace(%ld) too small\n", conf.uidspace); 188 goto initu; 189 } 190 strcpy(uidspace+o, name); 191 uid[u].uid = n; 192 uid[u].offset = o; 193 u++; 194 if(u >= conf.nuid) { 195 cprint("conf.nuid(%ld) too small\n", conf.nuid); 196 goto initu; 197 } 198 199 uskip: 200 if(c == '\n') 201 goto ul1; 202 if(c) { 203 c = fname(name); 204 goto uskip; 205 } 206 /* cprint("%d uids read\n", u);/**/ 207 qsort(uid, u, sizeof(uid[0]), byuid); 208 for(c=u-1; c>0; c--) 209 if(uid[c].uid == uid[c-1].uid) { 210 cprint("duplicate uids: %d\n", uid[c].uid); 211 cprint(" %s", uidspace+uid[c].offset); 212 cprint(" %s\n", uidspace+uid[c-1].offset); 213 } 214 qsort(uid, u, sizeof(uid[0]), byname); 215 for(c=u-1; c>0; c--) 216 if(!strcmp(uidspace+uid[c].offset, 217 uidspace+uid[c-1].offset)) { 218 cprint("kfs: duplicate names: %s\n", uidspace+uid[c].offset); 219 cprint(" %d", uid[c].uid); 220 cprint(" %d\n", uid[c-1].uid); 221 } 222 if(cons.flags & Fuid) 223 for(c=0; c<u; c++) 224 cprint("%6d %s\n", uid[c].uid, uidspace+uid[c].offset); 225 226 uidgc.flen = 0; 227 uidgc.find = 0; 228 cons.offset = 0; 229 g = 0; 230 231 gl1: 232 c = fname(name); 233 if(c != ':') 234 goto gskip; 235 n = atol(name); /* number */ 236 if(n == 0) 237 goto gskip; 238 c = fname(name); /* name */ 239 if(c != ':') 240 goto gskip; 241 c = fname(name); /* leader */ 242 if(c != ':') 243 goto gskip; 244 o = strtouid1(name); 245 if(o == 0 && strcmp(name, "") != 0) 246 o = n; 247 for(c=0; c<u; c++) 248 if(uid[c].uid == n) { 249 uid[c].lead = o; 250 break; 251 } 252 c = fname(name); /* list of members */ 253 if(c != ',' && c != '\n') 254 goto gskip; 255 if(!name[0]) 256 goto gskip; 257 gidspace[g++] = n; 258 gl2: 259 n = strtouid1(name); 260 if(n) 261 gidspace[g++] = n; 262 if(g >= conf.gidspace-2) { 263 cprint("conf.gidspace(%ld) too small\n", conf.gidspace); 264 goto initu; 265 } 266 if(c == '\n') 267 goto gl3; 268 c = fname(name); 269 if(c == ',' || c == '\n') 270 goto gl2; 271 cprint("gid truncated\n"); 272 273 gl3: 274 gidspace[g++] = 0; 275 276 gskip: 277 if(c == '\n') 278 goto gl1; 279 if(c) { 280 c = fname(name); 281 goto gskip; 282 } 283 if(cons.flags & Fuid) { 284 o = 0; 285 for(c=0; c<g; c++) { 286 n = gidspace[c]; 287 if(n == 0) { 288 o = 0; 289 continue; 290 } 291 uidtostr1(name, n); 292 if(o) { 293 if(o > 6) { 294 cprint("\n %s", name); 295 o = 1; 296 } else 297 cprint(" %s", name); 298 } else 299 cprint("\n%6s", name); 300 o++; 301 } 302 cprint("\n"); 303 } 304 goto out; 305 306 ainitu: 307 wlock(&uidgc.uidlock); 308 uidgc.uidbuf = malloc(MAXDAT); 309 310 initu: 311 cprint("initializing minimal user table\n"); 312 memset(uid, 0, conf.nuid * sizeof(*uid)); 313 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 314 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 315 o = conf.uidspace; 316 u = 0; 317 318 for(i=0; admusers[i].name; i++){ 319 o -= strlen(admusers[i].name)+1; 320 strcpy(uidspace+o, admusers[i].name); 321 uid[u].uid = admusers[i].uid; 322 uid[u].lead = admusers[i].leader; 323 uid[u].offset = o; 324 u++; 325 } 326 327 out: 328 free(uidgc.uidbuf); 329 writegroup = strtouid1("write"); 330 wunlock(&uidgc.uidlock); 331 332 } 333 334 void 335 uidtostr(char *name, int id) 336 { 337 rlock(&uidgc.uidlock); 338 uidtostr1(name, id); 339 runlock(&uidgc.uidlock); 340 } 341 342 void 343 uidtostr1(char *name, int id) 344 { 345 Uid *u; 346 int i; 347 348 if(id == 0){ 349 strncpy(name, "none", NAMELEN); 350 return; 351 } 352 for(i=0, u=uid; i<conf.nuid; i++,u++) { 353 if(u->uid == id) { 354 strncpy(name, uidspace+u->offset, NAMELEN); 355 return; 356 } 357 } 358 strncpy(name, "none", NAMELEN); 359 } 360 361 int 362 strtouid(char *s) 363 { 364 int i; 365 366 rlock(&uidgc.uidlock); 367 i = strtouid1(s); 368 runlock(&uidgc.uidlock); 369 return i; 370 } 371 372 int 373 strtouid1(char *s) 374 { 375 Uid *u; 376 int i; 377 378 for(i=0, u=uid; i<conf.nuid; i++,u++) 379 if(!strcmp(s, uidspace+u->offset)) 380 return u->uid; 381 return 0; 382 } 383 384 int 385 ingroup(int u, int g) 386 { 387 short *p; 388 389 if(u == g) 390 return 1; 391 rlock(&uidgc.uidlock); 392 for(p=gidspace; *p;) { 393 if(*p != g) { 394 for(p++; *p++;) 395 ; 396 continue; 397 } 398 for(p++; *p; p++) 399 if(*p == u) { 400 runlock(&uidgc.uidlock); 401 return 1; 402 } 403 } 404 runlock(&uidgc.uidlock); 405 return 0; 406 } 407 408 int 409 leadgroup(int ui, int gi) 410 { 411 Uid *u; 412 int i; 413 414 rlock(&uidgc.uidlock); 415 for(i=0, u=uid; i<conf.nuid; i++,u++) { 416 if(u->uid == gi) { 417 i = u->lead; 418 runlock(&uidgc.uidlock); 419 if(i == ui) 420 return 1; 421 if(i == 0) 422 return ingroup(ui, gi); 423 return 0; 424 } 425 } 426 runlock(&uidgc.uidlock); 427 return 0; 428 } 429