a457fa9765
Signed-off-by: Steve Dickson <steved@redhat.com>
1289 lines
39 KiB
Diff
1289 lines
39 KiB
Diff
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 <rpc/rpc_com.h>
|
|
|
|
#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 <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
+#include <rpcsvc/nis.h>
|
|
|
|
#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 <stdlib.h>
|
|
+#include <unistd.h>
|
|
+#include <string.h>
|
|
+
|
|
+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 <reentrant.h>
|
|
#include <sys/types.h>
|
|
#include <rpc/rpc.h>
|
|
+#include <rpc/auth_des.h>
|
|
#include <stdlib.h>
|
|
|
|
/*
|
|
@@ -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 <reentrant.h>
|
|
#include <err.h>
|
|
#include <errno.h>
|
|
-#include <rpc/rpc.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
+#include <sys/poll.h>
|
|
+
|
|
|
|
#include <rpc/rpc.h>
|
|
#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
|