]> granicus.if.org Git - libtirpc/commitdiff
Reference count AUTHs
authorMatthew N. Dodd <matthew.nygard.dodd@gmail.com>
Mon, 20 Jun 2011 17:42:18 +0000 (13:42 -0400)
committerSteve Dickson <steved@redhat.com>
Tue, 21 Jun 2011 18:31:45 +0000 (14:31 -0400)
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>
src/auth_des.c
src/auth_gss.c
src/auth_unix.c
tirpc/rpc/auth.h

index 829c8172e087076e43beb17091f13bd0b4fb5735..f0c8b8c831f3a57ee1e9ad4addb75302a9339a27 100644 (file)
@@ -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:
index df3017a2462adfc6c8718cab3b1a5a3256fcd230..98f03413e27d247da20cbc45baf6f10c727230c9 100644 (file)
@@ -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;
 
index 5b8990ffd1d50d12d1dda9347fcfa455dfddb29b..4b9b13fd6a4c5d84a6dbdfc5b3c67106a88ac378 100644 (file)
@@ -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:
index f669ae48d9318de9783fcb92f31584826032b2b4..5f66e67d328e10af280e14a05dcf61bc5bc687c4 100644 (file)
@@ -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, \