diff options
-rw-r--r-- | fs/nfs/super.c | 58 |
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 | */ | ||
1445 | static 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 | */ |
1443 | static int nfs_try_mount(struct nfs_parsed_mount_data *args, | 1479 | static 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 | ||
1499 | static int nfs_parse_simple_hostname(const char *dev_name, | 1543 | static int nfs_parse_simple_hostname(const char *dev_name, |