diff options
author | Matthew N. Dodd <matthew.nygard.dodd@gmail.com> | 2011-06-20 13:42:18 -0400 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2011-06-20 13:42:18 -0400 |
commit | a17307911da331e8bf2a0ac94a3a37cc35a06767 (patch) | |
tree | a7c0c81f4ccc9f3ff4a5f69d77794c7a0e44de30 | |
parent | e716edbbed160423624f6c2f745debf10aad279b (diff) | |
download | ti-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.c | 1 | ||||
-rw-r--r-- | src/auth_gss.c | 2 | ||||
-rw-r--r-- | src/auth_unix.c | 1 | ||||
-rw-r--r-- | tirpc/rpc/auth.h | 35 |
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, \ |