diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f8a29db0f1b..eb494f6a4c6b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -920,7 +920,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) | |||
920 | data->mount_server.port = NFS_UNSPEC_PORT; | 920 | data->mount_server.port = NFS_UNSPEC_PORT; |
921 | data->nfs_server.port = NFS_UNSPEC_PORT; | 921 | data->nfs_server.port = NFS_UNSPEC_PORT; |
922 | data->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 922 | data->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
923 | data->auth_flavors[0] = RPC_AUTH_UNIX; | 923 | data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR; |
924 | data->auth_flavor_len = 1; | 924 | data->auth_flavor_len = 1; |
925 | data->minorversion = 0; | 925 | data->minorversion = 0; |
926 | data->need_mount = true; | 926 | data->need_mount = true; |
@@ -1608,49 +1608,57 @@ out_security_failure: | |||
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | /* | 1610 | /* |
1611 | * Match the requested auth flavors with the list returned by | 1611 | * Select a security flavor for this mount. The selected flavor |
1612 | * the server. Returns zero and sets the mount's authentication | 1612 | * is planted in args->auth_flavors[0]. |
1613 | * flavor on success; returns -EACCES if server does not support | ||
1614 | * the requested flavor. | ||
1615 | */ | 1613 | */ |
1616 | static int nfs_walk_authlist(struct nfs_parsed_mount_data *args, | 1614 | static void nfs_select_flavor(struct nfs_parsed_mount_data *args, |
1617 | struct nfs_mount_request *request) | 1615 | struct nfs_mount_request *request) |
1618 | { | 1616 | { |
1619 | unsigned int i, j, server_authlist_len = *(request->auth_flav_len); | 1617 | unsigned int i, count = *(request->auth_flav_len); |
1618 | rpc_authflavor_t flavor; | ||
1619 | |||
1620 | if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) | ||
1621 | goto out; | ||
1622 | |||
1623 | /* | ||
1624 | * The NFSv2 MNT operation does not return a flavor list. | ||
1625 | */ | ||
1626 | if (args->mount_server.version != NFS_MNT3_VERSION) | ||
1627 | goto out_default; | ||
1620 | 1628 | ||
1621 | /* | 1629 | /* |
1622 | * Certain releases of Linux's mountd return an empty | 1630 | * Certain releases of Linux's mountd return an empty |
1623 | * flavor list. To prevent behavioral regression with | 1631 | * flavor list in some cases. |
1624 | * these servers (ie. rejecting mounts that used to | ||
1625 | * succeed), revert to pre-2.6.32 behavior (no checking) | ||
1626 | * if the returned flavor list is empty. | ||
1627 | */ | 1632 | */ |
1628 | if (server_authlist_len == 0) | 1633 | if (count == 0) |
1629 | return 0; | 1634 | goto out_default; |
1630 | 1635 | ||
1631 | /* | 1636 | /* |
1632 | * We avoid sophisticated negotiating here, as there are | ||
1633 | * plenty of cases where we can get it wrong, providing | ||
1634 | * either too little or too much security. | ||
1635 | * | ||
1636 | * RFC 2623, section 2.7 suggests we SHOULD prefer the | 1637 | * RFC 2623, section 2.7 suggests we SHOULD prefer the |
1637 | * flavor listed first. However, some servers list | 1638 | * flavor listed first. However, some servers list |
1638 | * AUTH_NULL first. Our caller plants AUTH_SYS, the | 1639 | * AUTH_NULL first. Avoid ever choosing AUTH_NULL. |
1639 | * preferred default, in args->auth_flavors[0] if user | ||
1640 | * didn't specify sec= mount option. | ||
1641 | */ | 1640 | */ |
1642 | for (i = 0; i < args->auth_flavor_len; i++) | 1641 | for (i = 0; i < count; i++) { |
1643 | for (j = 0; j < server_authlist_len; j++) | 1642 | struct rpcsec_gss_info info; |
1644 | if (args->auth_flavors[i] == request->auth_flavs[j]) { | 1643 | |
1645 | dfprintk(MOUNT, "NFS: using auth flavor %d\n", | 1644 | flavor = request->auth_flavs[i]; |
1646 | request->auth_flavs[j]); | 1645 | switch (flavor) { |
1647 | args->auth_flavors[0] = request->auth_flavs[j]; | 1646 | case RPC_AUTH_UNIX: |
1648 | return 0; | 1647 | goto out_set; |
1649 | } | 1648 | case RPC_AUTH_NULL: |
1649 | continue; | ||
1650 | default: | ||
1651 | if (rpcauth_get_gssinfo(flavor, &info) == 0) | ||
1652 | goto out_set; | ||
1653 | } | ||
1654 | } | ||
1650 | 1655 | ||
1651 | dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n"); | 1656 | out_default: |
1652 | nfs_umount(request); | 1657 | flavor = RPC_AUTH_UNIX; |
1653 | return -EACCES; | 1658 | out_set: |
1659 | args->auth_flavors[0] = flavor; | ||
1660 | out: | ||
1661 | dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]); | ||
1654 | } | 1662 | } |
1655 | 1663 | ||
1656 | /* | 1664 | /* |
@@ -1713,12 +1721,8 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args, | |||
1713 | return status; | 1721 | return status; |
1714 | } | 1722 | } |
1715 | 1723 | ||
1716 | /* | 1724 | nfs_select_flavor(args, &request); |
1717 | * MNTv1 (NFSv2) does not support auth flavor negotiation. | 1725 | return 0; |
1718 | */ | ||
1719 | if (args->mount_server.version != NFS_MNT3_VERSION) | ||
1720 | return 0; | ||
1721 | return nfs_walk_authlist(args, &request); | ||
1722 | } | 1726 | } |
1723 | 1727 | ||
1724 | struct dentry *nfs_try_mount(int flags, const char *dev_name, | 1728 | struct dentry *nfs_try_mount(int flags, const char *dev_name, |