Updated to latest RC release: libtirpc-0-2-2-rc2 [bz 519430]

This commit is contained in:
Steve Dickson 2010-05-19 00:06:10 +00:00
parent d0331caa9f
commit e13a1fa345
3 changed files with 698 additions and 316 deletions

View File

@ -1,314 +0,0 @@
commit 599511589ca7ddb3b2eac8d3aa5b0b38be7a7691
Author: Jeff Layton <jlayton@redhat.com>
Date: Fri Mar 5 14:27:13 2010 -0500
libtirpc: allow larger ticket sizes with RPCSEC_GSS
libtirpc currently limits RPCSEC_GSS args to MAX_NETOBJ_SZ (1024) bytes.
This causes problems when you try to use large krb5 tickets, such as
those handed out by MS' Active Directory when the user has a large PAC.
This patch backports a set of changes from librpcsecgss which fixed this
problem there. It declares a new routine specifically for encoding
gss_buffer_t's and has the various auth_gss routines use that instead of
calling xdr_bytes directly.
An RPC_SLACK_SPACE constant is defined and added to the buffer length to
get a max buffer length to pass to xdr_rpc_gss_buf for the appropriate
callers.
This seems to fix the bug reported here:
https://bugzilla.redhat.com/show_bug.cgi?id=562807
Reported-by: Michael Young <m.a.young@durham.ac.uk>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/src/authgss_prot.c b/src/authgss_prot.c
index ab72d91..9d7fa09 100644
--- a/src/authgss_prot.c
+++ b/src/authgss_prot.c
@@ -44,6 +44,34 @@
#include <rpc/rpc.h>
#include <gssapi/gssapi.h>
+/* additional space needed for encoding */
+#define RPC_SLACK_SPACE 1024
+
+bool_t
+xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
+{
+ bool_t xdr_stat;
+ u_int tmplen;
+
+ if (xdrs->x_op != XDR_DECODE) {
+ if (buf->length > UINT_MAX)
+ return FALSE;
+ else
+ tmplen = buf->length;
+ }
+ xdr_stat = xdr_bytes(xdrs, (char **)&buf->value, &tmplen, maxsize);
+
+ if (xdr_stat && xdrs->x_op == XDR_DECODE)
+ buf->length = tmplen;
+
+ log_debug("xdr_rpc_gss_buf: %s %s (%p:%d)",
+ (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
+ (xdr_stat == TRUE) ? "success" : "failure",
+ buf->value, buf->length);
+
+ return xdr_stat;
+}
+
bool_t
xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
{
@@ -53,8 +81,7 @@ xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
xdr_enum(xdrs, (enum_t *)&p->gc_proc) &&
xdr_u_int(xdrs, &p->gc_seq) &&
xdr_enum(xdrs, (enum_t *)&p->gc_svc) &&
- xdr_bytes(xdrs, (char **)&p->gc_ctx.value,
- (u_int *)&p->gc_ctx.length, MAX_AUTH_BYTES));
+ xdr_rpc_gss_buf(xdrs, &p->gc_ctx, MAX_AUTH_BYTES));
log_debug("xdr_rpc_gss_cred: %s %s "
"(v %d, proc %d, seq %d, svc %d, ctx %p:%d)",
@@ -70,9 +97,9 @@ bool_t
xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p)
{
bool_t xdr_stat;
+ u_int maxlen = (u_int)(p->length + RPC_SLACK_SPACE);
- xdr_stat = xdr_bytes(xdrs, (char **)&p->value,
- (u_int *)&p->length, MAX_NETOBJ_SZ);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, p, maxlen);
log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%d)",
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
@@ -87,13 +114,14 @@ xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p)
{
bool_t xdr_stat;
- xdr_stat = (xdr_bytes(xdrs, (char **)&p->gr_ctx.value,
- (u_int *)&p->gr_ctx.length, MAX_NETOBJ_SZ) &&
+ u_int ctx_maxlen = (u_int)(p->gr_ctx.length + RPC_SLACK_SPACE);
+ u_int tok_maxlen = (u_int)(p->gr_token.length + RPC_SLACK_SPACE);
+
+ xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, ctx_maxlen) &&
xdr_u_int(xdrs, &p->gr_major) &&
xdr_u_int(xdrs, &p->gr_minor) &&
xdr_u_int(xdrs, &p->gr_win) &&
- xdr_bytes(xdrs, (char **)&p->gr_token.value,
- (u_int *)&p->gr_token.length, MAX_NETOBJ_SZ));
+ xdr_rpc_gss_buf(xdrs, &p->gr_token, tok_maxlen));
log_debug("xdr_rpc_gss_init_res %s %s "
"(ctx %p:%d, maj %d, min %d, win %d, token %p:%d)",
@@ -115,28 +143,33 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
OM_uint32 maj_stat, min_stat;
int start, end, conf_state;
bool_t xdr_stat;
+ u_int databuflen, maxwrapsz;
/* Skip databody length. */
start = XDR_GETPOS(xdrs);
XDR_SETPOS(xdrs, start + 4);
+ memset(&databuf, 0, sizeof(databuf));
+ memset(&wrapbuf, 0, sizeof(wrapbuf));
+
/* Marshal rpc_gss_data_t (sequence number + arguments). */
if (!xdr_u_int(xdrs, &seq) || !(*xdr_func)(xdrs, xdr_ptr))
return (FALSE);
end = XDR_GETPOS(xdrs);
/* Set databuf to marshalled rpc_gss_data_t. */
- databuf.length = end - start - 4;
+ databuflen = end - start - 4;
XDR_SETPOS(xdrs, start + 4);
- databuf.value = XDR_INLINE(xdrs, databuf.length);
+ databuf.value = XDR_INLINE(xdrs, databuflen);
xdr_stat = FALSE;
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Marshal databody_integ length. */
XDR_SETPOS(xdrs, start);
- if (!xdr_u_int(xdrs, (u_int *)&databuf.length))
+ if (!xdr_u_int(xdrs, (u_int *)&databuflen))
return (FALSE);
+ databuf.length = databuflen;
/* Checksum rpc_gss_data_t. */
maj_stat = gss_get_mic(&min_stat, ctx, qop,
@@ -147,8 +180,8 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
/* Marshal checksum. */
XDR_SETPOS(xdrs, end);
- xdr_stat = xdr_bytes(xdrs, (char **)&wrapbuf.value,
- (u_int *)&wrapbuf.length, MAX_NETOBJ_SZ);
+ maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
gss_release_buffer(&min_stat, &wrapbuf);
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
@@ -161,8 +194,8 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
/* Marshal databody_priv. */
XDR_SETPOS(xdrs, start);
- xdr_stat = xdr_bytes(xdrs, (char **)&wrapbuf.value,
- (u_int *)&wrapbuf.length, MAX_NETOBJ_SZ);
+ maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
gss_release_buffer(&min_stat, &wrapbuf);
}
return (xdr_stat);
@@ -188,14 +221,12 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Decode databody_integ. */
- if (!xdr_bytes(xdrs, (char **)&databuf.value, (u_int *)&databuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) {
log_debug("xdr decode databody_integ failed");
return (FALSE);
}
/* Decode checksum. */
- if (!xdr_bytes(xdrs, (char **)&wrapbuf.value, (u_int *)&wrapbuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
gss_release_buffer(&min_stat, &databuf);
log_debug("xdr decode checksum failed");
return (FALSE);
@@ -213,8 +244,7 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
/* Decode databody_priv. */
- if (!xdr_bytes(xdrs, (char **)&wrapbuf.value, (u_int *)&wrapbuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
log_debug("xdr decode databody_priv failed");
return (FALSE);
}
commit 89323aafc77e1a40800332fb135888782b1bfee6
Author: Jeff Layton <jlayton@redhat.com>
Date: Fri Mar 5 12:55:31 2010 -0500
libtirpc: don't call abort() in the AUTH_UNIX creation codepaths
When there are problems creating an AUTH_UNIX auth handle, libtirpc will
sometimes call abort(). It's bad for a library to do this since
decisions about how to handle errors are better left up to the
application and abort() generally causes the app to crash and dump core.
Make it so that these functions return NULL instead in these situations.
authunix_create already returns NULL for other error conditions so it
seems like an appropriate way to handle errors in these codepaths.
Have authunix_create and authunix_create_default set appropriate errors
in the rpc_createerr struct. It seems a little odd to do this since
rpc_createerr is supposed to report information about why CLIENT
creation failed, and the problem here is in creating an AUTH handle.
authgss_create does this already however, so there is some precedent.
While we're at it, it's also bad for libraries to log to stderr. It's
possible that a daemon is calling here and it has closed stderr and is
resuing fd 2 for something else. Rip out the warnx calls from these two
functions to make sure that they don't cause problems.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/src/auth_unix.c b/src/auth_unix.c
index 71ca15d..ddd89cc 100644
--- a/src/auth_unix.c
+++ b/src/auth_unix.c
@@ -49,7 +49,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
+#include <rpc/clnt.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
@@ -95,6 +97,8 @@ authunix_create(machname, uid, gid, len, aup_gids)
AUTH *auth;
struct audata *au;
+ memset(&rpc_createerr, 0, sizeof(rpc_createerr));
+
/*
* Allocate and set up auth handle
*/
@@ -102,14 +106,16 @@ authunix_create(machname, uid, gid, len, aup_gids)
auth = mem_alloc(sizeof(*auth));
#ifndef _KERNEL
if (auth == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
au = mem_alloc(sizeof(*au));
#ifndef _KERNEL
if (au == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
@@ -134,15 +140,18 @@ authunix_create(machname, uid, gid, len, aup_gids)
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
- if (! xdr_authunix_parms(&xdrs, &aup))
- abort();
+ if (!xdr_authunix_parms(&xdrs, &aup)) {
+ rpc_createerr.cf_stat = RPC_CANTENCODEARGS;
+ goto cleanup_authunix_create;
+ }
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
#ifdef _KERNEL
au->au_origcred.oa_base = mem_alloc((u_int) len);
#else
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
@@ -180,13 +189,22 @@ authunix_create_default()
gid_t gid;
gid_t gids[NGRPS];
- if (gethostname(machname, sizeof machname) == -1)
- abort();
+ memset(&rpc_createerr, 0, sizeof(rpc_createerr));
+
+ if (gethostname(machname, sizeof machname) == -1) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ return NULL;
+ }
machname[sizeof(machname) - 1] = 0;
uid = geteuid();
gid = getegid();
- if ((len = getgroups(NGRPS, gids)) < 0)
- abort();
+ len = getgroups(NGRPS, gids);
+ if (len < 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ return NULL;
+ }
/* XXX: interface problem; those should all have been unsigned */
return (authunix_create(machname, uid, gid, len, gids));
}

692
libtirpc-0-2-2-rc2.patch Normal file
View File

@ -0,0 +1,692 @@
diff --git a/.gitignore b/.gitignore
index f4a325a..a5a8f11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ ltmain.sh
Makefile.in
missing
config.h.in
+m4/*
# files generated by configure
confdefs.h
config.status
diff --git a/Makefile.am b/Makefile.am
index 7f5f37b..1a7596b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,5 @@
SUBDIRS = src man doc
+ACLOCAL_AMFLAGS = -I m4
nobase_include_HEADERS = tirpc/netconfig.h \
tirpc/rpcsvc/crypt.x \
diff --git a/configure.ac b/configure.ac
index 0f3ce42..34dc080 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,6 +2,7 @@ AC_INIT(libtirpc, 0.2.1)
AM_INIT_AUTOMAKE(libtirpc, 0.2.1)
AM_MAINTAINER_MODE
AC_CONFIG_SRCDIR([src/auth_des.c])
+AC_CONFIG_MACRO_DIR([m4])
AC_ARG_ENABLE(gss,[ --enable-gss Turn on gss api], [case "${enableval}" in
yes) gss=true ; AC_CHECK_LIB([gssapi],[gss_init_sec_context]) ;;
@@ -18,7 +19,6 @@ fi
AC_PROG_CC
AM_CONFIG_HEADER(config.h)
AC_PROG_LIBTOOL
-##AC_PROG_RANLIB
AC_HEADER_DIRENT
AC_PREFIX_DEFAULT(/usr)
AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h locale.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h])
diff --git a/src/auth_unix.c b/src/auth_unix.c
index 71ca15d..ddd89cc 100644
--- a/src/auth_unix.c
+++ b/src/auth_unix.c
@@ -49,7 +49,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
+#include <rpc/clnt.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
@@ -95,6 +97,8 @@ authunix_create(machname, uid, gid, len, aup_gids)
AUTH *auth;
struct audata *au;
+ memset(&rpc_createerr, 0, sizeof(rpc_createerr));
+
/*
* Allocate and set up auth handle
*/
@@ -102,14 +106,16 @@ authunix_create(machname, uid, gid, len, aup_gids)
auth = mem_alloc(sizeof(*auth));
#ifndef _KERNEL
if (auth == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
au = mem_alloc(sizeof(*au));
#ifndef _KERNEL
if (au == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
@@ -134,15 +140,18 @@ authunix_create(machname, uid, gid, len, aup_gids)
* Serialize the parameters into origcred
*/
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
- if (! xdr_authunix_parms(&xdrs, &aup))
- abort();
+ if (!xdr_authunix_parms(&xdrs, &aup)) {
+ rpc_createerr.cf_stat = RPC_CANTENCODEARGS;
+ goto cleanup_authunix_create;
+ }
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_UNIX;
#ifdef _KERNEL
au->au_origcred.oa_base = mem_alloc((u_int) len);
#else
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
- warnx("authunix_create: out of memory");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = ENOMEM;
goto cleanup_authunix_create;
}
#endif
@@ -180,13 +189,22 @@ authunix_create_default()
gid_t gid;
gid_t gids[NGRPS];
- if (gethostname(machname, sizeof machname) == -1)
- abort();
+ memset(&rpc_createerr, 0, sizeof(rpc_createerr));
+
+ if (gethostname(machname, sizeof machname) == -1) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ return NULL;
+ }
machname[sizeof(machname) - 1] = 0;
uid = geteuid();
gid = getegid();
- if ((len = getgroups(NGRPS, gids)) < 0)
- abort();
+ len = getgroups(NGRPS, gids);
+ if (len < 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ return NULL;
+ }
/* XXX: interface problem; those should all have been unsigned */
return (authunix_create(machname, uid, gid, len, gids));
}
diff --git a/src/authgss_prot.c b/src/authgss_prot.c
index ab72d91..9d7fa09 100644
--- a/src/authgss_prot.c
+++ b/src/authgss_prot.c
@@ -44,6 +44,34 @@
#include <rpc/rpc.h>
#include <gssapi/gssapi.h>
+/* additional space needed for encoding */
+#define RPC_SLACK_SPACE 1024
+
+bool_t
+xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
+{
+ bool_t xdr_stat;
+ u_int tmplen;
+
+ if (xdrs->x_op != XDR_DECODE) {
+ if (buf->length > UINT_MAX)
+ return FALSE;
+ else
+ tmplen = buf->length;
+ }
+ xdr_stat = xdr_bytes(xdrs, (char **)&buf->value, &tmplen, maxsize);
+
+ if (xdr_stat && xdrs->x_op == XDR_DECODE)
+ buf->length = tmplen;
+
+ log_debug("xdr_rpc_gss_buf: %s %s (%p:%d)",
+ (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
+ (xdr_stat == TRUE) ? "success" : "failure",
+ buf->value, buf->length);
+
+ return xdr_stat;
+}
+
bool_t
xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
{
@@ -53,8 +81,7 @@ xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
xdr_enum(xdrs, (enum_t *)&p->gc_proc) &&
xdr_u_int(xdrs, &p->gc_seq) &&
xdr_enum(xdrs, (enum_t *)&p->gc_svc) &&
- xdr_bytes(xdrs, (char **)&p->gc_ctx.value,
- (u_int *)&p->gc_ctx.length, MAX_AUTH_BYTES));
+ xdr_rpc_gss_buf(xdrs, &p->gc_ctx, MAX_AUTH_BYTES));
log_debug("xdr_rpc_gss_cred: %s %s "
"(v %d, proc %d, seq %d, svc %d, ctx %p:%d)",
@@ -70,9 +97,9 @@ bool_t
xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p)
{
bool_t xdr_stat;
+ u_int maxlen = (u_int)(p->length + RPC_SLACK_SPACE);
- xdr_stat = xdr_bytes(xdrs, (char **)&p->value,
- (u_int *)&p->length, MAX_NETOBJ_SZ);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, p, maxlen);
log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%d)",
(xdrs->x_op == XDR_ENCODE) ? "encode" : "decode",
@@ -87,13 +114,14 @@ xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p)
{
bool_t xdr_stat;
- xdr_stat = (xdr_bytes(xdrs, (char **)&p->gr_ctx.value,
- (u_int *)&p->gr_ctx.length, MAX_NETOBJ_SZ) &&
+ u_int ctx_maxlen = (u_int)(p->gr_ctx.length + RPC_SLACK_SPACE);
+ u_int tok_maxlen = (u_int)(p->gr_token.length + RPC_SLACK_SPACE);
+
+ xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, ctx_maxlen) &&
xdr_u_int(xdrs, &p->gr_major) &&
xdr_u_int(xdrs, &p->gr_minor) &&
xdr_u_int(xdrs, &p->gr_win) &&
- xdr_bytes(xdrs, (char **)&p->gr_token.value,
- (u_int *)&p->gr_token.length, MAX_NETOBJ_SZ));
+ xdr_rpc_gss_buf(xdrs, &p->gr_token, tok_maxlen));
log_debug("xdr_rpc_gss_init_res %s %s "
"(ctx %p:%d, maj %d, min %d, win %d, token %p:%d)",
@@ -115,28 +143,33 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
OM_uint32 maj_stat, min_stat;
int start, end, conf_state;
bool_t xdr_stat;
+ u_int databuflen, maxwrapsz;
/* Skip databody length. */
start = XDR_GETPOS(xdrs);
XDR_SETPOS(xdrs, start + 4);
+ memset(&databuf, 0, sizeof(databuf));
+ memset(&wrapbuf, 0, sizeof(wrapbuf));
+
/* Marshal rpc_gss_data_t (sequence number + arguments). */
if (!xdr_u_int(xdrs, &seq) || !(*xdr_func)(xdrs, xdr_ptr))
return (FALSE);
end = XDR_GETPOS(xdrs);
/* Set databuf to marshalled rpc_gss_data_t. */
- databuf.length = end - start - 4;
+ databuflen = end - start - 4;
XDR_SETPOS(xdrs, start + 4);
- databuf.value = XDR_INLINE(xdrs, databuf.length);
+ databuf.value = XDR_INLINE(xdrs, databuflen);
xdr_stat = FALSE;
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Marshal databody_integ length. */
XDR_SETPOS(xdrs, start);
- if (!xdr_u_int(xdrs, (u_int *)&databuf.length))
+ if (!xdr_u_int(xdrs, (u_int *)&databuflen))
return (FALSE);
+ databuf.length = databuflen;
/* Checksum rpc_gss_data_t. */
maj_stat = gss_get_mic(&min_stat, ctx, qop,
@@ -147,8 +180,8 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
/* Marshal checksum. */
XDR_SETPOS(xdrs, end);
- xdr_stat = xdr_bytes(xdrs, (char **)&wrapbuf.value,
- (u_int *)&wrapbuf.length, MAX_NETOBJ_SZ);
+ maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
gss_release_buffer(&min_stat, &wrapbuf);
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
@@ -161,8 +194,8 @@ xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
/* Marshal databody_priv. */
XDR_SETPOS(xdrs, start);
- xdr_stat = xdr_bytes(xdrs, (char **)&wrapbuf.value,
- (u_int *)&wrapbuf.length, MAX_NETOBJ_SZ);
+ maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE);
+ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz);
gss_release_buffer(&min_stat, &wrapbuf);
}
return (xdr_stat);
@@ -188,14 +221,12 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Decode databody_integ. */
- if (!xdr_bytes(xdrs, (char **)&databuf.value, (u_int *)&databuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) {
log_debug("xdr decode databody_integ failed");
return (FALSE);
}
/* Decode checksum. */
- if (!xdr_bytes(xdrs, (char **)&wrapbuf.value, (u_int *)&wrapbuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
gss_release_buffer(&min_stat, &databuf);
log_debug("xdr decode checksum failed");
return (FALSE);
@@ -213,8 +244,7 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
/* Decode databody_priv. */
- if (!xdr_bytes(xdrs, (char **)&wrapbuf.value, (u_int *)&wrapbuf.length,
- MAX_NETOBJ_SZ)) {
+ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
log_debug("xdr decode databody_priv failed");
return (FALSE);
}
diff --git a/src/rpc_generic.c b/src/rpc_generic.c
index 541275c..509fb36 100644
--- a/src/rpc_generic.c
+++ b/src/rpc_generic.c
@@ -523,7 +523,7 @@ __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
}
int
-__rpc_nconf2fd(const struct netconfig *nconf)
+__rpc_nconf2fd_flags(const struct netconfig *nconf, int flags)
{
struct __rpc_sockinfo si;
int fd;
@@ -531,7 +531,7 @@ __rpc_nconf2fd(const struct netconfig *nconf)
if (!__rpc_nconf2sockinfo(nconf, &si))
return 0;
- if ((fd = socket(si.si_af, si.si_socktype, si.si_proto)) >= 0 &&
+ if ((fd = socket(si.si_af, si.si_socktype | flags, si.si_proto)) >= 0 &&
si.si_af == AF_INET6) {
int val = 1;
@@ -541,6 +541,12 @@ __rpc_nconf2fd(const struct netconfig *nconf)
}
int
+__rpc_nconf2fd(const struct netconfig *nconf)
+{
+ return __rpc_nconf2fd_flags(nconf, 0);
+}
+
+int
__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
{
int i;
diff --git a/src/rpc_soc.c b/src/rpc_soc.c
index 709a8a8..c678429 100644
--- a/src/rpc_soc.c
+++ b/src/rpc_soc.c
@@ -60,13 +60,14 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
#include "rpc_com.h"
extern mutex_t rpcsoc_lock;
static CLIENT *clnt_com_create(struct sockaddr_in *, rpcprog_t, rpcvers_t,
- int *, u_int, u_int, char *);
+ int *, u_int, u_int, char *, int);
static SVCXPRT *svc_com_create(int, u_int, u_int, char *);
static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *);
@@ -78,7 +79,7 @@ static bool_t rpc_wrap_bcast(char *, struct netbuf *, struct netconfig *);
* A common clnt create routine
*/
static CLIENT *
-clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
+clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp, flags)
struct sockaddr_in *raddr;
rpcprog_t prog;
rpcvers_t vers;
@@ -86,6 +87,7 @@ clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
u_int sendsz;
u_int recvsz;
char *tp;
+ int flags;
{
CLIENT *cl;
int madefd = FALSE;
@@ -100,9 +102,21 @@ clnt_com_create(raddr, prog, vers, sockp, sendsz, recvsz, tp)
return (NULL);
}
if (fd == RPC_ANYSOCK) {
- fd = __rpc_nconf2fd(nconf);
- if (fd == -1)
- goto syserror;
+ static int have_cloexec;
+ fd = __rpc_nconf2fd_flags(nconf, flags);
+ if (fd == -1) {
+ if ((flags & SOCK_CLOEXEC) && have_cloexec <= 0) {
+ fd = __rpc_nconf2fd(nconf);
+ if (fd == -1)
+ goto syserror;
+ if (flags & SOCK_CLOEXEC) {
+ have_cloexec = -1;
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ }
+ } else
+ goto syserror;
+ } else if (flags & SOCK_CLOEXEC)
+ have_cloexec = 1;
madefd = TRUE;
}
@@ -154,6 +168,28 @@ err: if (madefd == TRUE)
}
CLIENT *
+__libc_clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz, flags)
+ struct sockaddr_in *raddr;
+ u_long prog;
+ u_long vers;
+ struct timeval wait;
+ int *sockp;
+ u_int sendsz;
+ u_int recvsz;
+ int flags;
+{
+ CLIENT *cl;
+
+ cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
+ sendsz, recvsz, "udp", flags);
+ if (cl == NULL) {
+ return (NULL);
+ }
+ (void) CLNT_CONTROL(cl, CLSET_RETRY_TIMEOUT, &wait);
+ return (cl);
+}
+
+CLIENT *
clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
struct sockaddr_in *raddr;
u_long prog;
@@ -166,7 +202,7 @@ clntudp_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
CLIENT *cl;
cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "udp");
+ sendsz, recvsz, "udp", 0);
if (cl == NULL) {
return (NULL);
}
@@ -195,7 +231,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
u_int recvsz;
{
return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "tcp");
+ sendsz, recvsz, "tcp", 0);
}
/* IPv6 version of clnt*_*create */
@@ -215,7 +251,7 @@ clntudp6_bufcreate(raddr, prog, vers, wait, sockp, sendsz, recvsz)
CLIENT *cl;
cl = clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "udp6");
+ sendsz, recvsz, "udp6", 0);
if (cl == NULL) {
return (NULL);
}
@@ -244,7 +280,7 @@ clnttcp6_create(raddr, prog, vers, sockp, sendsz, recvsz)
u_int recvsz;
{
return clnt_com_create(raddr, (rpcprog_t)prog, (rpcvers_t)vers, sockp,
- sendsz, recvsz, "tcp6");
+ sendsz, recvsz, "tcp6", 0);
}
#endif
diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c
index 4a3e96c..218ff7c 100644
--- a/src/rpcb_clnt.c
+++ b/src/rpcb_clnt.c
@@ -56,6 +56,7 @@
#include <unistd.h>
#include <netdb.h>
#include <syslog.h>
+#include <assert.h>
#include "rpc_com.h"
@@ -211,14 +212,12 @@ add_cache(host, netid, taddr, uaddr)
ad_cache->ac_uaddr = uaddr ? strdup(uaddr) : NULL;
ad_cache->ac_taddr = (struct netbuf *)malloc(sizeof (struct netbuf));
if (!ad_cache->ac_host || !ad_cache->ac_netid || !ad_cache->ac_taddr ||
- (uaddr && !ad_cache->ac_uaddr)) {
- return;
- }
+ (uaddr && !ad_cache->ac_uaddr))
+ goto out_free;
ad_cache->ac_taddr->len = ad_cache->ac_taddr->maxlen = taddr->len;
ad_cache->ac_taddr->buf = (char *) malloc(taddr->len);
- if (ad_cache->ac_taddr->buf == NULL) {
- return;
- }
+ if (ad_cache->ac_taddr->buf == NULL)
+ goto out_free;
memcpy(ad_cache->ac_taddr->buf, taddr->buf, taddr->len);
#ifdef ND_DEBUG
fprintf(stderr, "Added to cache: %s : %s\n", host, netid);
@@ -262,6 +261,14 @@ add_cache(host, netid, taddr, uaddr)
free(cptr);
}
rwlock_unlock(&rpcbaddr_cache_lock);
+ return;
+
+out_free:
+ free(ad_cache->ac_host);
+ free(ad_cache->ac_netid);
+ free(ad_cache->ac_uaddr);
+ free(ad_cache->ac_taddr);
+ free(ad_cache);
}
/*
@@ -289,6 +296,8 @@ getclnthandle(host, nconf, targaddr)
/* Get the address of the rpcbind. Check cache first */
client = NULL;
+ if (targaddr)
+ *targaddr = NULL;
addr_to_delete.len = 0;
rwlock_rdlock(&rpcbaddr_cache_lock);
ad_cache = NULL;
@@ -325,7 +334,8 @@ getclnthandle(host, nconf, targaddr)
}
if (!__rpc_nconf2sockinfo(nconf, &si)) {
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
- return NULL;
+ assert(client == NULL);
+ goto out_err;
}
memset(&hints, 0, sizeof hints);
@@ -344,7 +354,7 @@ getclnthandle(host, nconf, targaddr)
#ifdef ND_DEBUG
clnt_pcreateerror("rpcbind clnt interface");
#endif
- return (NULL);
+ goto out_err;
} else {
struct sockaddr_un sun;
@@ -356,7 +366,8 @@ getclnthandle(host, nconf, targaddr)
} else {
if (getaddrinfo(host, "sunrpc", &hints, &res) != 0) {
rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
- return NULL;
+ assert(client == NULL);
+ goto out_err;
}
}
@@ -404,6 +415,9 @@ getclnthandle(host, nconf, targaddr)
}
if (res)
freeaddrinfo(res);
+out_err:
+ if (!client && targaddr)
+ free(*targaddr);
return (client);
}
diff --git a/src/svc.c b/src/svc.c
index cc65e6a..b4a63d0 100644
--- a/src/svc.c
+++ b/src/svc.c
@@ -615,7 +615,7 @@ svc_getreqset (readfds)
maskp = readfds->fds_bits;
for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS)
{
- for (mask = *maskp++; (bit = ffs (mask)) != 0; mask ^= (1 << (bit - 1)))
+ for (mask = *maskp++; (bit = ffsl(mask)) != 0; mask ^= (1L << (bit - 1)))
{
/* sock has input waiting */
fd = sock + bit - 1;
diff --git a/src/svc_vc.c b/src/svc_vc.c
index 8e39597..aaaf2d7 100644
--- a/src/svc_vc.c
+++ b/src/svc_vc.c
@@ -748,6 +748,10 @@ __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid) {
* Destroy xprts that have not have had any activity in 'timeout' seconds.
* If 'cleanblock' is true, blocking connections (the default) are also
* cleaned. If timeout is 0, the least active connection is picked.
+ *
+ * Though this is not a publicly documented interface, some versions of
+ * rpcbind are known to call this function. Do not alter or remove this
+ * API without changing the library's sonum.
*/
bool_t
__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock)
diff --git a/tirpc/rpc/auth_des.h b/tirpc/rpc/auth_des.h
index f3f9f31..39b5332 100644
--- a/tirpc/rpc/auth_des.h
+++ b/tirpc/rpc/auth_des.h
@@ -84,7 +84,7 @@ struct authdes_verf {
struct timeval adv_ctime; /* clear time */
des_block adv_xtime; /* crypt time */
} adv_time_u;
- //u_long adv_int_u;
+ /*u_long adv_int_u;*/
u_int32_t adv_int_u;
};
diff --git a/tirpc/rpc/clnt.h b/tirpc/rpc/clnt.h
index 0b26189..e7bb43f 100644
--- a/tirpc/rpc/clnt.h
+++ b/tirpc/rpc/clnt.h
@@ -42,8 +42,7 @@
#ifndef _TIRPC_CLNT_H_
#define _TIRPC_CLNT_H_
-//#include <rpc/clnt_stat.h>
-#include "clnt_stat.h"
+#include <rpc/clnt_stat.h>
#include <rpc/auth.h>
#include <sys/cdefs.h>
diff --git a/tirpc/rpc/rpc.h b/tirpc/rpc/rpc.h
index 29e29e9..6c0222e 100644
--- a/tirpc/rpc/rpc.h
+++ b/tirpc/rpc/rpc.h
@@ -101,6 +101,7 @@ __END_DECLS
*/
__BEGIN_DECLS
int __rpc_nconf2fd(const struct netconfig *);
+int __rpc_nconf2fd_flags(const struct netconfig *, int);
int __rpc_nconf2sockinfo(const struct netconfig *, struct __rpc_sockinfo *);
int __rpc_fd2sockinfo(int, struct __rpc_sockinfo *);
u_int __rpc_get_t_size(int, int, int);
diff --git a/tirpc/rpc/rpcent.h b/tirpc/rpc/rpcent.h
index 1d83550..7fd93d9 100644
--- a/tirpc/rpc/rpcent.h
+++ b/tirpc/rpc/rpcent.h
@@ -44,23 +44,27 @@
/* #pragma ident "@(#)rpcent.h 1.13 94/04/25 SMI" */
/* @(#)rpcent.h 1.1 88/12/06 SMI */
+__BEGIN_DECLS
-//struct rpcent {
-// char *r_name; /* name of server for this rpc program */
-// char **r_aliases; /* alias list */
-// int r_number; /* rpc program number */
-//};
+/* These are defined in /usr/include/rpc/netdb.h */
+#if 0
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
-__BEGIN_DECLS
-//extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *,
-// char *, int);
-//extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int);
-//extern struct rpcent *getrpcent_r(struct rpcent *, char *, int);
+extern struct rpcent *getrpcbyname_r(const char *, struct rpcent *,
+ char *, int);
+extern struct rpcent *getrpcbynumber_r(int, struct rpcent *, char *, int);
+extern struct rpcent *getrpcent_r(struct rpcent *, char *, int);
/* Old interfaces that return a pointer to a static area; MT-unsafe */
-//extern struct rpcent *getrpcbyname(char *);
-//extern struct rpcent *getrpcbynumber(int);
-//extern struct rpcent *getrpcent(void);
+extern struct rpcent *getrpcbyname(char *);
+extern struct rpcent *getrpcbynumber(int);
+extern struct rpcent *getrpcent(void);
+#endif
+
extern void setrpcent(int) __THROW;
extern void endrpcent(void) __THROW;
__END_DECLS
diff --git a/tirpc/rpc/types.h b/tirpc/rpc/types.h
index d99a57b..52c30a2 100644
--- a/tirpc/rpc/types.h
+++ b/tirpc/rpc/types.h
@@ -39,7 +39,6 @@
#define _TIRPC_TYPES_H
#include <sys/types.h>
-//#include <sys/_null.h>
typedef int32_t bool_t;
typedef int32_t enum_t;
diff --git a/tirpc/rpc/xdr.h b/tirpc/rpc/xdr.h
index 3a6bc96..2c2a860 100644
--- a/tirpc/rpc/xdr.h
+++ b/tirpc/rpc/xdr.h
@@ -43,7 +43,7 @@
#include <sys/cdefs.h>
#include <stdio.h>
#include <netinet/in.h>
-// Rajout pour la définition des types
+
#include <rpc/types.h>
/*

View File

@ -1,12 +1,12 @@
Name: libtirpc
Version: 0.2.1
Release: 2%{?dist}
Release: 3%{?dist}
Summary: Transport Independent RPC Library
Group: System Environment/Libraries
License: SISSL and BSD
URL: http://nfsv4.bullopensource.org/
Patch001: libtirpc-0-2-2-rc1.patch
Patch001: libtirpc-0-2-2-rc2.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Source0: http://downloads.sourceforge.net/libtirpc/libtirpc-%{version}.tar.bz2
@ -46,6 +46,7 @@ developing programs which use the tirpc library.
find . -name "*.orig" | xargs rm -f
%build
sh autogen.sh
autoreconf -fisv
%configure --enable-gss
make all
@ -125,6 +126,9 @@ rm -rf %{buildroot}
%{_mandir}/*/*
%changelog
* Tue May 18 2010 Steve Dickson <steved@redhat.com> 0.2.1-3
- Updated to latest RC release: libtirpc-0-2-2-rc2 [bz 519430]
* Mon Mar 22 2010 Steve Dickson <steved@redhat.com> 0.2.1-2
- Updated to latest RC release: libtirpc-0-2-2-rc1