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