summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew N. Dodd <matthew.nygard.dodd@gmail.com>2011-06-20 13:42:18 -0400
committerSteve Dickson <steved@redhat.com>2011-06-20 13:42:18 -0400
commita17307911da331e8bf2a0ac94a3a37cc35a06767 (patch)
treea7c0c81f4ccc9f3ff4a5f69d77794c7a0e44de30
parente716edbbed160423624f6c2f745debf10aad279b (diff)
downloadti-rpc-a17307911da331e8bf2a0ac94a3a37cc35a06767.tar.gz
Reference count AUTHs
RPCSEC GSSv3 has the concept of a parent and a compound credential. As the normal course of operation involves using multiple AUTHs per client connection, and providing parent and compounds AUTHs when creating a GSSv3 AUTH, we need a way of reference counting them so that AUTH_DESTROY does not free them out from under a GSSv3 AUTH that is using them. Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--src/auth_des.c1
-rw-r--r--src/auth_gss.c2
-rw-r--r--src/auth_unix.c1
-rw-r--r--tirpc/rpc/auth.h35
4 files changed, 35 insertions, 4 deletions
diff --git a/src/auth_des.c b/src/auth_des.c
index 829c817..f0c8b8c 100644
--- a/src/auth_des.c
+++ b/src/auth_des.c
@@ -223,6 +223,7 @@ authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
goto failed;
}
ad->ad_nis_srvr = NULL; /* not needed any longer */
+ auth_get(auth); /* Reference for caller */
return (auth);
failed:
diff --git a/src/auth_gss.c b/src/auth_gss.c
index df3017a..98f0341 100644
--- a/src/auth_gss.c
+++ b/src/auth_gss.c
@@ -200,6 +200,8 @@ authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec)
if (!authgss_refresh(auth))
auth = NULL;
+ else
+ auth_get(auth); /* Reference for caller */
clnt->cl_auth = save_auth;
diff --git a/src/auth_unix.c b/src/auth_unix.c
index 5b8990f..4b9b13f 100644
--- a/src/auth_unix.c
+++ b/src/auth_unix.c
@@ -162,6 +162,7 @@ authunix_create(machname, uid, gid, len, aup_gids)
*/
auth->ah_cred = au->au_origcred;
marshal_new_auth(auth);
+ auth_get(auth); /* Reference for caller */
return (auth);
#ifndef _KERNEL
cleanup_authunix_create:
diff --git a/tirpc/rpc/auth.h b/tirpc/rpc/auth.h
index f669ae4..5f66e67 100644
--- a/tirpc/rpc/auth.h
+++ b/tirpc/rpc/auth.h
@@ -203,8 +203,22 @@ typedef struct __auth {
} *ah_ops;
void *ah_private;
+ int ah_refcnt;
} AUTH;
+static __inline int
+auth_get(AUTH *auth)
+{
+ return __sync_add_and_fetch(&auth->ah_refcnt, 1);
+}
+
+static __inline int
+auth_put(AUTH *auth)
+{
+ return __sync_sub_and_fetch(&auth->ah_refcnt, 1);
+}
+
+
/*
* Authentication ops.
@@ -234,10 +248,23 @@ typedef struct __auth {
#define auth_refresh(auth, msg) \
((*((auth)->ah_ops->ah_refresh))(auth, msg))
-#define AUTH_DESTROY(auth) \
- ((*((auth)->ah_ops->ah_destroy))(auth))
-#define auth_destroy(auth) \
- ((*((auth)->ah_ops->ah_destroy))(auth))
+#define AUTH_DESTROY(auth) \
+ do { \
+ int refs; \
+ if ((refs = auth_put((auth))) == 0) \
+ ((*((auth)->ah_ops->ah_destroy))(auth));\
+ log_debug("%s: auth_put(), refs %d\n", \
+ __func__, refs); \
+ } while (0)
+
+#define auth_destroy(auth) \
+ do { \
+ int refs; \
+ if ((refs = auth_put((auth))) == 0) \
+ ((*((auth)->ah_ops->ah_destroy))(auth));\
+ log_debug("%s: auth_put(), refs %d\n", \
+ __func__, refs); \
+ } while (0)
#define AUTH_WRAP(auth, xdrs, xfunc, xwhere) \
((*((auth)->ah_ops->ah_wrap))(auth, xdrs, \