--- a/usr/src/uts/common/fs/nfs/nfs_server.c Mon Oct 27 23:12:59 2008 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c Tue Oct 28 03:34:04 2008 -0700
@@ -29,8 +29,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
@@ -79,6 +77,7 @@
#include <nfs/nfs_clnt.h>
#include <nfs/nfs_acl.h>
#include <nfs/nfs_log.h>
+#include <nfs/nfs_cmd.h>
#include <nfs/lm.h>
#include <nfs/nfs_dispatch.h>
#include <nfs/nfs4_drc.h>
@@ -455,8 +454,8 @@
/* Double check the vers min/max ranges */
if ((nfs_versmin > nfs_versmax) ||
- (nfs_versmin < NFS_VERSMIN) ||
- (nfs_versmax > NFS_VERSMAX)) {
+ (nfs_versmin < NFS_VERSMIN) ||
+ (nfs_versmax > NFS_VERSMAX)) {
nfs_versmin = NFS_VERSMIN_DEFAULT;
nfs_versmax = NFS_VERSMAX_DEFAULT;
}
@@ -474,7 +473,7 @@
/* Create a transport handle. */
error = svc_tli_kcreate(fp, readsize, buf, &addrmask, &xprt,
- sctp, NULL, NFS_SVCPOOL_ID, TRUE);
+ sctp, NULL, NFS_SVCPOOL_ID, TRUE);
if (error)
kmem_free(addrmask.buf, addrmask.maxlen);
@@ -500,7 +499,7 @@
if (nfs_server_upordown != NFS_SERVER_RUNNING) {
/* Do we need to stop and wait on the previous server? */
while (nfs_server_upordown == NFS_SERVER_STOPPING ||
- nfs_server_upordown == NFS_SERVER_OFFLINE)
+ nfs_server_upordown == NFS_SERVER_OFFLINE)
cv_wait(&nfs_server_upordown_cv,
&nfs_server_upordown_lock);
@@ -527,7 +526,7 @@
/* cold start */
rfs4_state_init();
nfs4_drc = rfs4_init_drc(nfs4_drc_max,
- nfs4_drc_hash);
+ nfs4_drc_hash);
}
/*
@@ -556,8 +555,8 @@
/* Double check the vers min/max ranges */
if ((rsa->nfs_versmin > rsa->nfs_versmax) ||
- (rsa->nfs_versmin < NFS_VERSMIN) ||
- (rsa->nfs_versmax > NFS_VERSMAX)) {
+ (rsa->nfs_versmin < NFS_VERSMIN) ||
+ (rsa->nfs_versmax > NFS_VERSMAX)) {
rsa->nfs_versmin = NFS_VERSMIN_DEFAULT;
rsa->nfs_versmax = NFS_VERSMAX_DEFAULT;
}
@@ -1618,6 +1617,14 @@
}
goto done;
}
+
+ /* check to see if we might need charmap */
+ if (exi->exi_export.ex_flags & EX_CHARMAP) {
+ struct sockaddr *ca;
+ ca = (struct sockaddr *)
+ svc_getrpccaller(req->rq_xprt)->buf;
+ (void) nfscmd_charmap(exi, ca);
+ }
}
} else
cr = NULL;
@@ -1631,7 +1638,7 @@
if (!(dis_flags & RPC_IDEMPOTENT)) {
dupstat = SVC_DUP_EXT(xprt, req, res, disp->dis_ressz, &dr,
- &dupcached);
+ &dupcached);
switch (dupstat) {
case DUP_ERROR:
@@ -1655,7 +1662,7 @@
if (curthread->t_flag & T_WOULDBLOCK) {
curthread->t_flag &= ~T_WOULDBLOCK;
SVC_DUPDONE_EXT(xprt, dr, res, NULL,
- disp->dis_ressz, DUP_DROP);
+ disp->dis_ressz, DUP_DROP);
if (res != (char *)&res_buf)
SVC_FREERES(xprt);
error++;
@@ -1663,12 +1670,12 @@
}
if (dis_flags & RPC_AVOIDWORK) {
SVC_DUPDONE_EXT(xprt, dr, res, NULL,
- disp->dis_ressz, DUP_DROP);
+ disp->dis_ressz, DUP_DROP);
} else {
SVC_DUPDONE_EXT(xprt, dr, res,
- disp->dis_resfree == nullfree ? NULL :
- disp->dis_resfree,
- disp->dis_ressz, DUP_DONE);
+ disp->dis_resfree == nullfree ? NULL :
+ disp->dis_resfree,
+ disp->dis_ressz, DUP_DONE);
dupcached = TRUE;
}
break;
@@ -1754,7 +1761,7 @@
*/
if (logging_enabled) {
nfslog_write_record(nfslog_exi, req, args, (char *)&res_buf,
- cr, &nb, nfslog_rec_id, NFSLOG_ONE_BUFFER);
+ cr, &nb, nfslog_rec_id, NFSLOG_ONE_BUFFER);
exi_rele(nfslog_exi);
kmem_free((&nb)->buf, (&nb)->len);
}
@@ -1795,7 +1802,7 @@
rfs_dispatch(struct svc_req *req, SVCXPRT *xprt)
{
common_dispatch(req, xprt, NFS_VERSMIN, NFS_VERSMAX,
- "NFS", rfs_disptable);
+ "NFS", rfs_disptable);
}
static char *aclcallnames_v2[] = {
@@ -1921,7 +1928,7 @@
acl_dispatch(struct svc_req *req, SVCXPRT *xprt)
{
common_dispatch(req, xprt, NFS_ACL_VERSMIN, NFS_ACL_VERSMAX,
- "ACL", acl_disptable);
+ "ACL", acl_disptable);
}
int
@@ -2056,15 +2063,37 @@
switch (rpcflavor) {
case AUTH_NONE:
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
break;
case AUTH_UNIX:
if (!stat || crgetuid(cr) == 0 && !(access & NFSAUTH_ROOT)) {
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
+ } else if (!stat || crgetuid(cr) == 0 &&
+ access & NFSAUTH_ROOT) {
+ /*
+ * It is root, so apply rootid to get real UID
+ * Find the secinfo structure. We should be able
+ * to find it by the time we reach here.
+ * nfsauth_access() has done the checking.
+ */
+ secp = NULL;
+ for (i = 0; i < exi->exi_export.ex_seccnt; i++) {
+ struct secinfo *sptr;
+ sptr = &exi->exi_export.ex_secinfo[i];
+ if (sptr->s_secinfo.sc_nfsnum == nfsflavor) {
+ secp = sptr;
+ break;
+ }
+ }
+ if (secp != NULL) {
+ (void) crsetugid(cr, secp->s_rootid,
+ secp->s_rootid);
+ (void) crsetgroups(cr, 0, NULL);
+ }
}
break;
@@ -2106,11 +2135,12 @@
* to anon.
*/
if (principal && sec_svc_inrootlist(rpcflavor, principal,
- secp->s_rootcnt, secp->s_rootnames)) {
- if (crgetuid(cr) == 0)
+ secp->s_rootcnt, secp->s_rootnames)) {
+ if (crgetuid(cr) == 0 && secp->s_rootid == 0)
return (1);
- (void) crsetugid(cr, 0, 0);
+
+ (void) crsetugid(cr, secp->s_rootid, secp->s_rootid);
/*
* NOTE: If and when kernel-land privilege tracing is
@@ -2135,7 +2165,7 @@
return (1);
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
break;
default:
@@ -2227,15 +2257,36 @@
switch (rpcflavor) {
case AUTH_NONE:
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
break;
case AUTH_UNIX:
if (crgetuid(cr) == 0 && !(access & NFSAUTH_ROOT)) {
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
+ } else if (crgetuid(cr) == 0 && access & NFSAUTH_ROOT) {
+ /*
+ * It is root, so apply rootid to get real UID
+ * Find the secinfo structure. We should be able
+ * to find it by the time we reach here.
+ * nfsauth_access() has done the checking.
+ */
+ secp = NULL;
+ for (i = 0; i < exi->exi_export.ex_seccnt; i++) {
+ struct secinfo *sptr;
+ sptr = &exi->exi_export.ex_secinfo[i];
+ if (sptr->s_secinfo.sc_nfsnum == nfsflavor) {
+ secp = &exi->exi_export.ex_secinfo[i];
+ break;
+ }
+ }
+ if (secp != NULL) {
+ (void) crsetugid(cr, secp->s_rootid,
+ secp->s_rootid);
+ (void) crsetgroups(cr, 0, NULL);
+ }
}
break;
@@ -2273,14 +2324,14 @@
/*
* Map root principals listed in the share's root= list to root,
* and map any others principals that were mapped to root by RPC
- * to anon.
+ * to anon. If not going to anon, set to rootid (root_mapping).
*/
if (principal && sec_svc_inrootlist(rpcflavor, principal,
- secp->s_rootcnt, secp->s_rootnames)) {
- if (crgetuid(cr) == 0)
+ secp->s_rootcnt, secp->s_rootnames)) {
+ if (crgetuid(cr) == 0 && secp->s_rootid == 0)
return (1);
- (void) crsetugid(cr, 0, 0);
+ (void) crsetugid(cr, secp->s_rootid, secp->s_rootid);
/*
* NOTE: If and when kernel-land privilege tracing is
@@ -2305,7 +2356,7 @@
return (1);
anon_res = crsetugid(cr, exi->exi_export.ex_anon,
- exi->exi_export.ex_anon);
+ exi->exi_export.ex_anon);
(void) crsetgroups(cr, 0, NULL);
break;
} /* switch on rpcflavor */
@@ -2318,11 +2369,11 @@
if (anon_res != 0) {
cmn_err(CE_NOTE,
- "nfs_server: client %s%ssent wrong "
- "authentication for %s",
- client_name(req), client_addr(req, buf),
- exi->exi_export.ex_path ?
- exi->exi_export.ex_path : "?");
+ "nfs_server: client %s%ssent wrong "
+ "authentication for %s",
+ client_name(req), client_addr(req, buf),
+ exi->exi_export.ex_path ?
+ exi->exi_export.ex_path : "?");
return (0);
}
@@ -2373,14 +2424,14 @@
ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf;
if (ca->sa_family == AF_INET) {
- b = (uchar_t *)&((struct sockaddr_in *)ca)->sin_addr;
- (void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace,
- b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
+ b = (uchar_t *)&((struct sockaddr_in *)ca)->sin_addr;
+ (void) sprintf(buf, "%s(%d.%d.%d.%d) ", frontspace,
+ b[0] & 0xFF, b[1] & 0xFF, b[2] & 0xFF, b[3] & 0xFF);
} else if (ca->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)ca;
(void) kinet_ntop6((uchar_t *)&sin6->sin6_addr,
- buf, INET6_ADDRSTRLEN);
+ buf, INET6_ADDRSTRLEN);
} else {
@@ -2591,8 +2642,9 @@
VN_HOLD(realvp);
VN_RELE(*vpp);
*vpp = realvp;
- } else
- break;
+ } else {
+ break;
+ }
/* LINTED */
} while (TRUE);
@@ -2610,8 +2662,8 @@
if (vn_mountedvfs(mc_dvp) != NULL) {
error = traverse(&mc_dvp);
if (error) {
- VN_RELE(*vpp);
- goto publicfh_done;
+ VN_RELE(*vpp);
+ goto publicfh_done;
}
}