diff --git a/libtirpc-0.3.3-rc3.patch b/libtirpc-0.3.3-rc3.patch new file mode 100644 index 0000000..383470c --- /dev/null +++ b/libtirpc-0.3.3-rc3.patch @@ -0,0 +1,1288 @@ +diff --git a/configure.ac b/configure.ac +index 99a0d33..4d18efa 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -5,6 +5,33 @@ AC_CONFIG_SRCDIR([src/auth_des.c]) + AC_CONFIG_MACRO_DIR([m4]) + AC_PROG_CC + ++# LT_VERSION_INFO="current:revision:age" ++# ++# From the libtool manual: ++# ++# 1. Start with version information of 0:0:0 for each libtool library. ++# 2. Update the version information only immediately before a public ++# release of your software. More frequent updates are unnecessary, ++# and only guarantee that the current interface number gets larger faster. ++# 3. If the library source code has changed at all since the last update, ++# then increment revision (c:r:a becomes c:r+1:a). ++# 4. If any interfaces have been added, removed, or changed since the last ++# update, increment current, and set revision to 0. ++# 5. If any interfaces have been added since the last public release, ++# then increment age. ++# 6. If any interfaces have been removed since the last public release, ++# then set age to 0. ++# ++# _Never_ try to set the interface numbers so that they correspond to the ++# release number of your package. This is an abuse that only fosters ++# misunderstanding of the purpose of library versions. ++# ++# In addition to these rules, symbol versioning is now in effect. soname ++# changes should be avoided. ++# ++LT_VERSION_INFO="2:0:1" ++AC_SUBST([LT_VERSION_INFO]) ++ + AC_CHECK_HEADER([gssapi/gssapi.h], [HAVE_GSSAPI_H=yes], [HAVE_GSSAPI_H=no]) + + AC_ARG_ENABLE(gssapi, +@@ -39,6 +66,21 @@ AC_ARG_ENABLE(symvers, + [],[enable_symvers=yes]) + AM_CONDITIONAL(SYMVERS, test "x$enable_symvers" = xyes) + ++AC_CANONICAL_BUILD ++# Check for which host we are on and setup a few things ++# specifically based on the host ++case $build_os in ++ linux*) ++ # Do something specific for linux ++ LDFLAG_NOUNDEFINED="-Wl,--no-undefined" ++ AC_SUBST(LDFLAG_NOUNDEFINED) ++ ;; ++ *) ++ #Default Case ++ ;; ++esac ++ ++ + AC_CONFIG_HEADERS([config.h]) + AC_PROG_LIBTOOL + AC_HEADER_DIRENT +diff --git a/man/rpc_gss_get_mech_info.3t b/man/rpc_gss_get_mech_info.3t +index 1f3ba04..44f0df3 100644 +--- a/man/rpc_gss_get_mech_info.3t ++++ b/man/rpc_gss_get_mech_info.3t +@@ -29,28 +29,33 @@ + .Os + .Sh NAME + .Nm rpc_gss_get_mech_info +-.Nd "Get extra information about a security mechanism" ++.Nd "Get Quality of Protection information for a security mechanism" + .Sh SYNOPSIS + .In rpc/rpcsec_gss.h + .Ft const char ** + .Fn rpc_gss_get_mech_info "const char *mech" "rpc_gss_service_t *service" + .Sh DESCRIPTION +-This function looks up a mechanism by name by reading the file +-/etc/gss/mech and queries it for its capabilities. ++This function returns the list of QOP names supported by the ++GSS_API mechanism named "mech". + .Sh PARAMETERS + .Bl -tag -width ".It service" + .It mech +-The mechanism to search for ++The name of a GSS_API mechanism. ++"kerberos_v5" is currently the only supported mechanism. + .It service +-If the mechanism is found, the maximum supported service type is +-returned in +-.Fa *service ++Buffer in which maximum service type is planted + .El + .Sh RETURN VALUES +-If the mechanism is found, +-a list of the supported qualities of protection is returned, +-otherwise +-.Dv NULL . ++If the named GSS_API mechanism is recognized, ++a list of the supported Qualities of Protection is returned. ++The maximum supported service type for the mechanism is returned in ++.Fa *service . ++Otherwise ++.Dv NULL ++is returned. ++.Pp ++Note: The returned QOP list is statically allocated memory. ++The caller must not free this array. + .Sh AVAILABILITY + The + .Fn rpc_gss_get_mech_info +diff --git a/man/rpc_gss_getcred.3t b/man/rpc_gss_getcred.3t +index 8589f08..691df31 100644 +--- a/man/rpc_gss_getcred.3t ++++ b/man/rpc_gss_getcred.3t +@@ -51,7 +51,6 @@ If non-null, + .Fa *rcred + is set to point at the raw credentials for this request + .It ucred +-.It rcred + If non-null, + .Fa *ucred + is set to point at the corresponding unix credentials +diff --git a/man/rpc_gss_is_installed.3t b/man/rpc_gss_is_installed.3t +index 274a1f0..d5f5e44 100644 +--- a/man/rpc_gss_is_installed.3t ++++ b/man/rpc_gss_is_installed.3t +@@ -29,23 +29,24 @@ + .Os + .Sh NAME + .Nm rpc_gss_is_installed +-.Nd "Query for the presence os a security mechanism" ++.Nd "Query for the presence of a security mechanism" + .Sh SYNOPSIS + .In rpc/rpcsec_gss.h + .Ft bool_t + .Fn rpc_gss_is_installed "const char *mech" + .Sh DESCRIPTION +-This function looks up a mechanism by name by reading the file +-/etc/gss/mech. ++This function indicates whether the GSS_API mechanism named "mech" ++is installed and enabled. + .Sh PARAMETERS + .Bl -tag -width ".It mech" + .It mech +-The mechanism to search for ++The name of a GSS_API mechanism. ++"kerberos_v5" is currently the only supported mechanism. + .El + .Sh RETURN VALUES + Returns + .Dv TRUE +-if the mechanism is installed, ++if the named GSS_API mechanism is installed and enabled, + .Dv FALSE + otherwise. + .Sh AVAILABILITY +diff --git a/man/rpc_gss_mech_to_oid.3t b/man/rpc_gss_mech_to_oid.3t +index 8bbe616..4a1b25d 100644 +--- a/man/rpc_gss_mech_to_oid.3t ++++ b/man/rpc_gss_mech_to_oid.3t +@@ -35,22 +35,27 @@ + .Ft bool_t + .Fn rpc_gss_mech_to_oid "const char *mech" "gss_OID *oid_ret" + .Sh DESCRIPTION +-This function looks up a mechanism by name by reading the file +-/etc/gss/mech. ++This function returns the GSS OID associated with the GSS_API ++mechanism "mech". + .Sh PARAMETERS + .Bl -tag -width ".It oid_ret" + .It mech +-The mechanism name to search for ++The name of a GSS_API mechanism. ++"kerberos_v5" is currently the only supported mechanism. + .It oid_ret +-If the mechanism is found, the corresponding GSS-API oid is returned +-in +-.Fa *oid_ret ++Buffer in which to place the returned OID + .El + .Sh RETURN VALUES +-If the mechanism is found, ++If the GSS_API mechanism name is recognized, + .Dv TRUE +-is returned, otherwise +-.Dv FALSE . ++is returned. ++The corresponding GSS-API oid is returned in ++.Fa *oid_ret . ++Otherwise ++.Dv FALSE ++is returned and ++.Fa *oid_ret ++is left untouched. + .Sh AVAILABILITY + The + .Fn rpc_gss_mech_to_oid +diff --git a/man/rpc_gss_qop_to_num.3t b/man/rpc_gss_qop_to_num.3t +index 3968216..7ac1a4c 100644 +--- a/man/rpc_gss_qop_to_num.3t ++++ b/man/rpc_gss_qop_to_num.3t +@@ -29,30 +29,37 @@ + .Os + .Sh NAME + .Nm rpc_gss_qop_to_num +-.Nd "Convert a quality of protection name to number" ++.Nd "Convert a Quality of Protection name to number" + .Sh SYNOPSIS + .In rpc/rpcsec_gss.h + .Ft bool_t + .Fn rpc_gss_qop_to_num "const char *qop" "const char *mech" "u_int *num_ret" + .Sh DESCRIPTION +-This function looks up a quality of protection by name by reading the file +-/etc/gss/qop. ++This function returns the numeric QOP value associated with the ++GSS_API QOP "qop" and mechanism "mech." + .Sh PARAMETERS + .Bl -tag -width ".It number_ret" + .It qop +-The quality of protection to search for ++The name of Quality of Protection associated with the ++GSS_API mechanism "mech". ++"GSS_C_QOP_DEFAULT" is currently the only supported QOP. + .It mech +-The mechanism name to search for ++The name of a GSS_API mechanism. ++"kerberos_v5" is currently the only supported mechanism. + .It number_ret +-If the quality of protection is found, the corresponding number is +-returned in +-.Fa *num_ret ++Buffer in which to place the returned QOP number + .El + .Sh RETURN VALUES +-If the value is found, ++If the QOP and mechanism names are recognized, + .Dv TRUE +-is returned, otherwise +-.Dv FALSE . ++is returned. ++The corresponding QOP number is returned in ++.Fa *num_ret . ++Otherwise ++.Dv FALSE ++is returned and ++.It number_ret ++is left untouched. + .Sh AVAILABILITY + The + .Fn rpc_gss_qop_to_num +diff --git a/man/rpc_gss_seccreate.3t b/man/rpc_gss_seccreate.3t +index 9f526a6..b52df19 100644 +--- a/man/rpc_gss_seccreate.3t ++++ b/man/rpc_gss_seccreate.3t +@@ -55,9 +55,8 @@ For instance, a principal such as + .Qq nfs@server.example.com + might be used by an application which needs to contact an NFS server + .It mechanism +-The desired mechanism for this security context. +-The value of mechanism should be the name of one of the security +-mechanisms listed in /etc/gss/mech. ++The name of the GSS_API mechanism to use for the new security context. ++"kerberos_v5" is currently the only supported mechanism. + .It service + Type of service requested. + .Bl -tag -width "rpc_gss_svc_integrity" +@@ -72,8 +71,9 @@ RPC headers and data are integrity protected by a checksum. + RPC headers are integrity protected by a checksum and data is encrypted. + .El + .It qop +-Desired quality of protection or NULL for the default. +-Available values are listed in /etc/gss/qop ++The name of the Quality of Protection to use for the new security context, ++or NULL to use the default QOP. ++"GSS_C_QOP_DEFAULT" is currently the only supported QOP. + .It options_req + Extra security context options to be passed to the underlying GSS-API + mechanism. +diff --git a/man/rpc_secure.3t b/man/rpc_secure.3t +index 7ad6e49..4a1ad93 100644 +--- a/man/rpc_secure.3t ++++ b/man/rpc_secure.3t +@@ -16,6 +16,14 @@ + .Fa "struct sockaddr *addr" + .Fa "des_block *ckey" + .Fc ++.Ft AUTH * ++.Fo authdes_pk_create ++.Fa "char *name" ++.FA "netobj *publickey" ++.Fa "unsigned window" ++.Fa "struct sockaddr *addr" ++.Fa "des_block *ckey" ++.Fc + .Ft int + .Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups" + .Ft int +@@ -113,6 +121,13 @@ key to be used for the encryption of credentials. + If it is supplied, however, then it will be used instead. + .Pp + The ++.Fn authdes_pk_create ++function is identical to ++.Fn authdes_create , ++except that the public key needs to be provided at calling time and ++will not looked up by this function itself. ++.Pp ++The + .Fn authdes_getucred + function, + the second of the two +diff --git a/src/Makefile.am b/src/Makefile.am +index 6cc567a..d94a8e9 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -12,36 +12,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/tirpc -include config.h -DPORTMAP -DINET6 \ + + lib_LTLIBRARIES = libtirpc.la + +-# +-# Set the library version information +-# +-# According to the libtool manual: +-# +-# "This flag accepts an argument of the form current[:revision[:age]]. +-# +-# If either revision or age are omitted, they default to 0. Also note that +-# age must be less than or equal to the current interface number. +-# +-# Here are a set of rules to help you update your library version information: +-# +-# 1. Start with version information of 0:0:0 for each libtool library. +-# 2. Update the version information only immediately before a public +-# release of your software. More frequent updates are unnecessary, +-# and only guarantee that the current interface number gets larger faster. +-# 3. If the library source code has changed at all since the last update, +-# then increment revision (c:r:a becomes c:r+1:a). +-# 4. If any interfaces have been added, removed, or changed since the last +-# update, increment current, and set revision to 0. +-# 5. If any interfaces have been added since the last public release, +-# then increment age. +-# 6. If any interfaces have been removed since the last public release, +-# then set age to 0. +-# +-# _Never_ try to set the interface numbers so that they correspond to the +-# release number of your package. This is an abuse that only fosters +-# misunderstanding of the purpose of library versions." +-# +-libtirpc_la_LDFLAGS = -lpthread -version-info 1:10:0 ++libtirpc_la_LDFLAGS = @LDFLAG_NOUNDEFINED@ -lpthread ++libtirpc_la_LDFLAGS += -version-info @LT_VERSION_INFO@ + + libtirpc_la_SOURCES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ + clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ +@@ -50,11 +22,12 @@ libtirpc_la_SOURCES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c cln + pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \ + rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \ + rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_auth_none.c \ ++ svc_auth_des.c \ + svc_generic.c svc_raw.c svc_run.c svc_simple.c svc_vc.c getpeereid.c \ + auth_time.c auth_des.c authdes_prot.c debug.c + + ## XDR +-libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c ++libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c xdr_sizeof.c + + if SYMVERS + libtirpc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libtirpc.map +@@ -69,7 +42,7 @@ if GSS + endif + + libtirpc_la_SOURCES += key_call.c key_prot_xdr.c getpublickey.c +-libtirpc_la_SOURCES += netname.c netnamer.c rtime.c ++libtirpc_la_SOURCES += netname.c netnamer.c rpcdname.c rtime.c + + CLEANFILES = cscope.* *~ + DISTCLEANFILES = Makefile.in +diff --git a/src/auth_gss.c b/src/auth_gss.c +index 722d54c..4fa8568 100644 +--- a/src/auth_gss.c ++++ b/src/auth_gss.c +@@ -821,7 +821,6 @@ rpc_gss_seccreate(CLIENT *clnt, char *principal, char *mechanism, + clnt->cl_auth = auth; + + if (_rpc_gss_refresh(auth, ret) == FALSE) { +- authgss_destroy(auth); + auth = NULL; + } else { + rpc_gss_clear_error(); +diff --git a/src/libtirpc.map b/src/libtirpc.map +index 063cddd..f385de5 100644 +--- a/src/libtirpc.map ++++ b/src/libtirpc.map +@@ -316,6 +316,17 @@ TIRPC_0.3.2 { + xdr_unixcred; + } TIRPC_0.3.1; + ++TIRPC_0.3.3 { ++ __getpublickey_LOCAL; ++ __key_decryptsession_pk_LOCAL; ++ __key_encryptsession_pk_LOCAL; ++ __key_gendes_LOCAL; ++ xdr_sizeof; ++ authdes_pk_create; ++ svc_pollfd; ++ svc_max_pollfd; ++} TIRPC_0.3.2; ++ + TIRPC_PRIVATE { + global: + __libc_clntudp_bufcreate; +diff --git a/src/rpc_com.h b/src/rpc_com.h +index 52a8c48..10bec79 100644 +--- a/src/rpc_com.h ++++ b/src/rpc_com.h +@@ -40,47 +40,20 @@ + #ifndef _TIRPC_RPCCOM_H + #define _TIRPC_RPCCOM_H + +- +-/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ +- +-/* +- * The max size of the transport, if the size cannot be determined +- * by other means. +- */ +-#define RPC_MAXDATASIZE 9000 +-#define RPC_MAXADDRSIZE 1024 +- +-#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ +- (u_int32_t)(now)->tv_usec) ++#include + + #ifdef __cplusplus + extern "C" { + #endif +-extern u_int __rpc_get_a_size(int); +-extern int __rpc_dtbsize(void); +-extern struct netconfig * __rpcgettp(int); +-extern int __rpc_get_default_domain(char **); +-struct netbuf *__rpc_set_netbuf(struct netbuf *, const void *, size_t); + +-char *__rpc_taddr2uaddr_af(int, const struct netbuf *); +-struct netbuf *__rpc_uaddr2taddr_af(int, const char *); +-int __rpc_fixup_addr(struct netbuf *, const struct netbuf *); +-int __rpc_sockinfo2netid(struct __rpc_sockinfo *, const char **); +-int __rpc_seman2socktype(int); +-int __rpc_socktype2seman(int); +-void *rpc_nullproc(CLIENT *); +-int __rpc_sockisbound(int); ++struct netbuf *__rpc_set_netbuf(struct netbuf *, const void *, size_t); + +-struct netbuf *__rpcb_findaddr(rpcprog_t, rpcvers_t, const struct netconfig *, +- const char *, CLIENT **); + struct netbuf *__rpcb_findaddr_timed(rpcprog_t, rpcvers_t, + const struct netconfig *, const char *host, CLIENT **clpp, + struct timeval *tp); + + bool_t __rpc_control(int,void *); + +-char *_get_next_token(char *, int); +- + bool_t __svc_clean_idle(fd_set *, int, bool_t); + bool_t __xdrrec_setnonblock(XDR *, int); + bool_t __xdrrec_getrec(XDR *, enum xprt_stat *, bool_t); +diff --git a/src/rpc_commondata.c b/src/rpc_commondata.c +index 5392306..918c1aa 100644 +--- a/src/rpc_commondata.c ++++ b/src/rpc_commondata.c +@@ -36,3 +36,6 @@ + struct opaque_auth _null_auth; + fd_set svc_fdset; + int svc_maxfd = -1; ++struct pollfd *svc_pollfd; ++int svc_max_pollfd; ++ +diff --git a/src/rpc_dtablesize.c b/src/rpc_dtablesize.c +index 5c6033e..13d320c 100644 +--- a/src/rpc_dtablesize.c ++++ b/src/rpc_dtablesize.c +@@ -50,8 +50,6 @@ _rpc_dtablesize(void) + + if (size == 0) { + size = getdtablesize(); +- if (size > FD_SETSIZE) +- size = FD_SETSIZE; + } + return (size); + } +diff --git a/src/rpc_gss_utils.c b/src/rpc_gss_utils.c +index 9a7fed3..80fc78a 100644 +--- a/src/rpc_gss_utils.c ++++ b/src/rpc_gss_utils.c +@@ -159,6 +159,7 @@ static char *_rpc_gss_krb5_qop_names[] = { + NULL, + }; + ++/* GSS_MECH_KRB5_OID: Defined by RFC 1964 */ + static struct _rpc_gss_mechanism _rpc_gss_mech_kerberos_v5 = { + .mi_name = "kerberos_v5", + .mi_oid = { 9, "\052\206\110\206\367\022\001\002\002" }, +@@ -166,8 +167,17 @@ static struct _rpc_gss_mechanism _rpc_gss_mech_kerberos_v5 = { + .mi_qops = _rpc_gss_krb5_qops, + }; + ++/* GSS_KRB5_NT_PRINCIPAL_NAME: Defined by RFC 1964 */ ++static struct _rpc_gss_mechanism _rpc_gss_mech_kerberos_v5_princname = { ++ .mi_name = "kerberos_v5", ++ .mi_oid = { 10, "\052\206\110\206\367\022\001\002\002\001" }, ++ .mi_qop_names = _rpc_gss_krb5_qop_names, ++ .mi_qops = _rpc_gss_krb5_qops, ++}; ++ + static struct _rpc_gss_mechanism *_rpc_gss_mechanisms[] = { + &_rpc_gss_mech_kerberos_v5, ++ &_rpc_gss_mech_kerberos_v5_princname, + NULL, + }; + +@@ -187,13 +197,20 @@ _rpc_gss_find_mechanism(char *mechanism) + return NULL; + } + ++static bool_t ++_rpc_gss_OID_equal(rpc_gss_OID o1, rpc_gss_OID o2) ++{ ++ return (o1->length == o2->length) && ++ (memcmp(o1->elements, o2->elements, o1->length) == 0); ++} ++ + static struct _rpc_gss_mechanism * + _rpc_gss_find_oid(rpc_gss_OID oid) + { + unsigned int i; + + for (i = 0; _rpc_gss_mechanisms[i] != NULL; i++) +- if (g_OID_equal(oid, &_rpc_gss_mechanisms[i]->mi_oid)) ++ if (_rpc_gss_OID_equal(oid, &_rpc_gss_mechanisms[i]->mi_oid)) + return _rpc_gss_mechanisms[i]; + return NULL; + } +diff --git a/src/rpc_soc.c b/src/rpc_soc.c +index e146ed4..1ec7b3f 100644 +--- a/src/rpc_soc.c ++++ b/src/rpc_soc.c +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + #include "rpc_com.h" + +@@ -531,7 +532,6 @@ authdes_create(servername, window, syncaddr, ckey) + struct sockaddr *syncaddr; /* optional hostaddr to sync with */ + des_block *ckey; /* optional conversation key to use */ + { +- AUTH *dummy; + AUTH *nauth; + char hostname[NI_MAXHOST]; + +@@ -540,19 +540,68 @@ authdes_create(servername, window, syncaddr, ckey) + * Change addr to hostname, because that is the way + * new interface takes it. + */ +- if (getnameinfo(syncaddr, sizeof(syncaddr), hostname, +- sizeof hostname, NULL, 0, 0) != 0) +- goto fallback; +- ++ switch (syncaddr->sa_family) { ++ case AF_INET: ++ if (getnameinfo(syncaddr, sizeof(struct sockaddr_in), hostname, ++ sizeof hostname, NULL, 0, 0) != 0) ++ goto fallback; ++ break; ++ case AF_INET6: ++ if (getnameinfo(syncaddr, sizeof(struct sockaddr_in6), hostname, ++ sizeof hostname, NULL, 0, 0) != 0) ++ goto fallback; ++ break; ++ default: ++ goto fallback; ++ } + nauth = authdes_seccreate(servername, window, hostname, ckey); + return (nauth); + } + fallback: +- dummy = authdes_seccreate(servername, window, NULL, ckey); +- return (dummy); ++ return authdes_seccreate(servername, window, NULL, ckey); + } + + /* ++ * Create the client des authentication object. Obsoleted by ++ * authdes_pk_seccreate(). ++ */ ++extern AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, ++ const des_block *, nis_server *); ++ ++AUTH * ++authdes_pk_create(servername, pkey, window, syncaddr, ckey) ++ char *servername; /* network name of server */ ++ netobj *pkey; /* public key */ ++ u_int window; /* time to live */ ++ struct sockaddr *syncaddr; /* optional hostaddr to sync with */ ++ des_block *ckey; /* optional conversation key to use */ ++{ ++ AUTH *nauth; ++ char hostname[NI_MAXHOST]; ++ ++ if (syncaddr) { ++ /* ++ * Change addr to hostname, because that is the way ++ * new interface takes it. ++ */ ++ switch (syncaddr->sa_family) { ++ case AF_INET: ++ if (getnameinfo(syncaddr, sizeof(struct sockaddr_in), hostname, ++ sizeof hostname, NULL, 0, 0) != 0) ++ goto fallback; ++ break; ++ default: ++ goto fallback; ++ } ++ nauth = authdes_pk_seccreate(servername, pkey, window, hostname, ckey, NULL); ++ return (nauth); ++ } ++fallback: ++ return authdes_pk_seccreate(servername, pkey, window, NULL, ckey, NULL); ++} ++ ++ ++/* + * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() + */ + CLIENT * +diff --git a/src/rpcdname.c b/src/rpcdname.c +new file mode 100644 +index 0000000..3e6a988 +--- /dev/null ++++ b/src/rpcdname.c +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (c) 2009, Sun Microsystems, Inc. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * - Redistributions of source code must retain the above copyright notice, ++ * this list of conditions and the following disclaimer. ++ * - Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * - Neither the name of Sun Microsystems, Inc. nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * rpcdname.c ++ * Gets the default domain name ++ */ ++ ++#include ++#include ++#include ++ ++static char *default_domain = 0; ++ ++static char * ++get_default_domain() ++{ ++ char temp[256]; ++ ++ if (default_domain) ++ return (default_domain); ++ if (getdomainname(temp, sizeof(temp)) < 0) ++ return (0); ++ if ((int) strlen(temp) > 0) { ++ default_domain = (char *)malloc((strlen(temp)+(unsigned)1)); ++ if (default_domain == 0) ++ return (0); ++ (void) strcpy(default_domain, temp); ++ return (default_domain); ++ } ++ return (0); ++} ++ ++/* ++ * This is a wrapper for the system call getdomainname which returns a ++ * ypclnt.h error code in the failure case. It also checks to see that ++ * the domain name is non-null, knowing that the null string is going to ++ * get rejected elsewhere in the NIS client package. ++ */ ++int ++__rpc_get_default_domain(domain) ++ char **domain; ++{ ++ if ((*domain = get_default_domain()) != 0) ++ return (0); ++ return (-1); ++} +diff --git a/src/svc.c b/src/svc.c +index 32c84f1..a4c6b3d 100644 +--- a/src/svc.c ++++ b/src/svc.c +@@ -100,16 +100,43 @@ xprt_register (xprt) + rwlock_wrlock (&svc_fd_lock); + if (__svc_xports == NULL) + { +- __svc_xports = (SVCXPRT **) mem_alloc (FD_SETSIZE * sizeof (SVCXPRT *)); ++ __svc_xports = (SVCXPRT **) calloc (_rpc_dtablesize(), sizeof (SVCXPRT *)); + if (__svc_xports == NULL) + return; +- memset (__svc_xports, '\0', FD_SETSIZE * sizeof (SVCXPRT *)); + } +- if (sock < FD_SETSIZE) ++ if (sock < _rpc_dtablesize()) + { ++ int i; ++ struct pollfd *new_svc_pollfd; ++ + __svc_xports[sock] = xprt; +- FD_SET (sock, &svc_fdset); +- svc_maxfd = max (svc_maxfd, sock); ++ if (sock < FD_SETSIZE) ++ { ++ FD_SET (sock, &svc_fdset); ++ svc_maxfd = max (svc_maxfd, sock); ++ } ++ ++ /* Check if we have an empty slot */ ++ for (i = 0; i < svc_max_pollfd; ++i) ++ if (svc_pollfd[i].fd == -1) ++ { ++ svc_pollfd[i].fd = sock; ++ svc_pollfd[i].events = (POLLIN | POLLPRI | ++ POLLRDNORM | POLLRDBAND); ++ return; ++ } ++ ++ new_svc_pollfd = (struct pollfd *) realloc (svc_pollfd, ++ sizeof (struct pollfd) ++ * (svc_max_pollfd + 1)); ++ if (new_svc_pollfd == NULL) /* Out of memory */ ++ return; ++ svc_pollfd = new_svc_pollfd; ++ ++svc_max_pollfd; ++ ++ svc_pollfd[svc_max_pollfd - 1].fd = sock; ++ svc_pollfd[svc_max_pollfd - 1].events = (POLLIN | POLLPRI | ++ POLLRDNORM | POLLRDBAND); + } + rwlock_unlock (&svc_fd_lock); + } +@@ -142,16 +169,25 @@ __xprt_do_unregister (xprt, dolock) + + if (dolock) + rwlock_wrlock (&svc_fd_lock); +- if ((sock < FD_SETSIZE) && (__svc_xports[sock] == xprt)) ++ if ((sock < _rpc_dtablesize() ) && (__svc_xports[sock] == xprt)) + { ++ int i; ++ + __svc_xports[sock] = NULL; +- FD_CLR (sock, &svc_fdset); +- if (sock >= svc_maxfd) ++ if (sock < FD_SETSIZE) + { +- for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--) +- if (__svc_xports[svc_maxfd]) +- break; ++ FD_CLR (sock, &svc_fdset); ++ if (sock >= svc_maxfd) ++ { ++ for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--) ++ if (__svc_xports[svc_maxfd]) ++ break; ++ } + } ++ ++ for (i = 0; i < svc_max_pollfd; ++i) ++ if (svc_pollfd[i].fd == sock) ++ svc_pollfd[i].fd = -1; + } + if (dolock) + rwlock_unlock (&svc_fd_lock); +@@ -606,11 +642,15 @@ svc_getreqset (readfds) + int bit, fd; + fd_mask mask, *maskp; + int sock; ++ int setsize; + + assert (readfds != NULL); + ++ setsize = _rpc_dtablesize (); ++ if (setsize > FD_SETSIZE) ++ setsize = FD_SETSIZE; + maskp = readfds->fds_bits; +- for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) ++ for (sock = 0; sock < setsize; sock += NFDBITS) + { + for (mask = *maskp++; (bit = ffsl(mask)) != 0; mask ^= (1L << (bit - 1))) + { +@@ -733,36 +773,22 @@ svc_getreq_poll (pfdp, pollretval) + struct pollfd *pfdp; + int pollretval; + { +- int i; +- int fds_found; ++ int fds_found, i; + +- for (i = fds_found = 0; fds_found < pollretval; i++) ++ for (i = fds_found = 0; i < svc_max_pollfd; ++i) + { + struct pollfd *p = &pfdp[i]; + +- if (p->revents) ++ if (p->fd != -1 && p->revents) + { +- /* fd has input waiting */ +- fds_found++; +- /* +- * We assume that this function is only called +- * via someone _select()ing from svc_fdset or +- * _poll()ing from svc_pollset[]. Thus it's safe +- * to handle the POLLNVAL event by simply turning +- * the corresponding bit off in svc_fdset. The +- * svc_pollset[] array is derived from svc_fdset +- * and so will also be updated eventually. +- * +- * XXX Should we do an xprt_unregister() instead? +- */ +- if (p->revents & POLLNVAL) +- { +- rwlock_wrlock (&svc_fd_lock); +- FD_CLR (p->fd, &svc_fdset); +- rwlock_unlock (&svc_fd_lock); +- } +- else +- svc_getreq_common (p->fd); ++ /* fd has input waiting */ ++ if (p->revents & POLLNVAL) ++ xprt_unregister (__svc_xports[p->fd]); ++ else ++ svc_getreq_common (p->fd); ++ ++ if (++fds_found >= pollretval) ++ break; + } + } + } +diff --git a/src/svc_auth.c b/src/svc_auth.c +index 31241c9..94029bb 100644 +--- a/src/svc_auth.c ++++ b/src/svc_auth.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -109,11 +110,9 @@ _gss_authenticate(rqst, msg, no_dispatch) + case AUTH_SHORT: + dummy = _svcauth_short(rqst, msg); + return (dummy); +-#ifdef DES_BUILTIN + case AUTH_DES: + dummy = _svcauth_des(rqst, msg); + return (dummy); +-#endif + #ifdef HAVE_RPCSEC_GSS + case RPCSEC_GSS: + dummy = _svcauth_gss(rqst, msg, no_dispatch); +@@ -172,9 +171,7 @@ svc_auth_reg(cred_flavor, handler) + case AUTH_NULL: + case AUTH_SYS: + case AUTH_SHORT: +-#ifdef DES_BUILTIN + case AUTH_DES: +-#endif + #ifdef HAVE_RPCSEC_GSS + case RPCSEC_GSS: + #endif +diff --git a/src/svc_auth_des.c b/src/svc_auth_des.c +index 08e2bee..5bc264c 100644 +--- a/src/svc_auth_des.c ++++ b/src/svc_auth_des.c +@@ -433,7 +433,6 @@ cache_spot(key, name, timestamp) + } + + +-#if (defined(sun) || defined(vax) || defined(__FreeBSD__)) + /* + * Local credential handling stuff. + * NOTE: bsd unix dependent. +@@ -528,5 +527,3 @@ invalidate(cred) + } + ((struct bsdcred *)cred)->grouplen = INVALID; + } +-#endif +- +diff --git a/src/svc_auth_gss.c b/src/svc_auth_gss.c +index 016357b..0206e5e 100644 +--- a/src/svc_auth_gss.c ++++ b/src/svc_auth_gss.c +@@ -235,28 +235,20 @@ static bool_t + _rpc_gss_fill_in_creds(struct svc_rpc_gss_data *gd, struct rpc_gss_cred *gc) + { + rpc_gss_rawcred_t *rcred = &gd->rcred; +- OM_uint32 maj_stat, min_stat; +- gss_buffer_desc buf; + + rcred->version = gc->gc_v; + if (!rpc_gss_oid_to_mech(gd->sec.mech, &rcred->mechanism)) + return FALSE; + rcred->service = _rpc_gss_svc_to_service(gd->sec.svc); +- maj_stat = gss_export_name(&min_stat, gd->client_name, &buf); +- if (maj_stat != GSS_S_COMPLETE) { +- gss_log_status("gss_export_name", maj_stat, min_stat); +- return FALSE; +- } + + rcred->client_principal = calloc(1, sizeof(rpc_gss_principal_t) + +- buf.length); +- if (rcred->client_principal == NULL) { +- (void)gss_release_buffer(&min_stat, &buf); ++ gd->cname.length); ++ if (rcred->client_principal == NULL) + return FALSE; +- } +- rcred->client_principal->len = buf.length; +- (void)memcpy(rcred->client_principal->name, buf.value, buf.length); +- (void)gss_release_buffer(&min_stat, &buf); ++ ++ rcred->client_principal->len = gd->cname.length; ++ (void)memcpy(rcred->client_principal->name, ++ gd->cname.value, gd->cname.length); + + rcred->svc_principal = _svcauth_svc_name; + +diff --git a/src/svc_generic.c b/src/svc_generic.c +index f49d776..7aae796 100644 +--- a/src/svc_generic.c ++++ b/src/svc_generic.c +@@ -283,6 +283,8 @@ svc_tli_create(fd, nconf, bindaddr, sendsz, recvsz) + xprt->xp_type = __rpc_socktype2seman(si.si_socktype); + + if (nconf) { ++ if (xprt->xp_netid != NULL) ++ free(xprt->xp_netid); + xprt->xp_netid = strdup(nconf->nc_netid); + xprt->xp_tp = strdup(nconf->nc_device); + } +diff --git a/src/svc_run.c b/src/svc_run.c +index 783b1dc..f40314b 100644 +--- a/src/svc_run.c ++++ b/src/svc_run.c +@@ -34,10 +34,11 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include ++ + + #include + #include "rpc_com.h" +@@ -46,33 +47,54 @@ + void + svc_run() + { +- fd_set readfds, cleanfds; +- struct timeval timeout; +- extern rwlock_t svc_fd_lock; ++ int i; ++ struct pollfd *my_pollfd = NULL; ++ int last_max_pollfd = 0; ++ ++ for (;;) { ++ int max_pollfd = svc_max_pollfd; ++ if (max_pollfd == 0 && svc_pollfd == NULL) ++ break; ++ ++ if (last_max_pollfd != max_pollfd) ++ { ++ struct pollfd *new_pollfd ++ = realloc (my_pollfd, sizeof (struct pollfd) * max_pollfd); ++ ++ if (new_pollfd == NULL) ++ { ++ warn ("svc_run: - out of memory"); ++ break; ++ } ++ ++ my_pollfd = new_pollfd; ++ last_max_pollfd = max_pollfd; ++ } ++ ++ for (i = 0; i < max_pollfd; ++i) ++ { ++ my_pollfd[i].fd = svc_pollfd[i].fd; ++ my_pollfd[i].events = svc_pollfd[i].events; ++ my_pollfd[i].revents = 0; ++ } + ++ switch (i = poll (my_pollfd, max_pollfd, -1)) ++ { ++ case -1: ++ if (errno == EINTR) ++ continue; ++ warn ("svc_run: - poll failed"); ++ break; ++ case 0: ++ continue; ++ default: ++ svc_getreq_poll (my_pollfd, i); ++ continue; ++ } ++ break; ++ } + +- for (;;) { +- rwlock_rdlock(&svc_fd_lock); +- readfds = svc_fdset; +- cleanfds = svc_fdset; +- rwlock_unlock(&svc_fd_lock); +- timeout.tv_sec = 30; +- timeout.tv_usec = 0; +- switch (select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { +- case -1: +- FD_ZERO(&readfds); +- if (errno == EINTR) { +- continue; +- } +- warn("svc_run: - select failed"); +- return; +- case 0: +- __svc_clean_idle(&cleanfds, 30, FALSE); +- continue; +- default: +- svc_getreqset(&readfds); +- } +- } ++ free (my_pollfd); + } + + /* +@@ -85,6 +107,8 @@ svc_exit() + extern rwlock_t svc_fd_lock; + + rwlock_wrlock(&svc_fd_lock); +- FD_ZERO(&svc_fdset); ++ free (svc_pollfd); ++ svc_pollfd = NULL; ++ svc_max_pollfd = 0; + rwlock_unlock(&svc_fd_lock); + } +diff --git a/src/svc_vc.c b/src/svc_vc.c +index 9824631..4bafbcf 100644 +--- a/src/svc_vc.c ++++ b/src/svc_vc.c +@@ -309,7 +309,6 @@ rendezvous_request(xprt, msg) + socklen_t len; + struct __rpc_sockinfo si; + SVCXPRT *newxprt; +- fd_set cleanfds; + + assert(xprt != NULL); + assert(msg != NULL); +@@ -321,13 +320,16 @@ again: + &len)) < 0) { + if (errno == EINTR) + goto again; +- /* +- * Clean out the most idle file descriptor when we're +- * running out. +- */ ++ + if (errno == EMFILE || errno == ENFILE) { +- cleanfds = svc_fdset; +- __svc_clean_idle(&cleanfds, 0, FALSE); ++ /* If there are no file descriptors available, then accept will fail. ++ We want to delay here so the connection request can be dequeued; ++ otherwise we can bounce between polling and accepting, never ++ giving the request a chance to dequeue and eating an enormous ++ amount of cpu time in svc_run if we're polling on many file ++ descriptors. */ ++ struct timespec ts = { .tv_sec = 0, .tv_nsec = 50000000 }; ++ nanosleep (&ts, NULL); + goto again; + } + return (FALSE); +@@ -337,6 +339,8 @@ again: + */ + + newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); ++ if (!newxprt) ++ return (FALSE); + + if (!__rpc_set_netbuf(&newxprt->xp_rtaddr, &addr, len)) + return (FALSE); +@@ -392,6 +396,12 @@ svc_vc_destroy(xprt) + __svc_vc_dodestroy(xprt); + } + ++static bool_t ++__svc_rendezvous_socket(xprt) ++ SVCXPRT *xprt; ++{ ++ return (xprt->xp_ops->xp_recv == rendezvous_request); ++} + static void + __svc_vc_dodestroy(xprt) + SVCXPRT *xprt; +@@ -403,7 +413,7 @@ __svc_vc_dodestroy(xprt) + + if (xprt->xp_fd != RPC_ANYFD) + (void)close(xprt->xp_fd); +- if (xprt->xp_port != 0) { ++ if (__svc_rendezvous_socket(xprt)) { + /* a rendezvouser socket */ + r = (struct cf_rendezvous *)xprt->xp_p1; + mem_free(r, sizeof (struct cf_rendezvous)); +@@ -786,47 +796,17 @@ __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) { + * rpcbind are known to call this function. Do not alter or remove this + * API without changing the library's sonum. + */ ++/* Since this is an exported interface used by rpcbind, we cannot ++ remove it. But since poll() can handle much more and much higher ++ file descriptors, this code doesn't really work anymore, too. ++ So for now, keep it as dummy function and do nothing to not break ++ existing binaries. If we have ported rpcbind to the poll() interface ++ and find out, that we really need this cleanup stuff (but nobody ++ besides FreeBSD has this), we need to re-implement it using poll(). ++ But this means a new function name with different parameters. For ++ ABI/API compatibility, we cannot reuse this one. */ + bool_t + __svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) + { +- int i, ncleaned; +- SVCXPRT *xprt, *least_active; +- struct timeval tv, tdiff, tmax; +- struct cf_conn *cd; +- +- gettimeofday(&tv, NULL); +- tmax.tv_sec = tmax.tv_usec = 0; +- least_active = NULL; +- rwlock_wrlock(&svc_fd_lock); +- for (i = ncleaned = 0; i <= svc_maxfd; i++) { +- if (FD_ISSET(i, fds)) { +- xprt = __svc_xports[i]; +- if (xprt == NULL || xprt->xp_ops == NULL || +- xprt->xp_ops->xp_recv != svc_vc_recv) +- continue; +- cd = (struct cf_conn *)xprt->xp_p1; +- if (!cleanblock && !cd->nonblock) +- continue; +- if (timeout == 0) { +- timersub(&tv, &cd->last_recv_time, &tdiff); +- if (timercmp(&tdiff, &tmax, >)) { +- tmax = tdiff; +- least_active = xprt; +- } +- continue; +- } +- if (tv.tv_sec - cd->last_recv_time.tv_sec > timeout) { +- __xprt_unregister_unlocked(xprt); +- __svc_vc_dodestroy(xprt); +- ncleaned++; +- } +- } +- } +- if (timeout == 0 && least_active != NULL) { +- __xprt_unregister_unlocked(least_active); +- __svc_vc_dodestroy(least_active); +- ncleaned++; +- } +- rwlock_unlock(&svc_fd_lock); +- return ncleaned > 0 ? TRUE : FALSE; ++ return FALSE; + } +diff --git a/src/xdr_sizeof.c b/src/xdr_sizeof.c +index cc5414b..d23fbd1 100644 +--- a/src/xdr_sizeof.c ++++ b/src/xdr_sizeof.c +@@ -90,7 +90,7 @@ x_inline(xdrs, len) + if (xdrs->x_op != XDR_ENCODE) { + return (NULL); + } +- if (len < (u_int)xdrs->x_base) { ++ if (len < (uintptr_t)xdrs->x_base) { + /* x_private was already allocated */ + xdrs->x_handy += len; + return ((int32_t *) xdrs->x_private); +@@ -102,7 +102,7 @@ x_inline(xdrs, len) + xdrs->x_base = 0; + return (NULL); + } +- xdrs->x_base = (caddr_t) len; ++ xdrs->x_base = (caddr_t)(uintptr_t)len; + xdrs->x_handy += len; + return ((int32_t *) xdrs->x_private); + } +diff --git a/tirpc/rpc/auth.h b/tirpc/rpc/auth.h +index 3e44863..e67779c 100644 +--- a/tirpc/rpc/auth.h ++++ b/tirpc/rpc/auth.h +@@ -313,6 +313,8 @@ extern AUTH *authnone_create(void); /* takes no parameters */ + extern "C" { + #endif + extern AUTH *authdes_create (char *, u_int, struct sockaddr *, des_block *); ++extern AUTH *authdes_pk_create (char *, netobj *, u_int, ++ struct sockaddr *, des_block *); + extern AUTH *authdes_seccreate (const char *, const u_int, const char *, + const des_block *); + #ifdef __cplusplus +diff --git a/tirpc/rpc/auth_gss.h b/tirpc/rpc/auth_gss.h +index a17b34b..5316ed6 100644 +--- a/tirpc/rpc/auth_gss.h ++++ b/tirpc/rpc/auth_gss.h +@@ -73,11 +73,6 @@ struct authgss_private_data { + u_int pd_seq_win; /* Sequence window */ + }; + +-#define g_OID_equal(o1, o2) \ +- (((o1)->length == (o2)->length) && \ +- ((o1)->elements != 0) && ((o2)->elements != 0) && \ +- (memcmp((o1)->elements, (o2)->elements, (int) (o1)->length) == 0)) +- + /* from kerberos source, gssapi_krb5.c */ + extern gss_OID_desc krb5oid; + extern gss_OID_desc spkm3oid; +diff --git a/tirpc/rpc/svc.h b/tirpc/rpc/svc.h +index 8273c95..1ab6527 100644 +--- a/tirpc/rpc/svc.h ++++ b/tirpc/rpc/svc.h +@@ -88,6 +88,7 @@ enum xprt_stat { + */ + typedef struct __rpc_svcxprt { + int xp_fd; ++#define xp_sock xp_fd + u_short xp_port; /* associated port number */ + const struct xp_ops { + /* receive incoming requests */ +@@ -314,12 +315,10 @@ extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, + * dynamic; must be inspected before each call to select + */ + extern int svc_maxfd; +-#ifdef FD_SETSIZE + extern fd_set svc_fdset; + #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +-#else +-extern int svc_fds; +-#endif /* def FD_SETSIZE */ ++extern struct pollfd *svc_pollfd; ++extern int svc_max_pollfd; + + /* + * a small program implemented by the svc_rpc implementation itself; +diff --git a/tirpc/rpc/xdr.h b/tirpc/rpc/xdr.h +index 64069ab..80b35ce 100644 +--- a/tirpc/rpc/xdr.h ++++ b/tirpc/rpc/xdr.h +@@ -327,6 +327,7 @@ extern bool_t xdr_hyper(XDR *, quad_t *); + extern bool_t xdr_u_hyper(XDR *, u_quad_t *); + extern bool_t xdr_longlong_t(XDR *, quad_t *); + extern bool_t xdr_u_longlong_t(XDR *, u_quad_t *); ++extern u_long xdr_sizeof(xdrproc_t, void *); + #ifdef __cplusplus + } + #endif diff --git a/libtirpc.spec b/libtirpc.spec index 27c1a76..7b94935 100644 --- a/libtirpc.spec +++ b/libtirpc.spec @@ -2,7 +2,7 @@ Name: libtirpc Version: 0.3.2 -Release: 2.0%{?dist} +Release: 3.0%{?dist} Summary: Transport Independent RPC Library Group: System Environment/Libraries License: SISSL and BSD @@ -10,7 +10,7 @@ URL: http://nfsv4.bullopensource.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Source0: http://downloads.sourceforge.net/libtirpc/libtirpc-%{version}.tar.bz2 -Patch001: libtirpc-0.3.3-rc2.patch +Patch001: libtirpc-0.3.3-rc3.patch BuildRequires: automake, autoconf, libtool, pkgconfig BuildRequires: krb5-devel @@ -134,6 +134,9 @@ rm -rf %{buildroot} %{_mandir}/*/* %changelog +* Fri Aug 28 2015 Steve Dickson 0.3.2-3.0 +- Updated to latest upstream release: libtirpc-0-3-3-rc3 + * Fri Jul 10 2015 Steve Dickson 0.3.2-2.0 - Updated to latest upstream release: libtirpc-0-3-3-rc2