X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=008fdbc7c9846f41100b3921ea657cad53adb3a0;hp=b5956495eeebf164638d9613102faf81e503a4a5;hb=bac279da80ae860267e8485d7fe2109096a326e9;hpb=97731f394c6b83ed7e5c3923278bbe98ee130bee diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index b595649..008fdbc 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -38,6 +38,7 @@ #include "xcommon.h" #include "mount.h" #include "nls.h" +#include "nfsrpc.h" #include "mount_constants.h" #include "stropts.h" #include "error.h" @@ -371,10 +372,13 @@ static int nfs_extract_server_addresses(struct mount_options *options, } static int nfs_construct_new_options(struct mount_options *options, + struct sockaddr *nfs_saddr, struct pmap *nfs_pmap, + struct sockaddr *mnt_saddr, struct pmap *mnt_pmap) { char new_option[64]; + char *netid; po_remove_all(options, "nfsprog"); po_remove_all(options, "mountprog"); @@ -391,20 +395,14 @@ static int nfs_construct_new_options(struct mount_options *options, po_remove_all(options, "proto"); po_remove_all(options, "udp"); po_remove_all(options, "tcp"); - switch (nfs_pmap->pm_prot) { - case IPPROTO_TCP: - snprintf(new_option, sizeof(new_option) - 1, - "proto=tcp"); - if (po_append(options, new_option) == PO_FAILED) - return 0; - break; - case IPPROTO_UDP: - snprintf(new_option, sizeof(new_option) - 1, - "proto=udp"); - if (po_append(options, new_option) == PO_FAILED) - return 0; - break; - } + netid = nfs_get_netid(nfs_saddr->sa_family, nfs_pmap->pm_prot); + if (netid == NULL) + return 0; + snprintf(new_option, sizeof(new_option) - 1, + "proto=%s", netid); + free(netid); + if (po_append(options, new_option) == PO_FAILED) + return 0; po_remove_all(options, "port"); if (nfs_pmap->pm_port != NFS_PORT) { @@ -421,20 +419,14 @@ static int nfs_construct_new_options(struct mount_options *options, return 0; po_remove_all(options, "mountproto"); - switch (mnt_pmap->pm_prot) { - case IPPROTO_TCP: - snprintf(new_option, sizeof(new_option) - 1, - "mountproto=tcp"); - if (po_append(options, new_option) == PO_FAILED) - return 0; - break; - case IPPROTO_UDP: - snprintf(new_option, sizeof(new_option) - 1, - "mountproto=udp"); - if (po_append(options, new_option) == PO_FAILED) - return 0; - break; - } + netid = nfs_get_netid(mnt_saddr->sa_family, mnt_pmap->pm_prot); + if (netid == NULL) + return 0; + snprintf(new_option, sizeof(new_option) - 1, + "mountproto=%s", netid); + free(netid); + if (po_append(options, new_option) == PO_FAILED) + return 0; po_remove_all(options, "mountport"); snprintf(new_option, sizeof(new_option) - 1, @@ -510,7 +502,8 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options) return 0; } - if (!nfs_construct_new_options(options, &nfs_pmap, &mnt_pmap)) { + if (!nfs_construct_new_options(options, nfs_saddr, &nfs_pmap, + mnt_saddr, &mnt_pmap)) { errno = EINVAL; return 0; } @@ -611,6 +604,18 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) } if (mi->version == 0) { + if (po_contains(options, "mounthost") || + po_contains(options, "mountaddr") || + po_contains(options, "mountvers") || + po_contains(options, "mountproto")) { + /* + * Since these mountd options are set assume version 3 + * is wanted so error out with EPROTONOSUPPORT so the + * protocol negation starts with v3. + */ + errno = EPROTONOSUPPORT; + goto out_fail; + } if (po_append(options, "vers=4") == PO_FAILED) { errno = EINVAL; goto out_fail; @@ -656,9 +661,10 @@ static int nfs_try_mount(struct nfsmount_info *mi) /* * To deal with legacy Linux servers that don't * automatically export a pseudo root, retry - * ENOENT errors using version 3 + * ENOENT errors using version 3. And for + * Linux servers prior to 2.6.25, retry EPERM */ - if (errno != ENOENT) + if (errno != ENOENT && errno != EPERM) break; } }