aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-08-09 15:09:32 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:09:32 -0400
commitec88f28d1eb77346f19ca324ceec76e645cdd9da (patch)
tree673457f29da29179be1dc368e5c5fcc75c0cecf3 /fs
parent059f90b323c0f5d34656ab7e0548d7d033c2a51a (diff)
NFS: Use the authentication flavor list returned by mountd
Commit a14017db added support in the kernel's NFS mount client to decode the authentication flavor list returned by mountd. The NFS client can now use this list to determine whether the authentication flavor requested by the user is actually supported by the server. Note we don't actually negotiate the security flavor if none was specified by the user. Instead, we try to use AUTH_SYS, and fail if the server does not support it. This prevents us from negotiating an inappropriate security flavor (some servers list AUTH_NULL first). If the server does not support AUTH_SYS, the user must provide an appropriate security flavor by specifying the "sec=" mount option. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/super.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a33e608713e9..8526008eba72 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1437,13 +1437,50 @@ out_security_failure:
1437} 1437}
1438 1438
1439/* 1439/*
1440 * Match the requested auth flavors with the list returned by
1441 * the server. Returns zero and sets the mount's authentication
1442 * flavor on success; returns -EACCES if server does not support
1443 * the requested flavor.
1444 */
1445static int nfs_walk_authlist(struct nfs_parsed_mount_data *args,
1446 struct nfs_mount_request *request)
1447{
1448 unsigned int i, j, server_authlist_len = *(request->auth_flav_len);
1449
1450 /*
1451 * We avoid sophisticated negotiating here, as there are
1452 * plenty of cases where we can get it wrong, providing
1453 * either too little or too much security.
1454 *
1455 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1456 * flavor listed first. However, some servers list
1457 * AUTH_NULL first. Our caller plants AUTH_SYS, the
1458 * preferred default, in args->auth_flavors[0] if user
1459 * didn't specify sec= mount option.
1460 */
1461 for (i = 0; i < args->auth_flavor_len; i++)
1462 for (j = 0; j < server_authlist_len; j++)
1463 if (args->auth_flavors[i] == request->auth_flavs[j]) {
1464 dfprintk(MOUNT, "NFS: using auth flavor %d\n",
1465 request->auth_flavs[j]);
1466 args->auth_flavors[0] = request->auth_flavs[j];
1467 return 0;
1468 }
1469
1470 dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n");
1471 nfs_umount(request);
1472 return -EACCES;
1473}
1474
1475/*
1440 * Use the remote server's MOUNT service to request the NFS file handle 1476 * Use the remote server's MOUNT service to request the NFS file handle
1441 * corresponding to the provided path. 1477 * corresponding to the provided path.
1442 */ 1478 */
1443static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1479static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1444 struct nfs_fh *root_fh) 1480 struct nfs_fh *root_fh)
1445{ 1481{
1446 unsigned int auth_flavor_len = 0; 1482 rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
1483 unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
1447 struct nfs_mount_request request = { 1484 struct nfs_mount_request request = {
1448 .sap = (struct sockaddr *) 1485 .sap = (struct sockaddr *)
1449 &args->mount_server.address, 1486 &args->mount_server.address,
@@ -1451,7 +1488,8 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1451 .protocol = args->mount_server.protocol, 1488 .protocol = args->mount_server.protocol,
1452 .fh = root_fh, 1489 .fh = root_fh,
1453 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1490 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1454 .auth_flav_len = &auth_flavor_len, 1491 .auth_flav_len = &server_authlist_len,
1492 .auth_flavs = server_authlist,
1455 }; 1493 };
1456 int status; 1494 int status;
1457 1495
@@ -1488,12 +1526,18 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1488 * to a file handle. 1526 * to a file handle.
1489 */ 1527 */
1490 status = nfs_mount(&request); 1528 status = nfs_mount(&request);
1491 if (status == 0) 1529 if (status != 0) {
1492 return 0; 1530 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
1531 request.hostname, status);
1532 return status;
1533 }
1493 1534
1494 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n", 1535 /*
1495 request.hostname, status); 1536 * MNTv1 (NFSv2) does not support auth flavor negotiation.
1496 return status; 1537 */
1538 if (args->mount_server.version != NFS_MNT3_VERSION)
1539 return 0;
1540 return nfs_walk_authlist(args, &request);
1497} 1541}
1498 1542
1499static int nfs_parse_simple_hostname(const char *dev_name, 1543static int nfs_parse_simple_hostname(const char *dev_name,