Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / afs_nfsdisp.c
1 /*
2 * This software has been released under the terms of the IBM Public
3 * License. For details, see the LICENSE file in the top-level source
4 * directory or online at http://www.openafs.org/dl/license10.html
5 */
6
7 /*
8 * Implements:
9 */
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13
14 /* Ugly Ugly Ugly but precludes conflicting XDR macros; We want kernel xdr */
15 #define __XDR_INCLUDE__
16 #include "afs/stds.h"
17 #include "afs/sysincludes.h" /* Standard vendor system headers */
18 #if defined(AFS_SUN5_ENV) && !defined(AFS_NONFSTRANS)
19 #include "rpc/types.h"
20 #include "rpc/auth.h"
21 #include "rpc/auth_unix.h"
22 #include "rpc/auth_des.h"
23 #include "sys/tiuser.h"
24 #include "rpc/svc.h"
25 #include "nfs/nfs.h"
26
27 #include "nfs/export.h"
28 /* Solaris 11.1 defines areq to areq_u.areq (and auid to areq_u.auid), for
29 * shortcut accessors to the nfsauth_arg structure. Since we dare to use the
30 * names areq and auid as parameter names in a lot of functions, work around
31 * this by undefining it. */
32 #ifdef areq
33 # undef areq
34 #endif
35 #ifdef auid
36 # undef auid
37 #endif
38
39 #include "nfs/nfs_clnt.h"
40 #include "nfs/nfs_acl.h"
41 #include "afs/afsincludes.h"
42 #include "afs/afs_stats.h"
43 #include "afs/exporter.h"
44
45 static int xlatorinit_v2_done = 0;
46 static int xlatorinit_v3_done = 0;
47 extern int afs_nobody;
48 extern int afs_NFSRootOnly;
49
50 struct rfs_disp_tbl {
51 void (*dis_proc) ();
52 xdrproc_t dis_xdrargs;
53 xdrproc_t dis_fastxdrargs;
54 int dis_argsz;
55 xdrproc_t dis_xdrres;
56 xdrproc_t dis_fastxdrres;
57 int dis_ressz;
58 void (*dis_resfree) ();
59 int dis_flags;
60 fhandle_t(*dis_getfh) ();
61 };
62
63 struct afs_nfs_disp_tbl {
64 void (*afs_proc) ();
65 void (*orig_proc) ();
66 };
67 struct afs_nfs2_resp {
68 enum nfsstat status;
69 };
70
71 #ifndef ACL2_NPROC
72 #if defined(AFS_SUN510_ENV)
73 #define ACL2_NPROC 6
74 #else
75 #define ACL2_NPROC 5
76 #endif
77 #endif
78 struct afs_nfs_disp_tbl afs_rfs_disp_tbl[RFS_NPROC];
79 struct afs_nfs_disp_tbl afs_acl_disp_tbl[ACL2_NPROC];
80
81 static int
82 is_afs_fh(fhandle_t * fhp)
83 {
84 if ((fhp->fh_fsid.val[0] == AFS_VFSMAGIC)
85 && (fhp->fh_fsid.val[1] == AFS_VFSFSID))
86 return 1;
87 return 0;
88 }
89
90 afs_int32
91 nfs2_to_afs_call(int which, caddr_t * args, fhandle_t ** fhpp,
92 fhandle_t ** fh2pp)
93 {
94 struct vnode *vp;
95 fhandle_t *fhp1 = 0;
96 fhandle_t *fhp2 = 0;
97 int errorcode;
98
99 afs_Trace1(afs_iclSetp, CM_TRACE_NFSIN, ICL_TYPE_INT32, which);
100 *fh2pp = (fhandle_t *) 0;
101 switch (which) {
102 case RFS_GETATTR:
103 case RFS_READLINK:
104 case RFS_STATFS:
105 fhp1 = (fhandle_t *) args;
106 break;
107 case RFS_SETATTR:
108 {
109 struct nfssaargs *sargs = (struct nfssaargs *)args;
110 fhp1 = (fhandle_t *) & sargs->saa_fh;
111 break;
112 }
113 case RFS_LOOKUP:
114 {
115 struct nfsdiropargs *sargs = (struct nfsdiropargs *)args;
116 fhp1 = sargs->da_fhandle;
117 break;
118 }
119 case RFS_READ:
120 {
121 struct nfsreadargs *sargs = (struct nfsreadargs *)args;
122 fhp1 = (fhandle_t *) & sargs->ra_fhandle;
123 break;
124 }
125 case RFS_WRITE:
126 {
127 struct nfswriteargs *sargs = (struct nfswriteargs *)args;
128 fhp1 = (fhandle_t *) & sargs->wa_fhandle;
129 break;
130 }
131 case RFS_CREATE:
132 {
133 struct nfscreatargs *sargs = (struct nfscreatargs *)args;
134 fhp1 = sargs->ca_da.da_fhandle;
135 break;
136 }
137 case RFS_REMOVE:
138 {
139 struct nfsdiropargs *sargs = (struct nfsdiropargs *)args;
140 fhp1 = sargs->da_fhandle;
141 break;
142 }
143 case RFS_RENAME:
144 {
145 struct nfsrnmargs *sargs = (struct nfsrnmargs *)args;
146 fhp1 = sargs->rna_from.da_fhandle;
147 fhp2 = sargs->rna_to.da_fhandle;
148 break;
149 }
150 case RFS_LINK:
151 {
152 struct nfslinkargs *sargs = (struct nfslinkargs *)args;
153 fhp1 = sargs->la_from;
154 fhp2 = sargs->la_to.da_fhandle;
155 break;
156 }
157 case RFS_SYMLINK:
158 {
159 struct nfsslargs *sargs = (struct nfsslargs *)args;
160 fhp1 = sargs->sla_from.da_fhandle;
161 break;
162 }
163 case RFS_MKDIR:
164 {
165 struct nfscreatargs *sargs = (struct nfscreatargs *)args;
166 fhp1 = sargs->ca_da.da_fhandle;
167 break;
168 }
169 case RFS_RMDIR:
170 {
171 struct nfsdiropargs *sargs = (struct nfsdiropargs *)args;
172 fhp1 = sargs->da_fhandle;
173 break;
174 }
175 case RFS_READDIR:
176 {
177 struct nfsrddirargs *sargs = (struct nfsrddirargs *)args;
178 fhp1 = (fhandle_t *) & sargs->rda_fh;
179 break;
180 }
181 default:
182 return NULL;
183 }
184
185 /* Ok if arg 1 is in AFS or if 2 args and arg 2 is in AFS */
186 if (fhp1 && is_afs_fh(fhp1)) {
187 *fhpp = fhp1;
188 if (fhp2)
189 *fh2pp = fhp2;
190 return 1;
191 }
192 if (fhp2 && is_afs_fh(fhp2)) {
193 *fhpp = fhp1;
194 *fh2pp = fhp2;
195 return 1;
196 }
197 return NULL;
198 }
199
200 afs_int32
201 acl2_to_afs_call(int which, caddr_t * args, fhandle_t ** fhpp)
202 {
203 fhandle_t *fhp;
204
205 switch (which) {
206 case ACLPROC2_NULL:
207 {
208 return NULL;
209 }
210 case ACLPROC2_GETACL:
211 {
212 struct GETACL2args *sargs = (struct GETACL2args *)args;
213 fhp = &sargs->fh;
214 break;
215 }
216 case ACLPROC2_SETACL:
217 {
218 struct SETACL2args *sargs = (struct SETACL2args *)args;
219 fhp = &sargs->fh;
220 break;
221 }
222 case ACLPROC2_GETATTR:
223 {
224 struct GETATTR2args *sargs = (struct GETATTR2args *)args;
225 fhp = &sargs->fh;
226 break;
227 }
228 case ACLPROC2_ACCESS:
229 {
230 struct ACCESS2args *sargs = (struct ACCESS2args *)args;
231 fhp = &sargs->fh;
232 break;
233 }
234 #if defined(AFS_SUN510_ENV)
235 case ACLPROC2_GETXATTRDIR:
236 {
237 struct GETXATTRDIR2args *sargs = (struct GETXATTRDIR2args *)args;
238 fhp = &sargs->fh;
239 break;
240 }
241 #endif
242 default:
243 return NULL;
244 }
245
246 if (fhp && is_afs_fh(fhp)) {
247 *fhpp = fhp;
248 return 1;
249 }
250
251 return NULL;
252 }
253
254 int
255 afs_nfs2_dispatcher(int type, afs_int32 which, char *argp,
256 struct exportinfo **expp, struct svc_req *rp,
257 afs_ucred_t *crp)
258 {
259 afs_int32 call = 0;
260 afs_int32 code = 0;
261 afs_int32 client = 0;
262 struct sockaddr *sa;
263 fhandle_t *fh = (fhandle_t *) argp;
264 fhandle_t *fh2 = (fhandle_t *) 0;
265
266 if (!xlatorinit_v2_done)
267 return 2;
268
269 sa = (struct sockaddr *)svc_getrpccaller(rp->rq_xprt)->buf;
270 if (sa->sa_family == AF_INET)
271 client = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
272
273 AFS_GLOCK();
274 code = 0;
275 switch (type) {
276 case 0:
277 code = (client && nfs2_to_afs_call(which, argp, &fh, &fh2));
278 break;
279 case 1:
280 code = (client && acl2_to_afs_call(which, argp, &fh));
281 break;
282 default:
283 break;
284 }
285
286 if (code) {
287 struct afs_exporter *out = 0;
288 afs_int32 dummy;
289 static int once = 0;
290 struct SmallFid Sfid;
291
292 memcpy((char *)&Sfid, fh->fh_data, SIZEOF_SMALLFID);
293
294 afs_Trace2(afs_iclSetp, CM_TRACE_NFSIN1, ICL_TYPE_POINTER, client,
295 ICL_TYPE_FID, &Sfid);
296
297 /* We ran */
298 call = 1;
299 if (!once && *expp) {
300 afs_nobody = (*expp)->exi_export.ex_anon;
301 once = 1;
302 }
303 code =
304 afs_nfsclient_reqhandler((struct afs_exporter *)0, &crp, client,
305 &dummy, &out);
306
307 if (!code && out)
308 EXP_RELE(out);
309
310 if (code == EINVAL)
311 call = 2;
312 }
313
314 AFS_GUNLOCK();
315 return call;
316 }
317
318 void
319 afs_nfs2_smallfidder(struct nfsdiropres *dr)
320 {
321 fhandle_t *fhp = (fhandle_t *) & dr->dr_fhandle;
322 afs_int32 addr[2];
323 struct vcache *vcp;
324
325 #if defined(AFS_SUN5_64BIT_ENV)
326 /* See also afs_fid() */
327 memcpy((char *)addr, fhp->fh_data, SIZEOF_SMALLFID);
328 addr[1] = (addr[1] >> 48) & 0xffff;
329 #else
330 memcpy((char *)addr, fhp->fh_data, 2 * sizeof(long));
331 #endif
332
333 AFS_GLOCK();
334 vcp = VTOAFS((struct vnode *)addr[0]);
335
336 if (addr[1] == AFS_XLATOR_MAGIC) {
337 if (dr->dr_status == NFS_OK) {
338 struct SmallFid Sfid;
339 struct cell *tcell;
340
341 /* Make up and copy out a SmallFid */
342 tcell = afs_GetCell(vcp->f.fid.Cell, READ_LOCK);
343 Sfid.Volume = vcp->f.fid.Fid.Volume;
344 Sfid.CellAndUnique =
345 ((tcell->cellIndex << 24) | (vcp->f.fid.Fid.Unique & 0xffffff));
346 afs_PutCell(tcell, READ_LOCK);
347 Sfid.Vnode = (u_short) (vcp->f.fid.Fid.Vnode & 0xffff);
348 fhp->fh_len = SIZEOF_SMALLFID;
349 memcpy(dr->dr_fhandle.fh_data, (char *)&Sfid, fhp->fh_len);
350
351 afs_Trace3(afs_iclSetp, CM_TRACE_NFSOUT, ICL_TYPE_INT32, 0,
352 ICL_TYPE_POINTER, vcp, ICL_TYPE_FID, &Sfid);
353 }
354
355 /* If we have a ref, release it */
356 if (vcp->vrefCount >= 1)
357 AFS_RELE(AFSTOV(vcp));
358 }
359 AFS_GUNLOCK();
360 }
361
362 void
363 afs_nfs2_noaccess(struct afs_nfs2_resp *resp)
364 {
365 resp->status = NFSERR_ACCES;
366 }
367
368 void
369 afs_nfs2_null(char *args, char *xp, char *exp, char *rp, char *crp)
370 {
371 }
372
373 void
374 afs_nfs2_root(char *args, char *xp, char *exp, char *rp, char *crp)
375 {
376 }
377
378 void
379 afs_nfs2_writecache(char *args, char *xp, char *exp, char *rp, char *crp)
380 {
381 }
382
383 void
384 afs_nfs2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
385 {
386 u_int call;
387 afs_ucred_t *svcred = curthread->t_cred;
388 curthread->t_cred = (afs_ucred_t *)crp;
389 call = afs_nfs2_dispatcher(0, RFS_GETATTR, (char *)args, &exp, rp, crp);
390 if (call > 1)
391 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
392 else
393 (*afs_rfs_disp_tbl[RFS_GETATTR].orig_proc) (args, xp, exp, rp, crp);
394 curthread->t_cred = svcred;
395 return;
396 }
397
398 void
399 afs_nfs2_setattr(char *args, char *xp, char *exp, char *rp, char *crp)
400 {
401 u_int call;
402 afs_ucred_t *svcred = curthread->t_cred;
403 curthread->t_cred = (afs_ucred_t *)crp;
404 call = afs_nfs2_dispatcher(0, RFS_SETATTR, (char *)args, &exp, rp, crp);
405 if (call > 1)
406 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
407 else
408 (*afs_rfs_disp_tbl[RFS_SETATTR].orig_proc) (args, xp, exp, rp, crp);
409 curthread->t_cred = svcred;
410 return;
411 }
412
413 void
414 afs_nfs2_lookup(char *args, char *xp, char *exp, char *rp, char *crp)
415 {
416 u_int call;
417 afs_ucred_t *svcred = curthread->t_cred;
418 curthread->t_cred = (afs_ucred_t *)crp;
419 call = afs_nfs2_dispatcher(0, RFS_LOOKUP, (char *)args, &exp, rp, crp);
420 if (call > 1)
421 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
422 else {
423 (*afs_rfs_disp_tbl[RFS_LOOKUP].orig_proc) (args, xp, exp, rp, crp);
424 if (afs_NFSRootOnly && call)
425 afs_nfs2_smallfidder(xp);
426 }
427 curthread->t_cred = svcred;
428 return;
429 }
430
431 void
432 afs_nfs2_readlink(char *args, char *xp, char *exp, char *rp, char *crp)
433 {
434 u_int call;
435 afs_ucred_t *svcred = curthread->t_cred;
436 curthread->t_cred = (afs_ucred_t *)crp;
437 call = afs_nfs2_dispatcher(0, RFS_READLINK, (char *)args, &exp, rp, crp);
438 if (call > 1)
439 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
440 else
441 (*afs_rfs_disp_tbl[RFS_READLINK].orig_proc) (args, xp, exp, rp, crp);
442 curthread->t_cred = svcred;
443 return;
444 }
445
446 void
447 afs_nfs2_read(char *args, char *xp, char *exp, char *rp, char *crp)
448 {
449 u_int call;
450 afs_ucred_t *svcred = curthread->t_cred;
451 curthread->t_cred = (afs_ucred_t *)crp;
452 call = afs_nfs2_dispatcher(0, RFS_READ, (char *)args, &exp, rp, crp);
453 if (call > 1)
454 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
455 else
456 (*afs_rfs_disp_tbl[RFS_READ].orig_proc) (args, xp, exp, rp, crp);
457 curthread->t_cred = svcred;
458 return;
459 }
460
461 void
462 afs_nfs2_write(char *args, char *xp, char *exp, char *rp, char *crp)
463 {
464 u_int call;
465 afs_ucred_t *svcred = curthread->t_cred;
466 curthread->t_cred = (afs_ucred_t *)crp;
467 call = afs_nfs2_dispatcher(0, RFS_WRITE, (char *)args, &exp, rp, crp);
468 if (call > 1)
469 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
470 else
471 (*afs_rfs_disp_tbl[RFS_WRITE].orig_proc) (args, xp, exp, rp, crp);
472 curthread->t_cred = svcred;
473 return;
474 }
475
476 void
477 afs_nfs2_create(char *args, char *xp, char *exp, char *rp, char *crp)
478 {
479 u_int call;
480 afs_ucred_t *svcred = curthread->t_cred;
481 curthread->t_cred = (afs_ucred_t *)crp;
482 call = afs_nfs2_dispatcher(0, RFS_CREATE, (char *)args, &exp, rp, crp);
483 if (call > 1)
484 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
485 else {
486 (*afs_rfs_disp_tbl[RFS_CREATE].orig_proc) (args, xp, exp, rp, crp);
487 if (afs_NFSRootOnly && call)
488 afs_nfs2_smallfidder(xp);
489 }
490 curthread->t_cred = svcred;
491 return;
492 }
493
494 void
495 afs_nfs2_remove(char *args, char *xp, char *exp, char *rp, char *crp)
496 {
497 u_int call;
498 afs_ucred_t *svcred = curthread->t_cred;
499 curthread->t_cred = (afs_ucred_t *)crp;
500 call = afs_nfs2_dispatcher(0, RFS_REMOVE, (char *)args, &exp, rp, crp);
501 if (call > 1)
502 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
503 else
504 (*afs_rfs_disp_tbl[RFS_REMOVE].orig_proc) (args, xp, exp, rp, crp);
505 curthread->t_cred = svcred;
506 return;
507 }
508
509 void
510 afs_nfs2_rename(char *args, char *xp, char *exp, char *rp, char *crp)
511 {
512 u_int call;
513 afs_ucred_t *svcred = curthread->t_cred;
514 curthread->t_cred = (afs_ucred_t *)crp;
515 call = afs_nfs2_dispatcher(0, RFS_RENAME, (char *)args, &exp, rp, crp);
516 if (call > 1)
517 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
518 else
519 (*afs_rfs_disp_tbl[RFS_RENAME].orig_proc) (args, xp, exp, rp, crp);
520 curthread->t_cred = svcred;
521 return;
522 }
523
524 void
525 afs_nfs2_link(char *args, char *xp, char *exp, char *rp, char *crp)
526 {
527 u_int call;
528 afs_ucred_t *svcred = curthread->t_cred;
529 curthread->t_cred = (afs_ucred_t *)crp;
530 call = afs_nfs2_dispatcher(0, RFS_LINK, (char *)args, &exp, rp, crp);
531 if (call > 1)
532 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
533 else
534 (*afs_rfs_disp_tbl[RFS_LINK].orig_proc) (args, xp, exp, rp, crp);
535 curthread->t_cred = svcred;
536 return;
537 }
538
539 void
540 afs_nfs2_symlink(char *args, char *xp, char *exp, char *rp, char *crp)
541 {
542 u_int call;
543 afs_ucred_t *svcred = curthread->t_cred;
544 curthread->t_cred = (afs_ucred_t *)crp;
545 call = afs_nfs2_dispatcher(0, RFS_SYMLINK, (char *)args, &exp, rp, crp);
546 if (call > 1)
547 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
548 else
549 (*afs_rfs_disp_tbl[RFS_SYMLINK].orig_proc) (args, xp, exp, rp, crp);
550 curthread->t_cred = svcred;
551 return;
552 }
553
554 void
555 afs_nfs2_mkdir(char *args, char *xp, char *exp, char *rp, char *crp)
556 {
557 u_int call;
558 afs_ucred_t *svcred = curthread->t_cred;
559 curthread->t_cred = (afs_ucred_t *)crp;
560 call = afs_nfs2_dispatcher(0, RFS_MKDIR, (char *)args, &exp, rp, crp);
561 if (call > 1)
562 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
563 else {
564 (*afs_rfs_disp_tbl[RFS_MKDIR].orig_proc) (args, xp, exp, rp, crp);
565 if (afs_NFSRootOnly && call)
566 afs_nfs2_smallfidder(xp);
567 }
568 curthread->t_cred = svcred;
569 return;
570 }
571
572 void
573 afs_nfs2_rmdir(char *args, char *xp, char *exp, char *rp, char *crp)
574 {
575 u_int call;
576 afs_ucred_t *svcred = curthread->t_cred;
577 curthread->t_cred = (afs_ucred_t *)crp;
578 call = afs_nfs2_dispatcher(0, RFS_RMDIR, (char *)args, &exp, rp, crp);
579 if (call > 1)
580 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
581 else
582 (*afs_rfs_disp_tbl[RFS_RMDIR].orig_proc) (args, xp, exp, rp, crp);
583 curthread->t_cred = svcred;
584 return;
585 }
586
587 void
588 afs_nfs2_readdir(char *args, char *xp, char *exp, char *rp, char *crp)
589 {
590 u_int call;
591 afs_ucred_t *svcred = curthread->t_cred;
592 curthread->t_cred = (afs_ucred_t *)crp;
593 call = afs_nfs2_dispatcher(0, RFS_READDIR, (char *)args, &exp, rp, crp);
594 if (call > 1)
595 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
596 else
597 (*afs_rfs_disp_tbl[RFS_READDIR].orig_proc) (args, xp, exp, rp, crp);
598 curthread->t_cred = svcred;
599 return;
600 }
601
602 void
603 afs_nfs2_statfs(char *args, char *xp, char *exp, char *rp, char *crp)
604 {
605 u_int call;
606 afs_ucred_t *svcred = curthread->t_cred;
607 curthread->t_cred = (afs_ucred_t *)crp;
608 call = afs_nfs2_dispatcher(0, RFS_STATFS, (char *)args, &exp, rp, crp);
609 if (call > 1)
610 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
611 else
612 (*afs_rfs_disp_tbl[RFS_STATFS].orig_proc) (args, xp, exp, rp, crp);
613 curthread->t_cred = svcred;
614 return;
615 }
616
617 struct afs_nfs_disp_tbl afs_rfs_disp_tbl[RFS_NPROC] = {
618 {afs_nfs2_null},
619 {afs_nfs2_getattr},
620 {afs_nfs2_setattr},
621 {afs_nfs2_root},
622 {afs_nfs2_lookup},
623 {afs_nfs2_readlink},
624 {afs_nfs2_read},
625 {afs_nfs2_writecache},
626 {afs_nfs2_write},
627 {afs_nfs2_create},
628 {afs_nfs2_remove},
629 {afs_nfs2_rename},
630 {afs_nfs2_link},
631 {afs_nfs2_symlink},
632 {afs_nfs2_mkdir},
633 {afs_nfs2_rmdir},
634 {afs_nfs2_readdir},
635 {afs_nfs2_statfs}
636 };
637
638 void
639 afs_acl2_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
640 {
641 u_int call;
642 afs_ucred_t *svcred = curthread->t_cred;
643 curthread->t_cred = (afs_ucred_t *)crp;
644 call =
645 afs_nfs2_dispatcher(1, ACLPROC2_GETACL, (char *)args, &exp, rp, crp);
646 if (call > 1)
647 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
648 else
649 (*afs_acl_disp_tbl[ACLPROC2_GETACL].orig_proc) (args, xp, exp, rp,
650 crp);
651 curthread->t_cred = svcred;
652 return;
653 }
654
655 void
656 afs_acl2_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
657 {
658 u_int call;
659 afs_ucred_t *svcred = curthread->t_cred;
660 curthread->t_cred = (afs_ucred_t *)crp;
661 call =
662 afs_nfs2_dispatcher(1, ACLPROC2_SETACL, (char *)args, &exp, rp, crp);
663 if (call > 1)
664 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
665 else
666 (*afs_acl_disp_tbl[ACLPROC2_SETACL].orig_proc) (args, xp, exp, rp,
667 crp);
668 curthread->t_cred = svcred;
669 return;
670 }
671
672 void
673 afs_acl2_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
674 {
675 u_int call;
676 afs_ucred_t *svcred = curthread->t_cred;
677 curthread->t_cred = (afs_ucred_t *)crp;
678 call =
679 afs_nfs2_dispatcher(1, ACLPROC2_GETATTR, (char *)args, &exp, rp, crp);
680 if (call > 1)
681 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
682 else
683 (*afs_acl_disp_tbl[ACLPROC2_GETATTR].orig_proc) (args, xp, exp, rp,
684 crp);
685 curthread->t_cred = svcred;
686 return;
687 }
688
689 void
690 afs_acl2_access(char *args, char *xp, char *exp, char *rp, char *crp)
691 {
692 u_int call;
693 afs_ucred_t *svcred = curthread->t_cred;
694 curthread->t_cred = (afs_ucred_t *)crp;
695 call =
696 afs_nfs2_dispatcher(1, ACLPROC2_ACCESS, (char *)args, &exp, rp, crp);
697 if (call > 1)
698 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
699 else
700 (*afs_acl_disp_tbl[ACLPROC2_ACCESS].orig_proc) (args, xp, exp, rp,
701 crp);
702 curthread->t_cred = svcred;
703 return;
704 }
705
706 #if defined(AFS_SUN510_ENV)
707 void
708 afs_acl2_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
709 {
710 u_int call;
711 afs_ucred_t *svcred = curthread->t_cred;
712 curthread->t_cred = (afs_ucred_t *)crp;
713 call =
714 afs_nfs2_dispatcher(1, ACLPROC2_GETXATTRDIR, (char *)args, &exp, rp, crp);
715 if (call > 1)
716 afs_nfs2_noaccess((struct afs_nfs2_resp *)xp);
717 else
718 (*afs_acl_disp_tbl[ACLPROC2_GETXATTRDIR].orig_proc) (args, xp, exp, rp,
719 crp);
720 curthread->t_cred = svcred;
721 return;
722 }
723 #endif
724
725 struct afs_nfs_disp_tbl afs_acl_disp_tbl[ACL2_NPROC] = {
726 {afs_nfs2_null},
727 {afs_acl2_getacl},
728 {afs_acl2_setacl},
729 {afs_acl2_getattr},
730 {afs_acl2_access},
731 #if defined(AFS_SUN510_ENV)
732 {afs_acl2_getxattrdir}
733 #endif
734 };
735
736 /* Munge the dispatch tables to link us in first */
737 void
738 afs_xlatorinit_v2(struct rfs_disp_tbl *_rfs_tbl,
739 struct rfs_disp_tbl *_acl_tbl)
740 {
741 int i;
742
743 if (xlatorinit_v2_done++)
744 return;
745
746 for (i = 0; i < RFS_NPROC; i++) {
747 afs_rfs_disp_tbl[i].orig_proc = _rfs_tbl[i].dis_proc;
748 _rfs_tbl[i].dis_proc = afs_rfs_disp_tbl[i].afs_proc;
749 }
750
751 for (i = 0; i < 5; i++) {
752 afs_acl_disp_tbl[i].orig_proc = _acl_tbl[i].dis_proc;
753 _acl_tbl[i].dis_proc = afs_acl_disp_tbl[i].afs_proc;
754 }
755 }
756
757 #ifndef RFS3_NPROC
758 #define RFS3_NPROC 22
759 #endif
760
761 #ifndef ACL3_NPROC
762 #if defined(AFS_SUN510_ENV)
763 #define ACL3_NPROC 4
764 #else
765 #define ACL3_NPROC 3
766 #endif
767 #endif
768
769 struct afs_nfs_disp_tbl afs_rfs3_disp_tbl[RFS3_NPROC];
770 struct afs_nfs_disp_tbl afs_acl3_disp_tbl[ACL3_NPROC];
771
772 struct afs_nfs3_resp {
773 nfsstat3 status;
774 bool_t flags;
775 };
776 typedef struct afs_nfs3_resp afs_nfs3_resp;
777
778 static int
779 is_afs_fh3(nfs_fh3 * fhp)
780 {
781 if ((fhp->fh3_fsid.val[0] == AFS_VFSMAGIC)
782 && (fhp->fh3_fsid.val[1] == AFS_VFSFSID))
783 return 1;
784 return 0;
785 }
786
787 void
788 afs_nfs3_noaccess(struct afs_nfs3_resp *resp)
789 {
790 resp->status = NFS3ERR_ACCES;
791 resp->flags = FALSE;
792 }
793
794 void
795 afs_nfs3_notsupp(struct afs_nfs3_resp *resp)
796 {
797 resp->status = NFS3ERR_NOTSUPP;
798 resp->flags = FALSE;
799 }
800
801 afs_int32
802 nfs3_to_afs_call(int which, caddr_t * args, nfs_fh3 ** fhpp, nfs_fh3 ** fh2pp)
803 {
804 struct vnode *vp;
805 nfs_fh3 *fhp1 = 0;
806 nfs_fh3 *fhp2 = 0;
807 int errorcode;
808
809 afs_Trace1(afs_iclSetp, CM_TRACE_NFS3IN, ICL_TYPE_INT32, which);
810 *fh2pp = (nfs_fh3 *) 0;
811 switch (which) {
812 case NFSPROC3_GETATTR:
813 {
814 GETATTR3args *arg = (GETATTR3args *) args;
815 fhp1 = (nfs_fh3 *) & arg->object;
816 break;
817 }
818 case NFSPROC3_SETATTR:
819 {
820 SETATTR3args *arg = (SETATTR3args *) args;
821 fhp1 = (nfs_fh3 *) & arg->object;
822 break;
823 }
824 case NFSPROC3_LOOKUP:
825 {
826 LOOKUP3args *arg = (LOOKUP3args *) args;
827 fhp1 = (nfs_fh3 *) arg->what.dirp;
828 break;
829 }
830 case NFSPROC3_ACCESS:
831 {
832 ACCESS3args *arg = (ACCESS3args *) args;
833 fhp1 = (nfs_fh3 *) & arg->object;
834 break;
835 }
836 case NFSPROC3_READLINK:
837 {
838 READLINK3args *arg = (READLINK3args *) args;
839 fhp1 = (nfs_fh3 *) & arg->symlink;
840 break;
841 }
842 case NFSPROC3_READ:
843 {
844 READ3args *arg = (READ3args *) args;
845 fhp1 = (nfs_fh3 *) & arg->file;
846 break;
847 }
848 case NFSPROC3_WRITE:
849 {
850 WRITE3args *arg = (WRITE3args *) args;
851 fhp1 = (nfs_fh3 *) & arg->file;
852 break;
853 }
854 case NFSPROC3_CREATE:
855 {
856 CREATE3args *arg = (CREATE3args *) args;
857 fhp1 = (nfs_fh3 *) arg->where.dirp;
858 break;
859 }
860 case NFSPROC3_MKDIR:
861 {
862 MKDIR3args *arg = (MKDIR3args *) args;
863 fhp1 = (nfs_fh3 *) arg->where.dirp;
864 break;
865 }
866 case NFSPROC3_SYMLINK:
867 {
868 SYMLINK3args *arg = (SYMLINK3args *) args;
869 fhp1 = (nfs_fh3 *) arg->where.dirp;
870 break;
871 }
872 case NFSPROC3_MKNOD:
873 {
874 MKNOD3args *arg = (MKNOD3args *) args;
875 fhp1 = (nfs_fh3 *) arg->where.dirp;
876 break;
877 }
878 case NFSPROC3_REMOVE:
879 {
880 REMOVE3args *arg = (REMOVE3args *) args;
881 fhp1 = (nfs_fh3 *) arg->object.dirp;
882 break;
883 }
884 case NFSPROC3_RMDIR:
885 {
886 RMDIR3args *arg = (RMDIR3args *) args;
887 fhp1 = (nfs_fh3 *) arg->object.dirp;
888 break;
889 }
890 case NFSPROC3_RENAME:
891 {
892 RENAME3args *arg = (RENAME3args *) args;
893 fhp1 = (nfs_fh3 *) arg->from.dirp;
894 fhp2 = (nfs_fh3 *) arg->to.dirp;
895 break;
896 }
897 case NFSPROC3_LINK:
898 {
899 LINK3args *arg = (LINK3args *) args;
900 fhp1 = (nfs_fh3 *) & arg->file;
901 fhp2 = (nfs_fh3 *) arg->link.dirp;
902 break;
903 }
904 case NFSPROC3_READDIR:
905 {
906 READDIR3args *arg = (READDIR3args *) args;
907 fhp1 = (nfs_fh3 *) & arg->dir;
908 break;
909 }
910 case NFSPROC3_READDIRPLUS:
911 {
912 READDIRPLUS3args *arg = (READDIRPLUS3args *) args;
913 fhp1 = (nfs_fh3 *) & arg->dir;
914 break;
915 }
916 case NFSPROC3_FSSTAT:
917 {
918 FSSTAT3args *arg = (FSSTAT3args *) args;
919 fhp1 = (nfs_fh3 *) & arg->fsroot;
920 break;
921 }
922 case NFSPROC3_FSINFO:
923 {
924 FSINFO3args *arg = (FSINFO3args *) args;
925 fhp1 = (nfs_fh3 *) & arg->fsroot;
926 break;
927 }
928 case NFSPROC3_PATHCONF:
929 {
930 PATHCONF3args *arg = (PATHCONF3args *) args;
931 fhp1 = (nfs_fh3 *) & arg->object;
932 break;
933 }
934 case NFSPROC3_COMMIT:
935 {
936 COMMIT3args *arg = (COMMIT3args *) args;
937 fhp1 = (nfs_fh3 *) & arg->file;
938 break;
939 }
940 default:
941 return NULL;
942 }
943
944 if (fhp1 && is_afs_fh3(fhp1)) {
945 *fhpp = fhp1;
946 if (fhp2)
947 *fh2pp = fhp2;
948 return 1;
949 }
950 if (fhp2 && is_afs_fh3(fhp2)) {
951 *fhpp = fhp1;
952 *fh2pp = fhp2;
953 return 1;
954 }
955 return NULL;
956 }
957
958 afs_int32
959 acl3_to_afs_call(int which, caddr_t * args, nfs_fh3 ** fhpp)
960 {
961 nfs_fh3 *fhp;
962
963 switch (which) {
964 case ACLPROC3_GETACL:
965 {
966 struct GETACL3args *sargs = (struct GETACL3args *)args;
967 fhp = &sargs->fh;
968 break;
969 }
970 case ACLPROC3_SETACL:
971 {
972 struct SETACL3args *sargs = (struct SETACL3args *)args;
973 fhp = &sargs->fh;
974 break;
975 }
976 #if defined(AFS_SUN510_ENV)
977 case ACLPROC3_GETXATTRDIR:
978 {
979 struct GETXATTRDIR3args *sargs = (struct GETXATTRDIR3args *)args;
980 fhp = &sargs->fh;
981 break;
982 }
983 #endif
984 default:
985 return NULL;
986 }
987
988 if (fhp && is_afs_fh3(fhp)) {
989 *fhpp = fhp;
990 return 1;
991 }
992
993 return NULL;
994 }
995
996 int
997 afs_nfs3_dispatcher(int type, afs_int32 which, char *argp,
998 struct exportinfo **expp, struct svc_req *rp,
999 afs_ucred_t *crp)
1000 {
1001 afs_int32 call = 0;
1002 afs_int32 code = 0;
1003 afs_int32 client = 0;
1004 struct sockaddr *sa;
1005 nfs_fh3 *fh = (nfs_fh3 *) argp;
1006 nfs_fh3 *fh2 = (nfs_fh3 *) 0;
1007
1008 if (!xlatorinit_v3_done)
1009 return 2;
1010
1011 sa = (struct sockaddr *)svc_getrpccaller(rp->rq_xprt)->buf;
1012 if (sa == NULL)
1013 return;
1014
1015 if (sa->sa_family == AF_INET)
1016 client = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
1017
1018 AFS_GLOCK();
1019 code = 0;
1020 switch (type) {
1021 case 0:
1022 code = (client && nfs3_to_afs_call(which, argp, &fh, &fh2));
1023 break;
1024 case 1:
1025 code = (client && acl3_to_afs_call(which, argp, &fh));
1026 break;
1027 default:
1028 break;
1029 }
1030
1031 if (code) {
1032 struct afs_exporter *out = 0;
1033 afs_int32 dummy;
1034 static int once = 0;
1035 struct SmallFid Sfid;
1036
1037 memcpy((char *)&Sfid, fh->fh3_data, SIZEOF_SMALLFID);
1038
1039 afs_Trace2(afs_iclSetp, CM_TRACE_NFS3IN1, ICL_TYPE_INT32, client,
1040 ICL_TYPE_FID, &Sfid);
1041
1042 call = 1;
1043 if (!once && *expp) {
1044 afs_nobody = (*expp)->exi_export.ex_anon;
1045 once = 1;
1046 }
1047 code =
1048 afs_nfsclient_reqhandler((struct afs_exporter *)0, &crp, client,
1049 &dummy, &out);
1050
1051 if (!code && out)
1052 EXP_RELE(out);
1053
1054
1055 if (code == EINVAL)
1056 call = 2;
1057 }
1058
1059 AFS_GUNLOCK();
1060 return call;
1061 }
1062
1063 void
1064 afs_nfs3_smallfidder(struct nfs_fh3 *fhp, int status)
1065 {
1066 afs_int32 addr[2];
1067 struct vcache *vcp;
1068
1069 #if defined(AFS_SUN5_64BIT_ENV)
1070 /* See also afs_fid() */
1071 memcpy((char *)addr, fhp->fh3_data, 10);
1072 addr[1] = (addr[1] >> 48) & 0xffff;
1073 #else
1074 memcpy((char *)addr, fhp->fh3_data, 2 * sizeof(long));
1075 #endif
1076
1077 AFS_GLOCK();
1078 vcp = VTOAFS((struct vnode *)addr[0]);
1079
1080 /* See also afs_osi_vget */
1081 if (addr[1] == AFS_XLATOR_MAGIC) {
1082 if (status == NFS_OK) {
1083 struct SmallFid Sfid;
1084 struct cell *tcell;
1085
1086 /* Make up and copy out a SmallFid */
1087 tcell = afs_GetCell(vcp->f.fid.Cell, READ_LOCK);
1088 Sfid.Volume = vcp->f.fid.Fid.Volume;
1089 Sfid.CellAndUnique =
1090 ((tcell->cellIndex << 24) | (vcp->f.fid.Fid.Unique & 0xffffff));
1091 afs_PutCell(tcell, READ_LOCK);
1092 Sfid.Vnode = (u_short) (vcp->f.fid.Fid.Vnode & 0xffff);
1093 fhp->fh3_len = SIZEOF_SMALLFID;
1094 memcpy(fhp->fh3_data, (char *)&Sfid, fhp->fh3_len);
1095
1096 afs_Trace3(afs_iclSetp, CM_TRACE_NFS3OUT, ICL_TYPE_INT32, status,
1097 ICL_TYPE_POINTER, vcp, ICL_TYPE_FID, &Sfid);
1098 }
1099
1100 /* If we have a ref, release it */
1101 if (vcp->vrefCount >= 1)
1102 AFS_RELE(AFSTOV(vcp));
1103 }
1104 AFS_GUNLOCK();
1105 }
1106
1107 void
1108 afs_nfs3_getattr(char *args, char *xp, char *exp, char *rp, char *crp)
1109 {
1110 u_int call;
1111 afs_nfs3_resp dummy;
1112 afs_ucred_t *svcred = curthread->t_cred;
1113 curthread->t_cred = (afs_ucred_t *)crp;
1114 call =
1115 afs_nfs3_dispatcher(0, NFSPROC3_GETATTR, (char *)args, &exp, rp, crp);
1116 if (call > 1)
1117 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1118 else
1119 (*afs_rfs3_disp_tbl[NFSPROC3_GETATTR].orig_proc) (args, xp, exp, rp,
1120 crp);
1121 curthread->t_cred = svcred;
1122 return;
1123 }
1124
1125 void
1126 afs_nfs3_setattr(char *args, char *xp, char *exp, char *rp, char *crp)
1127 {
1128 u_int call;
1129 afs_nfs3_resp dummy;
1130 afs_ucred_t *svcred = curthread->t_cred;
1131 curthread->t_cred = (afs_ucred_t *)crp;
1132 call =
1133 afs_nfs3_dispatcher(0, NFSPROC3_SETATTR, (char *)args, &exp, rp, crp);
1134 if (call > 1)
1135 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1136 else
1137 (*afs_rfs3_disp_tbl[NFSPROC3_SETATTR].orig_proc) (args, xp, exp, rp,
1138 crp);
1139 curthread->t_cred = svcred;
1140 return;
1141 }
1142
1143 void
1144 afs_nfs3_lookup(char *args, char *xp, char *exp, char *rp, char *crp)
1145 {
1146 u_int call;
1147 afs_nfs3_resp dummy;
1148 afs_ucred_t *svcred = curthread->t_cred;
1149 curthread->t_cred = (afs_ucred_t *)crp;
1150 call =
1151 afs_nfs3_dispatcher(0, NFSPROC3_LOOKUP, (char *)args, &exp, rp, crp);
1152 if (call > 1)
1153 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1154 else {
1155 (*afs_rfs3_disp_tbl[NFSPROC3_LOOKUP].orig_proc) (args, xp, exp, rp,
1156 crp);
1157 if (afs_NFSRootOnly && call) {
1158 LOOKUP3res *resp = (LOOKUP3res *) xp;
1159 afs_nfs3_smallfidder(&resp->resok.object, resp->status);
1160 }
1161 }
1162 curthread->t_cred = svcred;
1163 return;
1164 }
1165
1166 void
1167 afs_nfs3_access(char *args, char *xp, char *exp, char *rp, char *crp)
1168 {
1169 u_int call;
1170 afs_nfs3_resp dummy;
1171 afs_ucred_t *svcred = curthread->t_cred;
1172 curthread->t_cred = (afs_ucred_t *)crp;
1173 call =
1174 afs_nfs3_dispatcher(0, NFSPROC3_ACCESS, (char *)args, &exp, rp, crp);
1175 if (call > 1)
1176 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1177 else
1178 (*afs_rfs3_disp_tbl[NFSPROC3_ACCESS].orig_proc) (args, xp, exp, rp,
1179 crp);
1180 curthread->t_cred = svcred;
1181 return;
1182 }
1183
1184 void
1185 afs_nfs3_readlink(char *args, char *xp, char *exp, char *rp, char *crp)
1186 {
1187 u_int call;
1188 afs_nfs3_resp dummy;
1189 afs_ucred_t *svcred = curthread->t_cred;
1190 curthread->t_cred = (afs_ucred_t *)crp;
1191 call =
1192 afs_nfs3_dispatcher(0, NFSPROC3_READLINK, (char *)args, &exp, rp,
1193 crp);
1194 if (call > 1)
1195 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1196 else
1197 (*afs_rfs3_disp_tbl[NFSPROC3_READLINK].orig_proc) (args, xp, exp, rp,
1198 crp);
1199 curthread->t_cred = svcred;
1200 return;
1201 }
1202
1203 void
1204 afs_nfs3_read(char *args, char *xp, char *exp, char *rp, char *crp)
1205 {
1206 u_int call;
1207 afs_nfs3_resp dummy;
1208 afs_ucred_t *svcred = curthread->t_cred;
1209 curthread->t_cred = (afs_ucred_t *)crp;
1210 call = afs_nfs3_dispatcher(0, NFSPROC3_READ, (char *)args, &exp, rp, crp);
1211 if (call > 1)
1212 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1213 else
1214 (*afs_rfs3_disp_tbl[NFSPROC3_READ].orig_proc) (args, xp, exp, rp,
1215 crp);
1216 curthread->t_cred = svcred;
1217 return;
1218 }
1219
1220 void
1221 afs_nfs3_write(char *args, char *xp, char *exp, char *rp, char *crp)
1222 {
1223 u_int call;
1224 afs_nfs3_resp dummy;
1225 afs_ucred_t *svcred = curthread->t_cred;
1226 curthread->t_cred = (afs_ucred_t *)crp;
1227 call =
1228 afs_nfs3_dispatcher(0, NFSPROC3_WRITE, (char *)args, &exp, rp, crp);
1229 if (call > 1)
1230 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1231 else
1232 (*afs_rfs3_disp_tbl[NFSPROC3_WRITE].orig_proc) (args, xp, exp, rp,
1233 crp);
1234 curthread->t_cred = svcred;
1235 return;
1236 }
1237
1238 void
1239 afs_nfs3_create(char *args, char *xp, char *exp, char *rp, char *crp)
1240 {
1241 u_int call;
1242 afs_nfs3_resp dummy;
1243 afs_ucred_t *svcred = curthread->t_cred;
1244 curthread->t_cred = (afs_ucred_t *)crp;
1245 call =
1246 afs_nfs3_dispatcher(0, NFSPROC3_CREATE, (char *)args, &exp, rp, crp);
1247 if (call > 1)
1248 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1249 else {
1250 (*afs_rfs3_disp_tbl[NFSPROC3_CREATE].orig_proc) (args, xp, exp, rp,
1251 crp);
1252 if (afs_NFSRootOnly && call) {
1253 CREATE3res *resp = (CREATE3res *) xp;
1254 afs_nfs3_smallfidder(&resp->resok.obj.handle, resp->status);
1255 }
1256 }
1257 curthread->t_cred = svcred;
1258 return;
1259 }
1260
1261 void
1262 afs_nfs3_mkdir(char *args, char *xp, char *exp, char *rp, char *crp)
1263 {
1264 u_int call;
1265 afs_nfs3_resp dummy;
1266 afs_ucred_t *svcred = curthread->t_cred;
1267 curthread->t_cred = (afs_ucred_t *)crp;
1268 call =
1269 afs_nfs3_dispatcher(0, NFSPROC3_MKDIR, (char *)args, &exp, rp, crp);
1270 if (call > 1)
1271 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1272 else {
1273 (*afs_rfs3_disp_tbl[NFSPROC3_MKDIR].orig_proc) (args, xp, exp, rp,
1274 crp);
1275 if (afs_NFSRootOnly && call) {
1276 MKDIR3res *resp = (MKDIR3res *) xp;
1277 afs_nfs3_smallfidder(&resp->resok.obj.handle, resp->status);
1278 }
1279 }
1280 curthread->t_cred = svcred;
1281 return;
1282 }
1283
1284 void
1285 afs_nfs3_symlink(char *args, char *xp, char *exp, char *rp, char *crp)
1286 {
1287 u_int call;
1288 afs_nfs3_resp dummy;
1289 afs_ucred_t *svcred = curthread->t_cred;
1290 curthread->t_cred = (afs_ucred_t *)crp;
1291 call =
1292 afs_nfs3_dispatcher(0, NFSPROC3_SYMLINK, (char *)args, &exp, rp, crp);
1293 if (call > 1)
1294 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1295 else {
1296 (*afs_rfs3_disp_tbl[NFSPROC3_SYMLINK].orig_proc) (args, xp, exp, rp,
1297 crp);
1298 if (afs_NFSRootOnly && call) {
1299 SYMLINK3res *resp = (SYMLINK3res *) xp;
1300 afs_nfs3_smallfidder(&resp->resok.obj.handle, resp->status);
1301 }
1302 }
1303 curthread->t_cred = svcred;
1304 return;
1305 }
1306
1307 void
1308 afs_nfs3_mknod(char *args, char *xp, char *exp, char *rp, char *crp)
1309 {
1310 u_int call;
1311 afs_nfs3_resp dummy;
1312 afs_ucred_t *svcred = curthread->t_cred;
1313 curthread->t_cred = (afs_ucred_t *)crp;
1314 call =
1315 afs_nfs3_dispatcher(0, NFSPROC3_MKNOD, (char *)args, &exp, rp, crp);
1316 if (call > 1)
1317 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1318 else {
1319 (*afs_rfs3_disp_tbl[NFSPROC3_MKNOD].orig_proc) (args, xp, exp, rp,
1320 crp);
1321 if (afs_NFSRootOnly && call) {
1322 MKNOD3res *resp = (MKNOD3res *) xp;
1323 afs_nfs3_smallfidder(&resp->resok.obj.handle, resp->status);
1324 }
1325 }
1326 curthread->t_cred = svcred;
1327 return;
1328 }
1329
1330 void
1331 afs_nfs3_remove(char *args, char *xp, char *exp, char *rp, char *crp)
1332 {
1333 u_int call;
1334 afs_nfs3_resp dummy;
1335 afs_ucred_t *svcred = curthread->t_cred;
1336 curthread->t_cred = (afs_ucred_t *)crp;
1337 call =
1338 afs_nfs3_dispatcher(0, NFSPROC3_REMOVE, (char *)args, &exp, rp, crp);
1339 if (call > 1)
1340 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1341 else
1342 (*afs_rfs3_disp_tbl[NFSPROC3_REMOVE].orig_proc) (args, xp, exp, rp,
1343 crp);
1344 curthread->t_cred = svcred;
1345 return;
1346 }
1347
1348 void
1349 afs_nfs3_rmdir(char *args, char *xp, char *exp, char *rp, char *crp)
1350 {
1351 u_int call;
1352 afs_nfs3_resp dummy;
1353 afs_ucred_t *svcred = curthread->t_cred;
1354 curthread->t_cred = (afs_ucred_t *)crp;
1355 call =
1356 afs_nfs3_dispatcher(0, NFSPROC3_RMDIR, (char *)args, &exp, rp, crp);
1357 if (call > 1)
1358 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1359 else
1360 (*afs_rfs3_disp_tbl[NFSPROC3_RMDIR].orig_proc) (args, xp, exp, rp,
1361 crp);
1362 curthread->t_cred = svcred;
1363 return;
1364 }
1365
1366 void
1367 afs_nfs3_rename(char *args, char *xp, char *exp, char *rp, char *crp)
1368 {
1369 u_int call;
1370 afs_nfs3_resp dummy;
1371 afs_ucred_t *svcred = curthread->t_cred;
1372 curthread->t_cred = (afs_ucred_t *)crp;
1373 call =
1374 afs_nfs3_dispatcher(0, NFSPROC3_RENAME, (char *)args, &exp, rp, crp);
1375 if (call > 1)
1376 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1377 else
1378 (*afs_rfs3_disp_tbl[NFSPROC3_RENAME].orig_proc) (args, xp, exp, rp,
1379 crp);
1380 curthread->t_cred = svcred;
1381 return;
1382 }
1383
1384 void
1385 afs_nfs3_link(char *args, char *xp, char *exp, char *rp, char *crp)
1386 {
1387 u_int call;
1388 afs_nfs3_resp dummy;
1389 afs_ucred_t *svcred = curthread->t_cred;
1390 curthread->t_cred = (afs_ucred_t *)crp;
1391 call = afs_nfs3_dispatcher(0, NFSPROC3_LINK, (char *)args, &exp, rp, crp);
1392 if (call > 1)
1393 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1394 else
1395 (*afs_rfs3_disp_tbl[NFSPROC3_LINK].orig_proc) (args, xp, exp, rp,
1396 crp);
1397 curthread->t_cred = svcred;
1398 return;
1399 }
1400
1401 void
1402 afs_nfs3_readdir(char *args, char *xp, char *exp, char *rp, char *crp)
1403 {
1404 u_int call;
1405 afs_nfs3_resp dummy;
1406 afs_ucred_t *svcred = curthread->t_cred;
1407 curthread->t_cred = (afs_ucred_t *)crp;
1408 call =
1409 afs_nfs3_dispatcher(0, NFSPROC3_READDIR, (char *)args, &exp, rp, crp);
1410 if (call > 1)
1411 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1412 else
1413 (*afs_rfs3_disp_tbl[NFSPROC3_READDIR].orig_proc) (args, xp, exp, rp,
1414 crp);
1415 curthread->t_cred = svcred;
1416 return;
1417 }
1418
1419 void
1420 afs_nfs3_readdirplus(char *args, char *xp, char *exp, char *rp, char *crp)
1421 {
1422 u_int call;
1423 afs_nfs3_resp dummy;
1424 afs_ucred_t *svcred = curthread->t_cred;
1425 curthread->t_cred = (afs_ucred_t *)crp;
1426 call =
1427 afs_nfs3_dispatcher(0, NFSPROC3_READDIRPLUS, (char *)args, &exp, rp,
1428 crp);
1429 if (call > 1)
1430 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1431 else if (call == 1)
1432 afs_nfs3_notsupp((struct afs_nfs3_resp *)xp);
1433 else
1434 (*afs_rfs3_disp_tbl[NFSPROC3_READDIRPLUS].orig_proc) (args, xp, exp,
1435 rp, crp);
1436 curthread->t_cred = svcred;
1437 return;
1438 }
1439
1440 void
1441 afs_nfs3_fsstat(char *args, char *xp, char *exp, char *rp, char *crp)
1442 {
1443 u_int call;
1444 afs_nfs3_resp dummy;
1445 afs_ucred_t *svcred = curthread->t_cred;
1446 curthread->t_cred = (afs_ucred_t *)crp;
1447 call =
1448 afs_nfs3_dispatcher(0, NFSPROC3_FSSTAT, (char *)args, &exp, rp, crp);
1449 if (call > 1)
1450 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1451 else
1452 (*afs_rfs3_disp_tbl[NFSPROC3_FSSTAT].orig_proc) (args, xp, exp, rp,
1453 crp);
1454 curthread->t_cred = svcred;
1455 return;
1456 }
1457
1458 void
1459 afs_nfs3_fsinfo(char *args, char *xp, char *exp, char *rp, char *crp)
1460 {
1461 u_int call;
1462 afs_nfs3_resp dummy;
1463 afs_ucred_t *svcred = curthread->t_cred;
1464 curthread->t_cred = (afs_ucred_t *)crp;
1465 call =
1466 afs_nfs3_dispatcher(0, NFSPROC3_FSINFO, (char *)args, &exp, rp, crp);
1467 if (call > 1)
1468 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1469 else
1470 (*afs_rfs3_disp_tbl[NFSPROC3_FSINFO].orig_proc) (args, xp, exp, rp,
1471 crp);
1472 curthread->t_cred = svcred;
1473 return;
1474 }
1475
1476 void
1477 afs_nfs3_pathconf(char *args, char *xp, char *exp, char *rp, char *crp)
1478 {
1479 u_int call;
1480 afs_nfs3_resp dummy;
1481 afs_ucred_t *svcred = curthread->t_cred;
1482 curthread->t_cred = (afs_ucred_t *)crp;
1483 call =
1484 afs_nfs3_dispatcher(0, NFSPROC3_PATHCONF, (char *)args, &exp, rp,
1485 crp);
1486 if (call > 1)
1487 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1488 else
1489 (*afs_rfs3_disp_tbl[NFSPROC3_PATHCONF].orig_proc) (args, xp, exp, rp,
1490 crp);
1491 curthread->t_cred = svcred;
1492 return;
1493 }
1494
1495 void
1496 afs_nfs3_commit(char *args, char *xp, char *exp, char *rp, char *crp)
1497 {
1498 u_int call;
1499 afs_nfs3_resp dummy;
1500 afs_ucred_t *svcred = curthread->t_cred;
1501 curthread->t_cred = (afs_ucred_t *)crp;
1502 call =
1503 afs_nfs3_dispatcher(0, NFSPROC3_COMMIT, (char *)args, &exp, rp, crp);
1504 if (call > 1)
1505 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1506 else
1507 (*afs_rfs3_disp_tbl[NFSPROC3_COMMIT].orig_proc) (args, xp, exp, rp,
1508 crp);
1509 curthread->t_cred = svcred;
1510 return;
1511 }
1512
1513 struct afs_nfs_disp_tbl afs_rfs3_disp_tbl[22] = {
1514 {afs_nfs2_null},
1515 {afs_nfs3_getattr},
1516 {afs_nfs3_setattr},
1517 {afs_nfs3_lookup},
1518 {afs_nfs3_access},
1519 {afs_nfs3_readlink},
1520 {afs_nfs3_read},
1521 {afs_nfs3_write},
1522 {afs_nfs3_create},
1523 {afs_nfs3_mkdir},
1524 {afs_nfs3_symlink},
1525 {afs_nfs3_mknod},
1526 {afs_nfs3_remove},
1527 {afs_nfs3_rmdir},
1528 {afs_nfs3_rename},
1529 {afs_nfs3_link},
1530 {afs_nfs3_readdir},
1531 {afs_nfs3_readdirplus},
1532 {afs_nfs3_fsstat},
1533 {afs_nfs3_fsinfo},
1534 {afs_nfs3_pathconf},
1535 {afs_nfs3_commit}
1536 };
1537
1538 void
1539 afs_acl3_getacl(char *args, char *xp, char *exp, char *rp, char *crp)
1540 {
1541 u_int call;
1542 afs_ucred_t *svcred = curthread->t_cred;
1543 curthread->t_cred = (afs_ucred_t *)crp;
1544 call =
1545 afs_nfs3_dispatcher(1, ACLPROC3_GETACL, (char *)args, &exp, rp, crp);
1546 if (call > 1)
1547 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1548 else
1549 (*afs_acl3_disp_tbl[ACLPROC3_GETACL].orig_proc) (args, xp, exp, rp,
1550 crp);
1551 curthread->t_cred = svcred;
1552 return;
1553 }
1554
1555 void
1556 afs_acl3_setacl(char *args, char *xp, char *exp, char *rp, char *crp)
1557 {
1558 u_int call;
1559 afs_ucred_t *svcred = curthread->t_cred;
1560 curthread->t_cred = (afs_ucred_t *)crp;
1561 call =
1562 afs_nfs3_dispatcher(1, ACLPROC3_SETACL, (char *)args, &exp, rp, crp);
1563 if (call > 1)
1564 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1565 else
1566 (*afs_acl3_disp_tbl[ACLPROC3_SETACL].orig_proc) (args, xp, exp, rp,
1567 crp);
1568 curthread->t_cred = svcred;
1569 return;
1570 }
1571
1572 #if defined(AFS_SUN510_ENV)
1573 void
1574 afs_acl3_getxattrdir(char *args, char *xp, char *exp, char *rp, char *crp)
1575 {
1576 u_int call;
1577 afs_ucred_t *svcred = curthread->t_cred;
1578 curthread->t_cred = (afs_ucred_t *)crp;
1579 call =
1580 afs_nfs3_dispatcher(1, ACLPROC3_GETXATTRDIR, (char *)args, &exp, rp, crp);
1581 if (call > 1)
1582 afs_nfs3_noaccess((struct afs_nfs3_resp *)xp);
1583 else
1584 (*afs_acl3_disp_tbl[ACLPROC3_GETXATTRDIR].orig_proc) (args, xp, exp, rp,
1585 crp);
1586 curthread->t_cred = svcred;
1587 return;
1588 }
1589 #endif
1590
1591 struct afs_nfs_disp_tbl afs_acl3_disp_tbl[ACL3_NPROC] = {
1592 {afs_nfs2_null},
1593 {afs_acl3_getacl},
1594 {afs_acl3_setacl},
1595 #if defined(AFS_SUN510_ENV)
1596 {afs_acl3_getxattrdir},
1597 #endif
1598 };
1599
1600 /* Munge the dispatch tables to link us in first */
1601 void
1602 afs_xlatorinit_v3(struct rfs_disp_tbl *_rfs_tbl,
1603 struct rfs_disp_tbl *_acl_tbl)
1604 {
1605 int i;
1606
1607 if (xlatorinit_v3_done++)
1608 return;
1609
1610 for (i = 0; i < 22; i++) {
1611 afs_rfs3_disp_tbl[i].orig_proc = _rfs_tbl[i].dis_proc;
1612 _rfs_tbl[i].dis_proc = afs_rfs3_disp_tbl[i].afs_proc;
1613 }
1614
1615 for (i = 0; i < 3; i++) {
1616 afs_acl3_disp_tbl[i].orig_proc = _acl_tbl[i].dis_proc;
1617 _acl_tbl[i].dis_proc = afs_acl3_disp_tbl[i].afs_proc;
1618 }
1619 }
1620 #endif /* !defined(AFS_NONFSTRANS) */