nfs.c 9.3 KB

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