1 #include "all.h" 2 3 extern uchar buf[]; 4 5 Xfid * 6 rpc2xfid(Rpccall *cmd, Dir *dp) 7 { 8 char *argptr = cmd->args; 9 Xfile *xp; 10 Xfid *xf; 11 Session *s; 12 char *service; 13 Authunix au; 14 Qid qid; 15 char client[256], *user; 16 Unixidmap *m; 17 int i; 18 uvlong x1, x2; 19 20 chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr); 21 if(argptr[0] == 0 && argptr[1] == 0){ /* root */ 22 chat("root..."); 23 xp = xfroot(&argptr[2], 0); 24 s = xp ? xp->s : 0; 25 }else{ 26 ulong ul; 27 chat("noroot %.8lux...", *((ulong*)argptr)); 28 if((ul=GLONG()) != starttime){ 29 chat("bad tag %lux %lux...", ul, starttime); 30 return 0; 31 } 32 s = (Session *)GLONG(); 33 x1 = GLONG(); 34 x2 = GLONG(); 35 qid.path = x1 | (x2<<32); 36 qid.vers = 0; 37 qid.type = GBYTE(); 38 xp = xfile(&qid, s, 0); 39 } 40 if(xp == 0){ 41 chat("no xfile..."); 42 return 0; 43 } 44 if(auth2unix(&cmd->cred, &au) != 0){ 45 chat("auth flavor=%ld, count=%ld\n", 46 cmd->cred.flavor, cmd->cred.count); 47 for(i=0; i<cmd->cred.count; i++) 48 chat(" %.2ux", ((uchar *)cmd->cred.data)[i]); 49 chat("..."); 50 return 0; 51 }else{ 52 /* chat("auth: %d %.*s u=%d g=%d", 53 * au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid); 54 * for(i=0; i<au.gidlen; i++) 55 * chat(", %d", au.gids[i]); 56 * chat("..."); 57 */ 58 char *p = memchr(au.mach.s, '.', au.mach.n); 59 chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s); 60 } 61 if(au.mach.n >= sizeof client){ 62 chat("client name too long..."); 63 return 0; 64 } 65 memcpy(client, au.mach.s, au.mach.n); 66 client[au.mach.n] = 0; 67 service = xp->parent->s->service; 68 cmd->up = m = pair2idmap(service, cmd->host); 69 if(m == 0){ 70 chat("no map for pair (%s,%s)...", service, client); 71 /*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF, 72 (cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/ 73 /*if(getdom(cmd->host, client, sizeof(client))<0) 74 return 0;/**/ 75 return 0; 76 } 77 /*chat("map=(%s,%s)...", m->server, m->client);/**/ 78 cmd->user = user = id2name(&m->u.ids, au.uid); 79 if(user == 0){ 80 chat("no user for id %ld...", au.uid); 81 return 0; 82 } 83 chat("user=%s...", user);/**/ 84 xf = 0; 85 if(s == xp->parent->s){ 86 if(!s->noauth) 87 xf = setuser(xp, user); 88 if(xf == 0) 89 xf = setuser(xp, "none"); 90 if(xf == 0) 91 chat("can't set user none..."); 92 }else 93 xf = xp->users; 94 if(xf) 95 chat("uid=%s...", xf->uid); 96 if(xf && dp && xfstat(xf, dp) < 0){ 97 chat("can't stat %s...", xp->name); 98 return 0; 99 } 100 return xf; 101 } 102 103 Xfid * 104 setuser(Xfile *xp, char *user) 105 { 106 Xfid *xf, *xpf; 107 Session *s; 108 109 xf = xfid(user, xp, 1); 110 if(xf->urfid) 111 return xf; 112 if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */ 113 return xfid(user, xp, -1); 114 s = xp->s; 115 xf->urfid = newfid(s); 116 xf->urfid->owner = &xf->urfid; 117 setfid(s, xpf->urfid); 118 s->f.newfid = xf->urfid - s->fids; 119 s->f.nwname = 1; 120 s->f.wname[0] = xp->name; 121 if(xmesg(s, Twalk) || s->f.nwqid != 1) 122 return xfid(user, xp, -1); 123 return xf; 124 } 125 126 int 127 xfstat(Xfid *xf, Dir *dp) 128 { 129 Xfile *xp; 130 Session *s; 131 char buf[128]; 132 133 xp = xf->xp; 134 s = xp->s; 135 if(s != xp->parent->s){ 136 seprint(buf, buf+sizeof buf, "#%s", xf->uid); 137 dp->name = strstore(buf); 138 dp->uid = xf->uid; 139 dp->gid = xf->uid; 140 dp->muid = xf->uid; 141 dp->qid.path = (uvlong)xf->uid; 142 dp->qid.type = QTFILE; 143 dp->qid.vers = 0; 144 dp->mode = 0666; 145 dp->atime = time(0); 146 dp->mtime = dp->atime; 147 dp->length = NETCHLEN; 148 dp->type = 0; 149 dp->type = 0; 150 return 0; 151 } 152 setfid(s, xf->urfid); 153 if(xmesg(s, Tstat) == 0){ 154 convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf); 155 if(xp->qid.path == dp->qid.path){ 156 xp->name = strstore(dp->name); 157 return 0; 158 } 159 /* not reached ? */ 160 chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...", 161 xp->qid.path, dp->qid.path, dp->name); 162 } 163 if(xp != xp->parent) 164 xpclear(xp); 165 else 166 clog("can't stat root: %s", 167 s->f.type == Rerror ? s->f.ename : "??"); 168 return -1; 169 } 170 171 int 172 xfwstat(Xfid *xf, Dir *dp) 173 { 174 Xfile *xp; 175 Session *s; 176 177 xp = xf->xp; 178 s = xp->s; 179 180 /* 181 * xf->urfid can be zero because some DOS NFS clients 182 * try to do wstat on the #user authentication files on close. 183 */ 184 if(s == 0 || xf->urfid == 0) 185 return -1; 186 setfid(s, xf->urfid); 187 s->f.stat = s->statbuf; 188 convD2M(dp, s->f.stat, Maxstatdata); 189 if(xmesg(s, Twstat)) 190 return -1; 191 xp->name = strstore(dp->name); 192 return 0; 193 } 194 195 int 196 xfopen(Xfid *xf, int flag) 197 { 198 static int modes[] = { 199 [Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR, 200 }; 201 Xfile *xp; 202 Session *s; 203 Fid *opfid; 204 int omode; 205 206 if(xf->opfid && (xf->mode & flag & Open) == flag) 207 return 0; 208 omode = modes[(xf->mode|flag) & Open]; 209 if(flag & Trunc) 210 omode |= OTRUNC; 211 xp = xf->xp; 212 chat("open(\"%s\", %d)...", xp->name, omode); 213 s = xp->s; 214 opfid = newfid(s); 215 setfid(s, xf->urfid); 216 s->f.newfid = opfid - s->fids; 217 s->f.nwname = 0; 218 if(xmesg(s, Twalk)){ 219 putfid(s, opfid); 220 return -1; 221 } 222 setfid(s, opfid); 223 s->f.mode = omode; 224 if(xmesg(s, Topen)){ 225 clunkfid(s, opfid); 226 return -1; 227 } 228 if(xf->opfid) 229 clunkfid(s, xf->opfid); 230 xf->mode |= flag & Open; 231 xf->opfid = opfid; 232 opfid->owner = &xf->opfid; 233 xf->offset = 0; 234 return 0; 235 } 236 237 void 238 xfclose(Xfid *xf) 239 { 240 Xfile *xp; 241 242 if(xf->mode & Open){ 243 xp = xf->xp; 244 chat("close(\"%s\")...", xp->name); 245 if(xf->opfid) 246 clunkfid(xp->s, xf->opfid); 247 xf->mode &= ~Open; 248 xf->opfid = 0; 249 } 250 } 251 252 void 253 xfclear(Xfid *xf) 254 { 255 Xfile *xp = xf->xp; 256 257 if(xf->opfid){ 258 clunkfid(xp->s, xf->opfid); 259 xf->opfid = 0; 260 } 261 if(xf->urfid){ 262 clunkfid(xp->s, xf->urfid); 263 xf->urfid = 0; 264 } 265 xfid(xf->uid, xp, -1); 266 } 267 268 Xfid * 269 xfwalkcr(int type, Xfid *xf, String *elem, long perm) 270 { 271 Session *s; 272 Xfile *xp, *newxp; 273 Xfid *newxf; 274 Fid *nfid; 275 276 chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s); 277 xp = xf->xp; 278 s = xp->s; 279 nfid = newfid(s); 280 setfid(s, xf->urfid); 281 s->f.newfid = nfid - s->fids; 282 if(type == Tcreate){ 283 s->f.nwname = 0; 284 if(xmesg(s, Twalk)){ 285 putfid(s, nfid); 286 return 0; 287 } 288 s->f.fid = nfid - s->fids; 289 } 290 if(type == Tcreate){ 291 s->f.name = elem->s; 292 s->f.perm = perm; 293 s->f.mode = (perm&DMDIR) ? OREAD : ORDWR; 294 if(xmesg(s, type)){ 295 clunkfid(s, nfid); 296 return 0; 297 } 298 }else{ /* Twalk */ 299 s->f.nwname = 1; 300 s->f.wname[0] = elem->s; 301 if(xmesg(s, type) || s->f.nwqid!=1){ 302 putfid(s, nfid); 303 return 0; 304 } 305 s->f.qid = s->f.wqid[0]; /* only one element */ 306 } 307 chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type); 308 newxp = xfile(&s->f.qid, s, 1); 309 if(newxp->parent == 0){ 310 chat("new xfile..."); 311 newxp->parent = xp; 312 newxp->sib = xp->child; 313 xp->child = newxp; 314 } 315 newxf = xfid(xf->uid, newxp, 1); 316 if(type == Tcreate){ 317 newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite); 318 newxf->opfid = nfid; 319 nfid->owner = &newxf->opfid; 320 nfid = newfid(s); 321 setfid(s, xf->urfid); 322 s->f.newfid = nfid - s->fids; 323 s->f.nwname = 1; 324 s->f.wname[0] = elem->s; 325 if(xmesg(s, Twalk) || s->f.nwqid!=1){ 326 putfid(s, nfid); 327 xpclear(newxp); 328 return 0; 329 } 330 newxf->urfid = nfid; 331 nfid->owner = &newxf->urfid; 332 }else if(newxf->urfid){ 333 chat("old xfid %ld...", newxf->urfid-s->fids); 334 clunkfid(s, nfid); 335 }else{ 336 newxf->urfid = nfid; 337 nfid->owner = &newxf->urfid; 338 } 339 newxp->name = strstore(elem->s); 340 return newxf; 341 } 342 343 void 344 xpclear(Xfile *xp) 345 { 346 Session *s; 347 Xfid *xf; 348 Xfile *xnp; 349 350 s = xp->s; 351 while(xf = xp->users) /* assign = */ 352 xfclear(xf); 353 while(xnp = xp->child){ /* assign = */ 354 xp->child = xnp->sib; 355 xnp->parent = 0; 356 xpclear(xnp); 357 xfile(&xnp->qid, s, -1); 358 } 359 if(xnp = xp->parent){ /* assign = */ 360 if(xnp->child == xp) 361 xnp->child = xp->sib; 362 else{ 363 xnp = xnp->child; 364 while(xnp->sib != xp) 365 xnp = xnp->sib; 366 xnp->sib = xp->sib; 367 } 368 xfile(&xp->qid, s, -1); 369 } 370 } 371 372 int 373 xp2fhandle(Xfile *xp, Fhandle fh) 374 { 375 uchar *dataptr = fh; 376 ulong x; 377 int n; 378 379 memset(fh, 0, FHSIZE); 380 if(xp == xp->parent){ /* root */ 381 dataptr[0] = 0; 382 dataptr[1] = 0; 383 n = strlen(xp->s->service); 384 if(n > FHSIZE-3) 385 n = FHSIZE-3; 386 memmove(&dataptr[2], xp->s->service, n); 387 dataptr[2+n] = 0; 388 }else{ 389 PLONG(starttime); 390 PLONG((u32int)(uintptr)xp->s); 391 x = xp->qid.path; 392 PLONG(x); 393 x = xp->qid.path>>32; 394 PLONG(x); 395 PBYTE(xp->qid.type); 396 USED(dataptr); 397 } 398 return FHSIZE; 399 } 400 401 int 402 dir2fattr(Unixidmap *up, Dir *dp, void *mp) 403 { 404 uchar *dataptr = mp; 405 long length; 406 int r; 407 408 r = dp->mode & 0777; 409 if (dp->mode & DMDIR) 410 length = 1024; 411 else 412 length = dp->length; 413 if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0) 414 r |= 0555; 415 if(dp->mode & DMDIR){ 416 PLONG(NFDIR); /* type */ 417 r |= S_IFDIR; 418 PLONG(r); /* mode */ 419 PLONG(3); /* nlink */ 420 }else{ 421 PLONG(NFREG); /* type */ 422 r |= S_IFREG; 423 PLONG(r); /* mode */ 424 PLONG(1); /* nlink */ 425 } 426 r = name2id(&up->u.ids, dp->uid); 427 if(r < 0){ 428 r = name2id(&up->u.ids, "daemon"); 429 if(r < 0) 430 r = 1; 431 } 432 PLONG(r); /* uid */ 433 r = name2id(&up->g.ids, dp->gid); 434 if(r < 0){ 435 r = name2id(&up->g.ids, "user"); 436 if(r < 0) 437 r = 1; 438 } 439 PLONG(r); /* gid */ 440 PLONG(length); /* size */ 441 PLONG(2048); /* blocksize */ 442 PLONG(0); /* rdev */ 443 r = (length+2047)/2048; 444 PLONG(r); /* blocks */ 445 r = (dp->type<<16) | dp->dev; 446 PLONG(r); /* fsid */ 447 PLONG(dp->qid.path); /* fileid */ 448 PLONG(dp->atime); /* atime */ 449 PLONG(0); 450 PLONG(dp->mtime); /* mtime */ 451 PLONG(0); 452 PLONG(dp->mtime); /* ctime */ 453 PLONG(0); 454 return dataptr - (uchar *)mp; 455 } 456 457 int 458 convM2sattr(void *mp, Sattr *sp) 459 { 460 uchar *argptr = mp; 461 462 sp->mode = GLONG(); 463 sp->uid = GLONG(); 464 sp->gid = GLONG(); 465 sp->size = GLONG(); 466 sp->atime = GLONG(); 467 sp->ausec = GLONG(); 468 sp->mtime = GLONG(); 469 sp->musec = GLONG(); 470 return argptr - (uchar *)mp; 471 } 472