aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2013-03-22 12:53:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-04 17:01:01 -0400
commit4580a92d44e2b21c2254fa5fef0f1bfb43c82318 (patch)
tree77a5cbcc07af0fd7877b53aa91a8fa307927e1e9
parent1c74a244fcb61e6e1983d5725b8ccd5d3f51889c (diff)
NFS: Use server-recommended security flavor by default (NFSv3)
Since commit ec88f28d in 2009, checking if the user-specified flavor is in the server's flavor list has been the source of a few noticeable regressions (now fixed), but there is one that is still vexing. An NFS server can list AUTH_NULL in its flavor list, which suggests a client should try to mount the server with the flavor of the client's choice, but the server will squash all accesses. In some cases, our client fails to mount a server because of this check, when the mount could have proceeded successfully. Skip this check if the user has specified "sec=" on the mount command line. But do consult the server-provided flavor list to choose a security flavor if no sec= option is specified on the mount command. If a server lists Kerberos pseudoflavors before "sys" in its export options, our client now chooses Kerberos over AUTH_UNIX for mount points, when no security flavor is specified by the mount command. This could be surprising to some administrators or users, who would then need to have Kerberos credentials to access the export. Or, a client administrator may not have enabled rpc.gssd. In this case, auth_rpcgss.ko might still be loadable, which is enough for the new logic to choose Kerberos over AUTH_UNIX. But the mount would fail since no GSS context can be created without rpc.gssd running. To retain the use of AUTH_UNIX by default: o The server administrator can ensure that "sys" is listed before Kerberos flavors in its export security options (see exports(5)), o The client administrator can explicitly specify "sec=sys" on its mount command line (see nfs(5)), o The client administrator can use "Sec=sys" in an appropriate section of /etc/nfsmount.conf (see nfsmount.conf(5)), or o The client administrator can blacklist auth_rpcgss.ko. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4super.c2
-rw-r--r--fs/nfs/super.c80
2 files changed, 44 insertions, 38 deletions
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 569b166cc050..a5e1a3026d48 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -252,6 +252,8 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
252 252
253 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 253 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
254 254
255 if (data->auth_flavors[0] == RPC_AUTH_MAXFLAVOR)
256 data->auth_flavors[0] = RPC_AUTH_UNIX;
255 export_path = data->nfs_server.export_path; 257 export_path = data->nfs_server.export_path;
256 data->nfs_server.export_path = "/"; 258 data->nfs_server.export_path = "/";
257 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 259 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 17b32b722457..3bb8318f6d0c 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -917,7 +917,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
917 data->mount_server.port = NFS_UNSPEC_PORT; 917 data->mount_server.port = NFS_UNSPEC_PORT;
918 data->nfs_server.port = NFS_UNSPEC_PORT; 918 data->nfs_server.port = NFS_UNSPEC_PORT;
919 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 919 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
920 data->auth_flavors[0] = RPC_AUTH_UNIX; 920 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR;
921 data->auth_flavor_len = 1; 921 data->auth_flavor_len = 1;
922 data->minorversion = 0; 922 data->minorversion = 0;
923 data->need_mount = true; 923 data->need_mount = true;
@@ -1605,49 +1605,57 @@ out_security_failure:
1605} 1605}
1606 1606
1607/* 1607/*
1608 * Match the requested auth flavors with the list returned by 1608 * Select a security flavor for this mount. The selected flavor
1609 * the server. Returns zero and sets the mount's authentication 1609 * is planted in args->auth_flavors[0].
1610 * flavor on success; returns -EACCES if server does not support
1611 * the requested flavor.
1612 */ 1610 */
1613static int nfs_walk_authlist(struct nfs_parsed_mount_data *args, 1611static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
1614 struct nfs_mount_request *request) 1612 struct nfs_mount_request *request)
1615{ 1613{
1616 unsigned int i, j, server_authlist_len = *(request->auth_flav_len); 1614 unsigned int i, count = *(request->auth_flav_len);
1615 rpc_authflavor_t flavor;
1616
1617 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR)
1618 goto out;
1619
1620 /*
1621 * The NFSv2 MNT operation does not return a flavor list.
1622 */
1623 if (args->mount_server.version != NFS_MNT3_VERSION)
1624 goto out_default;
1617 1625
1618 /* 1626 /*
1619 * Certain releases of Linux's mountd return an empty 1627 * Certain releases of Linux's mountd return an empty
1620 * flavor list. To prevent behavioral regression with 1628 * flavor list in some cases.
1621 * these servers (ie. rejecting mounts that used to
1622 * succeed), revert to pre-2.6.32 behavior (no checking)
1623 * if the returned flavor list is empty.
1624 */ 1629 */
1625 if (server_authlist_len == 0) 1630 if (count == 0)
1626 return 0; 1631 goto out_default;
1627 1632
1628 /* 1633 /*
1629 * We avoid sophisticated negotiating here, as there are
1630 * plenty of cases where we can get it wrong, providing
1631 * either too little or too much security.
1632 *
1633 * RFC 2623, section 2.7 suggests we SHOULD prefer the 1634 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1634 * flavor listed first. However, some servers list 1635 * flavor listed first. However, some servers list
1635 * AUTH_NULL first. Our caller plants AUTH_SYS, the 1636 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1636 * preferred default, in args->auth_flavors[0] if user
1637 * didn't specify sec= mount option.
1638 */ 1637 */
1639 for (i = 0; i < args->auth_flavor_len; i++) 1638 for (i = 0; i < count; i++) {
1640 for (j = 0; j < server_authlist_len; j++) 1639 struct rpcsec_gss_info info;
1641 if (args->auth_flavors[i] == request->auth_flavs[j]) { 1640
1642 dfprintk(MOUNT, "NFS: using auth flavor %d\n", 1641 flavor = request->auth_flavs[i];
1643 request->auth_flavs[j]); 1642 switch (flavor) {
1644 args->auth_flavors[0] = request->auth_flavs[j]; 1643 case RPC_AUTH_UNIX:
1645 return 0; 1644 goto out_set;
1646 } 1645 case RPC_AUTH_NULL:
1646 continue;
1647 default:
1648 if (rpcauth_get_gssinfo(flavor, &info) == 0)
1649 goto out_set;
1650 }
1651 }
1647 1652
1648 dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n"); 1653out_default:
1649 nfs_umount(request); 1654 flavor = RPC_AUTH_UNIX;
1650 return -EACCES; 1655out_set:
1656 args->auth_flavors[0] = flavor;
1657out:
1658 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
1651} 1659}
1652 1660
1653/* 1661/*
@@ -1710,12 +1718,8 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1710 return status; 1718 return status;
1711 } 1719 }
1712 1720
1713 /* 1721 nfs_select_flavor(args, &request);
1714 * MNTv1 (NFSv2) does not support auth flavor negotiation. 1722 return 0;
1715 */
1716 if (args->mount_server.version != NFS_MNT3_VERSION)
1717 return 0;
1718 return nfs_walk_authlist(args, &request);
1719} 1723}
1720 1724
1721struct dentry *nfs_try_mount(int flags, const char *dev_name, 1725struct dentry *nfs_try_mount(int flags, const char *dev_name,