aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,