From c7d149a7a99681c4d8ea2a9ebbe5c780ef057b8a Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Nov 25 2013 01:39:42 +0000 Subject: - add current upstream patches (should fix bug 1033918). --- diff --git a/autofs-5.0.8-allow-with-systemd-to-take-a-path-arg.patch b/autofs-5.0.8-allow-with-systemd-to-take-a-path-arg.patch new file mode 100644 index 0000000..c08799c --- /dev/null +++ b/autofs-5.0.8-allow-with-systemd-to-take-a-path-arg.patch @@ -0,0 +1,62 @@ +autofs-5.0.8 - allow --with-systemd to take a path arg + +From: Joe MacDonald + +If building for a cross-compile environment with systemd it is convenient +to be able to specify a systemd path for the target that may not be the +same as that on the host. + +I encountered a problem while working with autofs in a cross-compile +environment where the host and target have either differing systemd paths +or where one may not have systemd support at all. The common solution +I've seen in other projects is to have a --with-systemddir=[path] option, +but I thought it'd be simpler to add an optional path argument to the +extant '--with-systemd' configure parameter and leave the default =y+probe +for path logic in place. + +Signed-off-by: Joe MacDonald +--- + CHANGELOG | 1 + + aclocal.m4 | 10 ++++++++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index a01393c..565153d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - 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. + + 17/10/2013 autofs-5.0.8 + ======================= +diff --git a/aclocal.m4 b/aclocal.m4 +index 3e6f223..105e3e9 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]) + ]) + diff --git a/autofs-5.0.8-fix-WITH_LIBTIRPC-function-name.patch b/autofs-5.0.8-fix-WITH_LIBTIRPC-function-name.patch new file mode 100644 index 0000000..d62b028 --- /dev/null +++ b/autofs-5.0.8-fix-WITH_LIBTIRPC-function-name.patch @@ -0,0 +1,49 @@ +autofs-5.0.8 - fix WITH_LIBTIRPC function name + +From: Ian Kent + +autoconf function names AM_ are reserved so don't use them. +--- + CHANGELOG | 1 + + aclocal.m4 | 2 +- + configure.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 565153d..68db340 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - fix master map type check. + - fix task manager not getting signaled. + - allow --with-systemd to take a path arg. ++- fix WITH_LIBTIRPC function name. + + 17/10/2013 autofs-5.0.8 + ======================= +diff --git a/aclocal.m4 b/aclocal.m4 +index 105e3e9..2115204 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -441,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.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/autofs-5.0.8-fix-allow-with-systemd-to-take-a-path-arg.patch b/autofs-5.0.8-fix-allow-with-systemd-to-take-a-path-arg.patch new file mode 100644 index 0000000..d49cb59 --- /dev/null +++ b/autofs-5.0.8-fix-allow-with-systemd-to-take-a-path-arg.patch @@ -0,0 +1,37 @@ +autofs-5.0.8 - fix allow with systemd to take a path arg + +From: Ian Kent + +And update configure .. +--- + configure | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +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/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch b/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch new file mode 100644 index 0000000..eee6c5c --- /dev/null +++ b/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch @@ -0,0 +1,345 @@ +autofs-5.0.8 - fix ipv6 libtirpc getport + +From: Ian Kent + +The method that was being used to obtain a service port number +when using libtirpc was wrong. +--- + CHANGELOG | 1 + lib/rpc_subs.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 267 insertions(+), 17 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 68db340..9c87373 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ + - fix task manager not getting signaled. + - allow --with-systemd to take a path arg. + - fix WITH_LIBTIRPC function name. ++- fix ipv6 libtirpc getport. + + 17/10/2013 autofs-5.0.8 + ======================= +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 46b3e8d..2365b6e 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -234,6 +234,28 @@ 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) ++{ ++ 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 +289,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 +343,244 @@ 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_PROCUNAVAIL: ++ case RPC_PROGUNAVAIL: ++ continue; ++ default: ++ /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ ++ return status; ++ } ++ } ++ ++ if (s_port == 0) ++ return RPC_PROGNOTREGISTERED; ++ ++ return RPC_PROCUNAVAIL; ++} ++ ++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); ++ ++ return status; ++} + #endif + + #if defined(HAVE_GETRPCBYNAME) || defined(HAVE_GETSERVBYNAME) +@@ -647,20 +904,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 +1111,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/autofs.spec b/autofs.spec index 7c86779..4035d55 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.8 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -16,6 +16,10 @@ Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.b Patch1: autofs-5.0.8-fix-undefined-authtype_requires_creds-err-if-ldap-en.patch Patch2: autofs-5.0.8-fix-master-map-type-check.patch Patch3: autofs-5.0.8-fix-task-manager-not-getting-signaled.patch +Patch4: autofs-5.0.8-allow-with-systemd-to-take-a-path-arg.patch +Patch5: autofs-5.0.8-fix-allow-with-systemd-to-take-a-path-arg.patch +Patch6: autofs-5.0.8-fix-WITH_LIBTIRPC-function-name.patch +Patch7: autofs-5.0.8-fix-ipv6-libtirpc-getport.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if %{with_systemd} BuildRequires: systemd-units @@ -76,6 +80,10 @@ echo %{version}-%{release} > .version %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build LDFLAGS=-Wl,-z,now @@ -167,6 +175,11 @@ fi %dir /etc/auto.master.d %changelog +* Mon Nov 25 2013 Ian Kent - 1:5.0.8-4 +- allow --with-systemd to take a path arg. +- fix WITH_LIBTIRPC function name. +- fix ipv6 libtirpc getport (bz1033918). + * Thu Nov 7 2013 Ian Kent - 1:5.0.8-3 - fix undefined authtype_requires_creds err if ldap enabled but without sasl. - fix master map type check.