/* * nfsauth4_access is used for NFS V4 auth checking. Besides doing * the common nfsauth_access(), it will check if the client can * have a limited access to this vnode even if the security flavor * used does not meet the policy. */ int nfsauth4_access(struct exportinfo *exi, vnode_t *vp, struct svc_req *req) { int access; access = nfsauth_access(exi, req); /* * There are cases that the server needs to allow the client * to have a limited view. * * e.g. * /export is shared as "sec=sys,rw=dfs-test-4,sec=krb5,rw" * /export/home is shared as "sec=sys,rw" * * When the client mounts /export with sec=sys, the client * would get a limited view with RO access on /export to see * "home" only because the client is allowed to access * /export/home with auth_sys. */ if (access & NFSAUTH_DENIED || access & NFSAUTH_WRONGSEC) { /* * Allow ro permission with LIMITED view if there is a * sub-dir exported under vp. */ if (has_visible(exi, vp)) return (NFSAUTH_LIMITED); } return (access); }
void nfsauth_func(void *cookie, char *dataptr, size_t arg_size, door_desc_t *dp, uint_t n_desc) { nfsauth_arg_t *ap; nfsauth_res_t res = {0}; nfsauth_res_t *rp = &res; XDR xdrs_a; XDR xdrs_r; caddr_t abuf = dataptr; size_t absz = arg_size; size_t rbsz = (size_t)(BYTES_PER_XDR_UNIT * 2); char result[BYTES_PER_XDR_UNIT * 2]; caddr_t rbuf = (caddr_t)&result; varg_t varg = {0}; /* * Decode the inbound door data, so we can look at the cmd. */ xdrmem_create(&xdrs_a, abuf, absz, XDR_DECODE); if (!xdr_varg(&xdrs_a, &varg)) { /* * If the arguments can't be decoded, bail. */ if (varg.vers == V_ERROR) syslog(LOG_ERR, gettext("Arg version mismatch")); res.stat = NFSAUTH_DR_DECERR; goto encres; } /* * Now set the args pointer to the proper version of the args */ switch (varg.vers) { case V_PROTO: ap = &varg.arg_u.arg; break; /* Additional arguments versions go here */ default: syslog(LOG_ERR, gettext("Invalid args version")); goto encres; } /* * Call the specified cmd */ switch (ap->cmd) { case NFSAUTH_ACCESS: nfsauth_access(&ap->areq, &rp->ares); rp->stat = NFSAUTH_DR_OKAY; break; default: rp->stat = NFSAUTH_DR_BADCMD; break; } encres: /* * Free space used to decode the args */ xdrs_a.x_op = XDR_FREE; (void) xdr_varg(&xdrs_a, &varg); xdr_destroy(&xdrs_a); /* * Encode the results before passing thru door. * * The result (nfsauth_res_t) is always two int's, so we don't * have to dynamically size (or allocate) the results buffer. */ xdrmem_create(&xdrs_r, rbuf, rbsz, XDR_ENCODE); if (!xdr_nfsauth_res(&xdrs_r, rp)) { /* * return only the status code */ rp->stat = NFSAUTH_DR_EFAIL; rbsz = sizeof (uint_t); *rbuf = (uint_t)rp->stat; } xdr_destroy(&xdrs_r); (void) door_return((char *)rbuf, rbsz, NULL, 0); (void) door_return(NULL, 0, NULL, 0); /* NOTREACHED */ }