diff --git a/CHANGELOG b/CHANGELOG index 62dac81..a9263c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,17 @@ +??/??/20?? autofs-5.0.9 +======================= +- fix undefined authtype_requires_creds err if ldap enabled but without sasl. +- fix master map type check. +- fix task manager not getting signaled. +- allow --with-systemd to take a path arg. +- fix WITH_LIBTIRPC function name. +- fix ipv6 libtirpc getport. +- fix ipv6 link local address handling. +- fix fix ipv6 libtirpc getport. +- get_nfs_info() should query portmapper if port is not given. +- fix rpc_portmap_getport() proto not set. +- fix protmap not trying proto v2. + 17/10/2013 autofs-5.0.8 ======================= - fix nobind sun escaped map entries. diff --git a/aclocal.m4 b/aclocal.m4 index 3e6f223..2115204 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -229,8 +229,10 @@ dnl Check the location of the systemd unit files directory dnl -------------------------------------------------------------------------- AC_DEFUN([AF_WITH_SYSTEMD], [AC_ARG_WITH(systemd, -[ --with-systemd install systemd unit file if systemd unit directory - is found on system], +[ --with-systemd@<:@=systemddir@:>@ install systemd unit file. If 'yes' + probe the system for unit directory. + If a path is specified, assume that + is a valid install path.], [if test "$withval" = yes; then if test -z "$systemddir"; then AC_MSG_CHECKING([location of the systemd unit files directory]) @@ -247,6 +249,10 @@ AC_DEFUN([AF_WITH_SYSTEMD], else AC_MSG_RESULT(not found) fi +else + if test "$withval" != no; then + systemddir=$withval + fi fi]) ]) @@ -435,7 +441,7 @@ CFLAGS="$af_check_libtirpc_save_cflags" LDFLAGS="$af_check_libtirpc_save_ldflags" ]) -AC_DEFUN([AM_WITH_LIBTIRPC], +AC_DEFUN([AF_WITH_LIBTIRPC], [AC_MSG_CHECKING([if libtirpc is requested and available]) AC_ARG_WITH(libtirpc, [ --with-libtirpc use libtirpc if available], diff --git a/configure b/configure index 2c2e312..4e1743d 100755 --- a/configure +++ b/configure @@ -1372,8 +1372,10 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-path=PATH look in PATH for binaries needed by the automounter - --with-systemd install systemd unit file if systemd unit directory - is found on system + --with-systemd[=systemddir] install systemd unit file. If 'yes' + probe the system for unit directory. + If a path is specified, assume that + is a valid install path. --with-confdir=DIR use DIR for autofs configuration files --with-mapdir=PATH look in PATH for mount maps used by the automounter --with-fifodir=PATH use PATH as the directory for fifos used by the automounter @@ -2260,6 +2262,10 @@ $as_echo "$systemddir" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } fi +else + if test "$withval" != no; then + systemddir=$withval + fi fi fi diff --git a/configure.in b/configure.in index 5f29163..1eeb8dc 100644 --- a/configure.in +++ b/configure.in @@ -124,7 +124,7 @@ AC_SUBST(flagdir) # # Use libtirpc # -AM_WITH_LIBTIRPC() +AF_WITH_LIBTIRPC() AC_SUBST(TIRPCLIB) # diff --git a/daemon/lookup.c b/daemon/lookup.c index e3d9536..7fea942 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -171,14 +171,22 @@ int lookup_nss_read_master(struct master *master, time_t age) char source[10]; memset(source, 0, 10); - if (!strncmp(name, "file:", 5) || - !strncmp(name, "yp:", 3) || - !strncmp(name, "nis:", 4) || - !strncmp(name, "nisplus:", 8) || - !strncmp(name, "ldap:", 5) || - !strncmp(name, "ldaps:", 6) || - !strncmp(name, "sss:", 4) || - !strncmp(name, "dir:", 4)) { + if ((!strncmp(name, "file", 4) && + (name[4] == ',' || name[4] == ':')) || + (!strncmp(name, "yp", 3) && + (name[3] == ',' || name[3] == ':')) || + (!strncmp(name, "nis", 3) && + (name[3] == ',' || name[3] == ':')) || + (!strncmp(name, "nisplus", 7) && + (name[7] == ',' || name[7] == ':')) || + (!strncmp(name, "ldap", 4) && + (name[4] == ',' || name[4] == ':')) || + (!strncmp(name, "ldaps", 5) && + (name[5] == ',' || name[5] == ':')) || + (!strncmp(name, "sss", 3) || + (name[3] == ',' || name[3] == ':')) || + (!strncmp(name, "dir", 3) && + (name[3] == ',' || name[3] == ':'))) { strncpy(source, name, tmp - name); /* diff --git a/daemon/state.c b/daemon/state.c index 8d81788..3174a9c 100644 --- a/daemon/state.c +++ b/daemon/state.c @@ -818,13 +818,13 @@ done: new = st_alloc_task(ap, state); if (new) list_add(&new->list, head); - /* Added to empty state queue, kick state machine */ - signaled = 1; - status = pthread_cond_signal(&cond); - if (status) - fatal(status); } + signaled = 1; + status = pthread_cond_signal(&cond); + if (status) + fatal(status); + return 1; } diff --git a/include/automount.h b/include/automount.h index 71787a5..396391c 100644 --- a/include/automount.h +++ b/include/automount.h @@ -335,6 +335,7 @@ size_t _strlen(const char *str, size_t max); int cat_path(char *buf, size_t len, const char *dir, const char *base); int ncat_path(char *buf, size_t len, const char *dir, const char *base, size_t blen); +int _strncmp(const char *s1, const char *s2, size_t n); /* Core automount definitions */ diff --git a/lib/cat_path.c b/lib/cat_path.c index 60669db..c386b33 100644 --- a/lib/cat_path.c +++ b/lib/cat_path.c @@ -87,3 +87,12 @@ int ncat_path(char *buf, size_t len, return cat_path(buf, len, dir, name); } +/* Compare first n bytes of s1 and s2 and that n == strlen(s1) */ +int _strncmp(const char *s1, const char *s2, size_t n) +{ + size_t len = strlen(s1); + + if (n != len) + return n - len; + return strncmp(s1, s2, n); +} diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index 46b3e8d..5d6ead0 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -234,6 +234,29 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i return 0; } +static int rpc_getport(struct conn_info *info, + struct pmap *parms, CLIENT *client, + unsigned short *port) +{ + enum clnt_stat status; + + /* + * Check to see if server is up otherwise a getport will take + * forever to timeout. + */ + status = clnt_call(client, PMAPPROC_NULL, + (xdrproc_t) xdr_void, 0, (xdrproc_t) xdr_void, 0, + info->timeout); + + if (status == RPC_SUCCESS) { + status = clnt_call(client, PMAPPROC_GETPORT, + (xdrproc_t) xdr_pmap, (caddr_t) parms, + (xdrproc_t) xdr_u_short, (caddr_t) port, + info->timeout); + } + + return status; +} #else static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd, CLIENT **client) { @@ -267,9 +290,6 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i laddr = (struct sockaddr *) &in4_laddr; in4_raddr->sin_port = htons(info->port); slen = sizeof(struct sockaddr_in); - /* Use rpcbind v2 for AF_INET */ - if (info->program == rpcb_prog) - info->version = PMAPVERS; } else if (addr->sa_family == AF_INET6) { struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr; in6_laddr.sin6_family = AF_INET6; @@ -324,6 +344,255 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i return 0; } + +/* + * Thankfully nfs-utils had already dealt with this. + * Thanks to Chuck Lever for his nfs-utils patch series, much of + * which is used here. + */ +static pthread_mutex_t proto_mutex = PTHREAD_MUTEX_INITIALIZER; + +static enum clnt_stat rpc_get_netid(const sa_family_t family, + const int protocol, char **netid) +{ + char *nc_protofmly, *nc_proto, *nc_netid; + struct netconfig *nconf; + struct protoent *proto; + void *handle; + + switch (family) { + case AF_LOCAL: + case AF_INET: + nc_protofmly = NC_INET; + break; + case AF_INET6: + nc_protofmly = NC_INET6; + break; + default: + return RPC_UNKNOWNPROTO; + } + + pthread_mutex_lock(&proto_mutex); + proto = getprotobynumber(protocol); + if (!proto) { + pthread_mutex_unlock(&proto_mutex); + return RPC_UNKNOWNPROTO; + } + nc_proto = strdup(proto->p_name); + pthread_mutex_unlock(&proto_mutex); + if (!nc_proto) + return RPC_SYSTEMERROR; + + handle = setnetconfig(); + while ((nconf = getnetconfig(handle)) != NULL) { + if (nconf->nc_protofmly != NULL && + strcmp(nconf->nc_protofmly, nc_protofmly) != 0) + continue; + if (nconf->nc_proto != NULL && + strcmp(nconf->nc_proto, nc_proto) != 0) + continue; + + nc_netid = strdup(nconf->nc_netid); + if (!nc_netid) { + free(nc_proto); + return RPC_SYSTEMERROR; + } + + *netid = nc_netid; + } + endnetconfig(handle); + free(nc_proto); + + return RPC_SUCCESS; +} + +static char *rpc_sockaddr2universal(const struct sockaddr *addr) +{ + const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) addr; + const struct sockaddr_un *sun = (const struct sockaddr_un *) addr; + const struct sockaddr_in *sin = (const struct sockaddr_in *) addr; + char buf[INET6_ADDRSTRLEN + 8 /* for port information */]; + uint16_t port; + size_t count; + char *result; + int len; + + switch (addr->sa_family) { + case AF_LOCAL: + return strndup(sun->sun_path, sizeof(sun->sun_path)); + case AF_INET: + if (inet_ntop(AF_INET, (const void *)&sin->sin_addr.s_addr, + buf, (socklen_t)sizeof(buf)) == NULL) + goto out_err; + port = ntohs(sin->sin_port); + break; + case AF_INET6: + if (inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, + buf, (socklen_t)sizeof(buf)) == NULL) + goto out_err; + port = ntohs(sin6->sin6_port); + break; + default: + goto out_err; + } + + count = sizeof(buf) - strlen(buf); + len = snprintf(buf + strlen(buf), count, ".%u.%u", + (unsigned)(port >> 8), (unsigned)(port & 0xff)); + /* before glibc 2.0.6, snprintf(3) could return -1 */ + if (len < 0 || (size_t)len > count) + goto out_err; + + result = strdup(buf); + return result; + +out_err: + return NULL; +} + +static int rpc_universal2port(const char *uaddr) +{ + char *addrstr; + char *p, *endptr; + unsigned long portlo, porthi; + int port = -1; + + addrstr = strdup(uaddr); + if (!addrstr) + return -1; + + p = strrchr(addrstr, '.'); + if (!p) + goto out; + + portlo = strtoul(p + 1, &endptr, 10); + if (*endptr != '\0' || portlo > 255) + goto out; + *p = '\0'; + + p = strrchr(addrstr, '.'); + if (!p) + goto out; + + porthi = strtoul(p + 1, &endptr, 10); + if (*endptr != '\0' || porthi > 255) + goto out; + *p = '\0'; + + port = (porthi << 8) | portlo; + +out: + free(addrstr); + return port; +} + +static enum clnt_stat rpc_rpcb_getport(CLIENT *client, + struct rpcb *parms, + struct timeval timeout, + unsigned short *port) +{ + rpcvers_t rpcb_version; + struct rpc_err rpcerr; + int s_port = 0; + + for (rpcb_version = RPCBVERS_4; + rpcb_version >= RPCBVERS_3; + rpcb_version--) { + enum clnt_stat status; + char *uaddr = NULL; + + CLNT_CONTROL(client, CLSET_VERS, (void *) &rpcb_version); + status = CLNT_CALL(client, (rpcproc_t) RPCBPROC_GETADDR, + (xdrproc_t) xdr_rpcb, (void *) parms, + (xdrproc_t) xdr_wrapstring, (void *) &uaddr, + timeout); + + switch (status) { + case RPC_SUCCESS: + if ((uaddr == NULL) || (uaddr[0] == '\0')) + return RPC_PROGNOTREGISTERED; + + s_port = rpc_universal2port(uaddr); + xdr_free((xdrproc_t) xdr_wrapstring, (char *) &uaddr); + if (s_port == -1) { + return RPC_N2AXLATEFAILURE; + } + *port = s_port; + return RPC_SUCCESS; + + case RPC_PROGVERSMISMATCH: + clnt_geterr(client, &rpcerr); + if (rpcerr.re_vers.low > RPCBVERS4) + return status; + continue; + + case RPC_PROGUNAVAIL: + continue; + + case RPC_PROGNOTREGISTERED: + continue; + + default: + /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ + return status; + } + } + + return RPC_PROGNOTREGISTERED; +} + +static enum clnt_stat rpc_getport(struct conn_info *info, + struct pmap *parms, CLIENT *client, + unsigned short *port) +{ + enum clnt_stat status; + struct sockaddr *paddr, addr; + struct rpcb rpcb_parms; + char *netid, *raddr; + + if (info->addr) + paddr = info->addr; + else { + if (!clnt_control(client, CLGET_SERVER_ADDR, (char *) &addr)) + return RPC_UNKNOWNADDR; + paddr = &addr; + } + + netid = NULL; + status = rpc_get_netid(paddr->sa_family, info->proto, &netid); + if (status != RPC_SUCCESS) + return status; + + raddr = rpc_sockaddr2universal(paddr); + if (!raddr) { + free(netid); + return RPC_UNKNOWNADDR; + } + + memset(&rpcb_parms, 0, sizeof(rpcb_parms)); + rpcb_parms.r_prog = parms->pm_prog; + rpcb_parms.r_vers = parms->pm_vers; + rpcb_parms.r_netid = netid; + rpcb_parms.r_addr = raddr; + rpcb_parms.r_owner = ""; + + status = rpc_rpcb_getport(client, &rpcb_parms, info->timeout, port); + + free(netid); + free(raddr); + + if (status == RPC_PROGNOTREGISTERED) { + /* Last chance, version 2 uses a different procedure */ + rpcvers_t rpcb_version = PMAPVERS; + CLNT_CONTROL(client, CLSET_VERS, (void *) &rpcb_version); + status = clnt_call(client, PMAPPROC_GETPORT, + (xdrproc_t) xdr_pmap, (caddr_t) parms, + (xdrproc_t) xdr_u_short, (caddr_t) port, + info->timeout); + } + + return status; +} #endif #if defined(HAVE_GETRPCBYNAME) || defined(HAVE_GETSERVBYNAME) @@ -380,7 +649,7 @@ static unsigned short rpc_getrpcbport(const int proto) done: pthread_mutex_unlock(&rpcb_mutex); #endif - return (unsigned short) PMAPPORT; + return (unsigned short) htons(PMAPPORT); } /* @@ -412,6 +681,12 @@ static int create_client(struct conn_info *info, CLIENT **client) goto done; if (ret == -EHOSTUNREACH) goto out_close; + if (ret == -EINVAL) { + char buf[MAX_ERR_BUF]; + char *estr = strerror_r(-ret, buf, MAX_ERR_BUF); + error(LOGOPT_ANY, "connect() failed: %s", estr); + goto out_close; + } if (!info->client && fd != RPC_ANYSOCK) { close(fd); @@ -618,6 +893,8 @@ int rpc_portmap_getport(struct conn_info *info, memset(&pmap_info, 0, sizeof(struct conn_info)); + pmap_info.proto = proto; + if (proto == IPPROTO_TCP) pmap_info.timeout.tv_sec = PMAP_TOUT_TCP; else @@ -647,20 +924,7 @@ int rpc_portmap_getport(struct conn_info *info, return ret; } - /* - * Check to see if server is up otherwise a getport will take - * forever to timeout. - */ - status = clnt_call(client, PMAPPROC_NULL, - (xdrproc_t) xdr_void, 0, (xdrproc_t) xdr_void, 0, - pmap_info.timeout); - - if (status == RPC_SUCCESS) { - status = clnt_call(client, PMAPPROC_GETPORT, - (xdrproc_t) xdr_pmap, (caddr_t) parms, - (xdrproc_t) xdr_u_short, (caddr_t) port, - pmap_info.timeout); - } + status = rpc_getport(&pmap_info, parms, client, port); if (!info->client) { /* @@ -867,6 +1131,11 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) &info->timeout); client->cl_auth = authunix_create_default(); + if (client->cl_auth == NULL) { + error(LOGOPT_ANY, "auth create failed"); + clnt_destroy(client); + return 0; + } vers_entry = 0; while (1) { diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c index 2ab1e8c..04b1da7 100644 --- a/modules/lookup_ldap.c +++ b/modules/lookup_ldap.c @@ -846,20 +846,20 @@ int get_property(unsigned logopt, xmlNodePtr node, const char *prop, char **valu return 0; } -#ifdef WITH_SASL /* * For plain text, login and digest-md5 authentication types, we need * user and password credentials. */ int authtype_requires_creds(const char *authtype) { +#ifdef WITH_SASL if (!strncmp(authtype, "PLAIN", strlen("PLAIN")) || !strncmp(authtype, "DIGEST-MD5", strlen("DIGEST-MD5")) || !strncmp(authtype, "LOGIN", strlen("LOGIN"))) return 1; +#endif return 0; } -#endif /* * Returns: diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c index 319f2e4..61aec70 100644 --- a/modules/mount_autofs.c +++ b/modules/mount_autofs.c @@ -116,17 +116,17 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, while (*comma != '\0' && *comma != ',') comma++; - if (strncmp(cp, "nobrowse", 8) == 0) + if (_strncmp(cp, "nobrowse", 8) == 0) ghost = 0; - else if (strncmp(cp, "nobind", 6) == 0) + else if (_strncmp(cp, "nobind", 6) == 0) nobind = 1; - else if (strncmp(cp, "browse", 6) == 0) + else if (_strncmp(cp, "browse", 6) == 0) ghost = 1; - else if (strncmp(cp, "symlink", 7) == 0) + else if (_strncmp(cp, "symlink", 7) == 0) symlnk = 1; - else if (strncmp(cp, "hosts", 5) == 0) + else if (_strncmp(cp, "hosts", 5) == 0) hosts = 1; - else if (strncmp(cp, "timeout=", 8) == 0) { + else if (_strncmp(cp, "timeout=", 8) == 0) { char *val = strchr(cp, '='); unsigned tout; if (val) { diff --git a/modules/mount_bind.c b/modules/mount_bind.c index 2b70104..a70bf3a 100644 --- a/modules/mount_bind.c +++ b/modules/mount_bind.c @@ -107,7 +107,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int end--; o_len = end - cp + 1; - if (strncmp("symlink", cp, o_len) == 0) + if (_strncmp("symlink", cp, o_len) == 0) symlnk = 1; } } diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c index 1edf347..1bc429d 100644 --- a/modules/mount_ext2.c +++ b/modules/mount_ext2.c @@ -77,7 +77,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int if (options && options[0]) { for (p = options; (p1 = strchr(p, ',')); p = p1) - if (!strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) + if (!_strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) ro = 1; if (!strcmp(p, "ro")) ro = 1; diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c index 5a582ef..315fc99 100644 --- a/modules/mount_nfs.c +++ b/modules/mount_nfs.c @@ -126,32 +126,32 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int o_len = end - cp + 1; - if (strncmp("proto=rdma", cp, o_len) == 0 || - strncmp("rdma", cp, o_len) == 0) + if (_strncmp("proto=rdma", cp, o_len) == 0 || + _strncmp("rdma", cp, o_len) == 0) rdma = 1; - if (strncmp("nosymlink", cp, o_len) == 0) { + if (_strncmp("nosymlink", cp, o_len) == 0) { warn(ap->logopt, MODPREFIX "the \"nosymlink\" option is depricated " "and will soon be removed, " "use the \"nobind\" option instead"); nosymlink = 1; - } else if (strncmp("nobind", cp, o_len) == 0) { + } else if (_strncmp("nobind", cp, o_len) == 0) { nobind = 1; - } else if (strncmp("no-use-weight-only", cp, o_len) == 0) { + } else if (_strncmp("no-use-weight-only", cp, o_len) == 0) { flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY; - } else if (strncmp("use-weight-only", cp, o_len) == 0) { + } else if (_strncmp("use-weight-only", cp, o_len) == 0) { flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; } else { - if (strncmp("vers=4", cp, o_len) == 0 || - strncmp("nfsvers=4", cp, o_len) == 0) + if (_strncmp("vers=4", cp, o_len) == 0 || + _strncmp("nfsvers=4", cp, o_len) == 0) vers = NFS4_VERS_MASK | TCP_SUPPORTED; - else if (strncmp("vers=3", cp, o_len) == 0 || - strncmp("nfsvers=3", cp, o_len) == 0) { + else if (_strncmp("vers=3", cp, o_len) == 0 || + _strncmp("nfsvers=3", cp, o_len) == 0) { vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); vers |= NFS3_REQUESTED; - } else if (strncmp("vers=2", cp, o_len) == 0 || - strncmp("nfsvers=2", cp, o_len) == 0) { + } else if (_strncmp("vers=2", cp, o_len) == 0 || + _strncmp("nfsvers=2", cp, o_len) == 0) { vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); vers |= NFS2_REQUESTED; } else if (strstr(cp, "port=") == cp && @@ -164,16 +164,16 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int if (port < 0) port = 0; port_opt = cp; - } else if (strncmp("proto=udp", cp, o_len) == 0 || - strncmp("udp", cp, o_len) == 0) { + } else if (_strncmp("proto=udp", cp, o_len) == 0 || + _strncmp("udp", cp, o_len) == 0) { vers &= ~TCP_SUPPORTED; - } else if (strncmp("proto=tcp", cp, o_len) == 0 || - strncmp("tcp", cp, o_len) == 0) { + } else if (_strncmp("proto=tcp", cp, o_len) == 0 || + _strncmp("tcp", cp, o_len) == 0) { vers &= ~UDP_SUPPORTED; } /* Check for options that also make sense with bind mounts */ - else if (strncmp("ro", cp, o_len) == 0) + else if (_strncmp("ro", cp, o_len) == 0) ro = 1; /* and jump over trailing white space */ memcpy(nfsp, cp, comma - cp + 1); diff --git a/modules/parse_sun.c b/modules/parse_sun.c index 30820b5..9a877c8 100644 --- a/modules/parse_sun.c +++ b/modules/parse_sun.c @@ -511,29 +511,29 @@ static int sun_mount(struct autofs_point *ap, const char *root, while (*comma != '\0' && *comma != ',') comma++; - if (strncmp("fstype=", cp, 7) == 0) { + if (_strncmp("fstype=", cp, 7) == 0) { int typelen = comma - (cp + 7); fstype = alloca(typelen + 1); memcpy(fstype, cp + 7, typelen); fstype[typelen] = '\0'; - } else if (strncmp("nonstrict", cp, 9) == 0) { + } else if (_strncmp("nonstrict", cp, 9) == 0) { nonstrict = 1; - } else if (strncmp("strict", cp, 6) == 0) { + } else if (_strncmp("strict", cp, 6) == 0) { nonstrict = 0; - } else if (strncmp("nobrowse", cp, 8) == 0 || - strncmp("browse", cp, 6) == 0 || - strncmp("timeout=", cp, 8) == 0) { + } else if (_strncmp("nobrowse", cp, 8) == 0 || + _strncmp("browse", cp, 6) == 0 || + _strncmp("timeout=", cp, 8) == 0) { if (strcmp(fstype, "autofs") == 0 || strstr(cp, "fstype=autofs")) { memcpy(np, cp, comma - cp + 1); np += comma - cp + 1; } - } else if (strncmp("no-use-weight-only", cp, 18) == 0) { + } else if (_strncmp("no-use-weight-only", cp, 18) == 0) { use_weight_only = -1; - } else if (strncmp("use-weight-only", cp, 15) == 0) { + } else if (_strncmp("use-weight-only", cp, 15) == 0) { use_weight_only = MOUNT_FLAG_USE_WEIGHT_ONLY; - } else if (strncmp("bg", cp, 2) == 0 || - strncmp("nofg", cp, 4) == 0) { + } else if (_strncmp("bg", cp, 2) == 0 || + _strncmp("nofg", cp, 4) == 0) { continue; } else { memcpy(np, cp, comma - cp + 1); @@ -862,7 +862,7 @@ static int validate_location(unsigned int logopt, char *loc) *ptr == '-' || *ptr == '.' || *ptr == '_' || *ptr == ',' || *ptr == '(' || *ptr == ')' || *ptr == '#' || *ptr == '@' || *ptr == ':' || - *ptr == '[' || *ptr == ']')) { + *ptr == '[' || *ptr == ']' || *ptr == '%')) { error(logopt, "invalid character \"%c\" " "found in location %s", *ptr, loc); return 0; diff --git a/modules/replicated.c b/modules/replicated.c index 5fdd9d9..2463235 100644 --- a/modules/replicated.c +++ b/modules/replicated.c @@ -444,9 +444,12 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, host->name, proto, version); rpc_info->proto = proto; - if (port < 0) - rpc_info->port = NFS_PORT; - else if (port > 0) + if (port < 0) { + if (version & NFS4_REQUESTED) + rpc_info->port = NFS_PORT; + else + port = 0; + } else if (port > 0) rpc_info->port = port; memset(&parms, 0, sizeof(struct pmap));