aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c126
1 files changed, 69 insertions, 57 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ceb60c78bfc0..8d51101771fc 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1608,16 +1608,13 @@ out_security_failure:
1608} 1608}
1609 1609
1610/* 1610/*
1611 * Select a security flavor for this mount. The selected flavor 1611 * Ensure that the specified authtype in args->auth_flavors[0] is supported by
1612 * is planted in args->auth_flavors[0]. 1612 * the server. Returns 0 if it's ok, and -EACCES if not.
1613 *
1614 * Returns 0 on success, -EACCES on failure.
1615 */ 1613 */
1616static int nfs_select_flavor(struct nfs_parsed_mount_data *args, 1614static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args,
1617 struct nfs_mount_request *request) 1615 rpc_authflavor_t *server_authlist, unsigned int count)
1618{ 1616{
1619 unsigned int i, count = *(request->auth_flav_len); 1617 unsigned int i;
1620 rpc_authflavor_t flavor;
1621 1618
1622 /* 1619 /*
1623 * If the sec= mount option is used, the specified flavor or AUTH_NULL 1620 * If the sec= mount option is used, the specified flavor or AUTH_NULL
@@ -1627,60 +1624,19 @@ static int nfs_select_flavor(struct nfs_parsed_mount_data *args,
1627 * means that the server will ignore the rpc creds, so any flavor 1624 * means that the server will ignore the rpc creds, so any flavor
1628 * can be used. 1625 * can be used.
1629 */ 1626 */
1630 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
1631 for (i = 0; i < count; i++) {
1632 if (args->auth_flavors[0] == request->auth_flavs[i] ||
1633 request->auth_flavs[i] == RPC_AUTH_NULL)
1634 goto out;
1635 }
1636 dfprintk(MOUNT, "NFS: auth flavor %d not supported by server\n",
1637 args->auth_flavors[0]);
1638 goto out_err;
1639 }
1640
1641 /*
1642 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1643 * flavor listed first. However, some servers list
1644 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1645 */
1646 for (i = 0; i < count; i++) { 1627 for (i = 0; i < count; i++) {
1647 struct rpcsec_gss_info info; 1628 if (args->auth_flavors[0] == server_authlist[i] ||
1648 1629 server_authlist[i] == RPC_AUTH_NULL)
1649 flavor = request->auth_flavs[i]; 1630 goto out;
1650 switch (flavor) {
1651 case RPC_AUTH_UNIX:
1652 goto out_set;
1653 case RPC_AUTH_NULL:
1654 continue;
1655 default:
1656 if (rpcauth_get_gssinfo(flavor, &info) == 0)
1657 goto out_set;
1658 }
1659 } 1631 }
1660 1632
1661 /* 1633 dfprintk(MOUNT, "NFS: auth flavor %u not supported by server\n",
1662 * As a last chance, see if the server list contains AUTH_NULL - 1634 args->auth_flavors[0]);
1663 * if it does, use the default flavor. 1635 return -EACCES;
1664 */
1665 for (i = 0; i < count; i++) {
1666 if (request->auth_flavs[i] == RPC_AUTH_NULL)
1667 goto out_default;
1668 }
1669
1670 dfprintk(MOUNT, "NFS: no auth flavors in common with server\n");
1671 goto out_err;
1672 1636
1673out_default:
1674 /* use default if flavor not already set */
1675 flavor = (args->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) ?
1676 RPC_AUTH_UNIX : args->auth_flavors[0];
1677out_set:
1678 args->auth_flavors[0] = flavor;
1679out: 1637out:
1680 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]); 1638 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1681 return 0; 1639 return 0;
1682out_err:
1683 return -EACCES;
1684} 1640}
1685 1641
1686/* 1642/*
@@ -1743,13 +1699,17 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1743 return status; 1699 return status;
1744 } 1700 }
1745 1701
1746 return nfs_select_flavor(args, &request); 1702 return 0;
1747} 1703}
1748 1704
1749static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info, 1705static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info,
1750 struct nfs_subversion *nfs_mod) 1706 struct nfs_subversion *nfs_mod)
1751{ 1707{
1752 int status; 1708 int status;
1709 unsigned int i;
1710 bool tried_auth_unix = false;
1711 bool auth_null_in_list = false;
1712 struct nfs_server *server = ERR_PTR(-EACCES);
1753 struct nfs_parsed_mount_data *args = mount_info->parsed; 1713 struct nfs_parsed_mount_data *args = mount_info->parsed;
1754 rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS]; 1714 rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
1755 unsigned int authlist_len = ARRAY_SIZE(authlist); 1715 unsigned int authlist_len = ARRAY_SIZE(authlist);
@@ -1759,6 +1719,58 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1759 if (status) 1719 if (status)
1760 return ERR_PTR(status); 1720 return ERR_PTR(status);
1761 1721
1722 /*
1723 * Was a sec= authflavor specified in the options? First, verify
1724 * whether the server supports it, and then just try to use it if so.
1725 */
1726 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
1727 status = nfs_verify_authflavor(args, authlist, authlist_len);
1728 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1729 if (status)
1730 return ERR_PTR(status);
1731 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1732 }
1733
1734 /*
1735 * No sec= option was provided. RFC 2623, section 2.7 suggests we
1736 * SHOULD prefer the flavor listed first. However, some servers list
1737 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1738 */
1739 for (i = 0; i < authlist_len; ++i) {
1740 rpc_authflavor_t flavor;
1741 struct rpcsec_gss_info info;
1742
1743 flavor = authlist[i];
1744 switch (flavor) {
1745 case RPC_AUTH_UNIX:
1746 tried_auth_unix = true;
1747 break;
1748 case RPC_AUTH_NULL:
1749 auth_null_in_list = true;
1750 continue;
1751 default:
1752 if (rpcauth_get_gssinfo(flavor, &info) != 0)
1753 continue;
1754 /* Fallthrough */
1755 }
1756 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
1757 args->auth_flavors[0] = flavor;
1758 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1759 if (!IS_ERR(server))
1760 return server;
1761 }
1762
1763 /*
1764 * Nothing we tried so far worked. At this point, give up if we've
1765 * already tried AUTH_UNIX or if the server's list doesn't contain
1766 * AUTH_NULL
1767 */
1768 if (tried_auth_unix || !auth_null_in_list)
1769 return server;
1770
1771 /* Last chance! Try AUTH_UNIX */
1772 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
1773 args->auth_flavors[0] = RPC_AUTH_UNIX;
1762 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1774 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1763} 1775}
1764 1776