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 2, "glenda", 2, 142 10000, "sys", 0, 143 10001, "upas", 10001, 144 10002, "bootes", 10002, 145 0, 0, 0, 146 }; 147 148 149 void 150 cmd_user(void) 151 { 152 int c, n, o, u, g, i; 153 char name[NAMELEN]; 154 155 wlock(&uidgc.uidlock); 156 uidgc.uidbuf = getbuf(devnone, Cuidbuf, 0); 157 158 memset(uid, 0, conf.nuid * sizeof(*uid)); 159 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 160 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 161 162 if(con_clone(FID1, FID2)) 163 goto initu; 164 if(con_path(FID2, "/adm/users")) 165 goto initu; 166 if(con_open(FID2, 0)) 167 goto initu; 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 initu: 307 cprint("initializing minimal user table\n"); 308 memset(uid, 0, conf.nuid * sizeof(*uid)); 309 memset(uidspace, 0, conf.uidspace * sizeof(*uidspace)); 310 memset(gidspace, 0, conf.gidspace * sizeof(*gidspace)); 311 o = conf.uidspace; 312 u = 0; 313 314 for(i=0; admusers[i].name; i++){ 315 o -= strlen(admusers[i].name)+1; 316 strcpy(uidspace+o, admusers[i].name); 317 uid[u].uid = admusers[i].uid; 318 uid[u].lead = admusers[i].leader; 319 uid[u].offset = o; 320 u++; 321 } 322 323 out: 324 putbuf(uidgc.uidbuf); 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