This commit updates lib/krb5/ccache/ccapi to support CCAPI Version 3
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 22 Jun 2006 16:57:14 +0000 (16:57 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 22 Jun 2006 16:57:14 +0000 (16:57 +0000)
and above.  Specify -DUSE_CCAPI_V3=1 when compiling to use CCAPI Version 3

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/ccapi@18193 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/ccache/ccapi/stdcc.c
src/lib/krb5/ccache/ccapi/stdcc.h
src/lib/krb5/ccache/ccapi/stdcc_util.c
src/lib/krb5/ccache/ccapi/stdcc_util.h
src/lib/krb5/ccache/ccapi/winccld.h

index 885abf5bb7b5dd3c296a0153669dd1545606130d..ace8958544338f5ef60e96d9cbbb9f42015f535e 100644 (file)
@@ -3,8 +3,9 @@
  *      credentical cache API
  *     
  * Written by Frank Dabek July 1998
+ * Updated by Jeffrey Altman June 2006
  *
- * Copyright 1998, 1999 by the Massachusetts Institute of Technology.
+ * Copyright 1998, 1999, 2006 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
  * 
  */
 
-#define NEED_WINDOWS
 #include "k5-int.h"
 #include "stdcc.h"
 #include "stdcc_util.h"
 #include "string.h"
 #include <stdio.h>
 
-apiCB *gCntrlBlock = NULL;
-
 #if defined(_WIN32)
 #include "winccld.h"   
 #endif
@@ -56,14 +54,37 @@ apiCB *gCntrlBlock = NULL;
 #define SHOW_DEBUG(buf)
 #endif
 
+#ifdef USE_CCAPI_V3
+cc_context_t gCntrlBlock = NULL;
+#else
+apiCB *gCntrlBlock = NULL;
+#endif
+
 /*
  * declare our global object wanna-be
  * must be installed in ccdefops.c
  */
 
 krb5_cc_ops krb5_cc_stdcc_ops = {
-     0,
-     "API",
+      0,
+      "API",
+#ifdef USE_CCAPI_V3
+      krb5_stdccv3_get_name,
+      krb5_stdccv3_resolve,
+      krb5_stdccv3_generate_new,
+      krb5_stdccv3_initialize,
+      krb5_stdccv3_destroy,
+      krb5_stdccv3_close,
+      krb5_stdccv3_store,
+      krb5_stdccv3_retrieve,
+      krb5_stdccv3_get_principal,
+      krb5_stdccv3_start_seq_get,
+      krb5_stdccv3_next_cred,
+      krb5_stdccv3_end_seq_get,
+      krb5_stdccv3_remove, 
+      krb5_stdccv3_set_flags,
+      krb5_stdccv3_get_flags
+#else
       krb5_stdcc_get_name,
       krb5_stdcc_resolve,
       krb5_stdcc_generate_new,
@@ -78,7 +99,8 @@ krb5_cc_ops krb5_cc_stdcc_ops = {
       krb5_stdcc_end_seq_get,
       krb5_stdcc_remove, 
       krb5_stdcc_set_flags,
-      krb5_stdcc_get_flags,
+      krb5_stdcc_get_flags
+#endif
 };
 
 #if defined(_WIN32)
@@ -114,6 +136,36 @@ struct err_xlate
 
 static const struct err_xlate err_xlate_table[] =
 {
+#ifdef USE_CCAPI_V3
+        { ccIteratorEnd,                       KRB5_CC_END },
+        { ccErrBadParam,                       KRB5_FCC_INTERNAL },
+        { ccErrNoMem,                          KRB5_CC_NOMEM },
+        { ccErrInvalidContext,                         KRB5_FCC_INTERNAL },
+        { ccErrInvalidCCache,                  KRB5_FCC_INTERNAL },
+        { ccErrInvalidString,                  KRB5_FCC_INTERNAL },
+        { ccErrInvalidCredentials,             KRB5_FCC_INTERNAL },
+        { ccErrInvalidCCacheIterator,          KRB5_FCC_INTERNAL },
+        { ccErrInvalidCredentialsIterator,     KRB5_FCC_INTERNAL },
+        { ccErrInvalidLock,                    KRB5_FCC_INTERNAL },
+        { ccErrBadName,                                KRB5_CC_BADNAME },
+        { ccErrBadCredentialsVersion,          KRB5_FCC_INTERNAL },
+        { ccErrBadAPIVersion,                  KRB5_FCC_INTERNAL },
+        { ccErrContextLocked,                  KRB5_FCC_INTERNAL },
+        { ccErrContextUnlocked,                        KRB5_FCC_INTERNAL },
+        { ccErrCCacheLocked,                   KRB5_FCC_INTERNAL },
+        { ccErrCCacheUnlocked,                 KRB5_FCC_INTERNAL },
+        { ccErrBadLockType,                    KRB5_FCC_INTERNAL },
+        { ccErrNeverDefault,                   KRB5_FCC_INTERNAL },
+        { ccErrCredentialsNotFound,            KRB5_CC_NOTFOUND },
+        { ccErrCCacheNotFound,                 KRB5_FCC_NOFILE },
+        { ccErrContextNotFound,                        KRB5_FCC_INTERNAL },
+        { ccErrServerUnavailable,              KRB5_FCC_NOFILE },
+        { ccErrServerInsecure,                 KRB5_FCC_INTERNAL },
+        { ccErrServerCantBecomeUID,            KRB5_FCC_INTERNAL },
+        { ccErrTimeOffsetNotSet,               KRB5_FCC_INTERNAL },
+        { ccErrBadInternalMessage,             KRB5_FCC_INTERNAL },
+        { ccErrNotImplemented,                 KRB5_FCC_INTERNAL },
+#else
        { CC_BADNAME,                           KRB5_CC_BADNAME },
        { CC_NOTFOUND,                          KRB5_CC_NOTFOUND },
        { CC_END,                               KRB5_CC_END },
@@ -131,6 +183,7 @@ static const struct err_xlate err_xlate_table[] =
        { CC_ERR_CACHE_RELEASE,                 KRB5_FCC_INTERNAL /* XXX */ },
        { CC_ERR_CACHE_FULL,                    KRB5_FCC_INTERNAL /* XXX */ },
        { CC_ERR_CRED_VERSION,                  KRB5_FCC_INTERNAL /* XXX */ },
+#endif
        { 0,                                    0 }
 };
 
@@ -138,7 +191,7 @@ static krb5_error_code cc_err_xlate(int err)
 {
        const struct err_xlate *p;
 
-       if (err == CC_NOERROR)
+       if (err == ccNoError)
                return 0;
 
        for (p = err_xlate_table; p->cc_err; p++) {
@@ -148,6 +201,536 @@ static krb5_error_code cc_err_xlate(int err)
        return KRB5_FCC_INTERNAL; /* XXX we need a miscellaneous return */
 }
 
+
+#ifdef USE_CCAPI_V3
+static krb5_error_code stdccv3_setup(krb5_context context,
+                                    stdccCacheDataPtr ccapi_data)
+{
+       cc_int32        err;
+
+       /* make sure the API has been intialized */
+       if (gCntrlBlock == NULL) {
+               err = cc_initialize(&gCntrlBlock, ccapi_version_max, NULL, NULL);
+               if (err != ccNoError)
+                       return cc_err_xlate(err);
+       }
+
+       /*
+        * No ccapi_data structure, so we don't need to make sure the
+        * ccache exists.
+        */
+       if (!ccapi_data)
+               return 0;
+
+       /*
+        * The ccache already exists
+        */
+       if (ccapi_data->NamedCache)
+               return 0;
+
+       err = cc_context_open_ccache(gCntrlBlock, ccapi_data->cache_name,
+                     &ccapi_data->NamedCache);
+       if (err == ccNoError)
+               return 0;
+
+       ccapi_data->NamedCache = NULL;
+       return cc_err_xlate(err);
+}
+
+void krb5_stdccv3_shutdown()
+{
+       if (gCntrlBlock)
+               cc_context_release(gCntrlBlock);
+       gCntrlBlock = NULL;
+}
+
+/*
+ * -- generate_new --------------------------------
+ * 
+ * create a new cache with a unique name, corresponds to creating a
+ * named cache initialize the API here if we have to.
+ */
+krb5_error_code KRB5_CALLCONV  krb5_stdccv3_generate_new 
+       (krb5_context context, krb5_ccache *id ) 
+{
+       krb5_ccache             newCache = NULL;
+       krb5_error_code         retval;
+       stdccCacheDataPtr       ccapi_data = NULL;
+       char                    *name = NULL;
+       cc_time                 time;
+       int                     err;
+
+       if ((retval = stdccv3_setup(context, NULL)))
+               return retval;
+       
+       retval = KRB5_CC_NOMEM;
+       if (!(newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache))))
+               goto errout;
+       if (!(ccapi_data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData))))
+               goto errout;
+       if (!(name = malloc(256)))
+               goto errout;
+       
+       /* create a unique name */
+       if (retval = cc_context_get_change_time(gCntrlBlock, &time))
+               goto errout;
+       sprintf(name, "gen_new_cache%d", time);
+       
+       /* create the new cache */
+       err = cc_context_create_ccache(gCntrlBlock, name, cc_credentials_v5, 0L,
+                       &ccapi_data->NamedCache);
+       if (err != ccNoError) {
+               retval = cc_err_xlate(err);
+               goto errout;
+       }
+
+       /* setup some fields */
+       newCache->ops = &krb5_cc_stdcc_ops;
+       newCache->data = ccapi_data;
+       ccapi_data->cache_name = name;
+       
+       /* return a pointer to the new cache */
+       *id = newCache;
+               
+       return 0;
+
+errout:
+       if (newCache)
+               free(newCache);
+       if (ccapi_data)
+               free(ccapi_data);
+       if (name)
+               free(name);
+       return retval;
+}
+  
+/*
+ * resolve
+ *
+ * create a new cache with the name stored in residual
+ */
+krb5_error_code KRB5_CALLCONV  krb5_stdccv3_resolve 
+        (krb5_context context, krb5_ccache *id , const char *residual ) 
+{
+       krb5_ccache             newCache = NULL;
+       stdccCacheDataPtr       ccapi_data = NULL;
+       int                     err;
+       krb5_error_code         retval;
+       char                    *cName = NULL;
+       
+       if ((retval = stdccv3_setup(context, NULL)))
+               return retval;
+       
+       retval = KRB5_CC_NOMEM;
+       if (!(newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache))))
+               goto errout;
+       
+       if (!(ccapi_data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData))))
+               goto errout;
+
+       if (!(cName = malloc(strlen(residual)+1)))
+               goto errout;
+       
+       newCache->ops = &krb5_cc_stdcc_ops;
+       newCache->data = ccapi_data;
+       ccapi_data->cache_name = cName;
+
+       strcpy(cName, residual);
+       
+       err = cc_context_open_ccache(gCntrlBlock, cName,
+                                    &ccapi_data->NamedCache);
+        if (err != ccNoError) {
+               ccapi_data->NamedCache = NULL;
+               goto errout;
+       }
+
+       /* return new cache structure */
+       *id = newCache;
+       
+       return 0;
+       
+errout:
+       if (newCache)
+               free(newCache);
+       if (ccapi_data)
+               free(ccapi_data);
+       if (cName)
+               free(cName);
+       return retval;
+}
+  
+/*
+ * initialize
+ *
+ * initialize the cache, check to see if one already exists for this
+ * principal if not set our principal to this principal. This
+ * searching enables ticket sharing
+ */
+krb5_error_code KRB5_CALLCONV  krb5_stdccv3_initialize 
+       (krb5_context context, krb5_ccache id,  krb5_principal princ) 
+{
+       stdccCacheDataPtr       ccapi_data = NULL;
+       int                     err;
+       char                    *cName = NULL;
+       krb5_error_code         retval;
+       
+       if ((retval = stdccv3_setup(context, NULL)))
+               return retval;
+       
+       /* test id for null */
+       if (id == NULL) return KRB5_CC_NOMEM;
+       
+       if ((retval = krb5_unparse_name(context, princ, &cName)))
+               return retval;
+
+       ccapi_data = id->data;
+
+
+        if (ccapi_data->NamedCache) {
+               err = cc_ccache_release(ccapi_data->NamedCache);
+               ccapi_data->NamedCache = NULL;
+       }
+
+       err = cc_context_create_ccache(gCntrlBlock, ccapi_data->cache_name, 
+                                      cc_credentials_v5, cName,
+                                      &ccapi_data->NamedCache);
+       if (err != ccNoError) {
+               krb5_free_unparsed_name(context, cName);
+               return cc_err_xlate(err);
+       }
+
+       krb5_free_unparsed_name(context, cName);
+       cache_changed();
+       
+       return cc_err_xlate(err);
+}
+
+/*
+ * store
+ *
+ * store some credentials in our cache
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_store 
+        (krb5_context context, krb5_ccache id, krb5_creds *creds )
+{
+       krb5_error_code         retval;
+       stdccCacheDataPtr       ccapi_data = id->data;
+       cc_credentials_t        c = NULL;
+       int err;
+
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+       
+       /* copy the fields from the almost identical structures */
+       dupK5toCC3(context, creds, &c);
+                       
+       /*
+        * finally store the credential
+        * store will copy (that is duplicate) everything
+        */
+       err = cc_ccache_store_credentials(((stdccCacheDataPtr)(id->data))->NamedCache, c->data);
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+             
+       err = cc_credentials_release(c);
+                
+       cache_changed();
+       return err;
+}
+
+/*
+ * start_seq_get
+ *
+ * begin an iterator call to get all of the credentials in the cache
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_start_seq_get 
+(krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor )
+{
+       stdccCacheDataPtr               ccapi_data = id->data;
+       krb5_error_code                 retval;
+       int                             err;
+       cc_credentials_iterator_t       iterator;
+
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+
+       err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache,
+                                                &iterator);
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+       *cursor = iterator;
+       return 0;
+}
+
+/*
+ * next cred
+ * 
+ * - get the next credential in the cache as part of an iterator call
+ * - this maps to call to cc_seq_fetch_creds
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred 
+        (krb5_context context, krb5_ccache id,  krb5_cc_cursor *cursor, 
+        krb5_creds *creds)
+{
+       krb5_error_code                 retval;
+       stdccCacheDataPtr               ccapi_data = id->data;
+       int                             err;
+       cc_credentials_t                cu;
+       cc_credentials_iterator_t       iterator;
+       
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+       
+       iterator = *cursor;
+       if (iterator == 0)
+               return KRB5_CC_END;
+       err = cc_credentials_iterator_next(iterator, &cu);
+
+       if (err == ccIteratorEnd) {
+               cc_credentials_iterator_release(iterator);
+               *cursor = 0;
+       }
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+       
+       /* copy data    (with translation) */
+       dupCC3toK5(context, cu, creds);
+       
+       cc_credentials_release(cu);
+       
+       return 0;
+}
+
+
+/*
+ * retrieve
+ *
+ * - try to find a matching credential in the cache
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_stdccv3_retrieve(context, id, whichfields, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    return krb5_cc_retrieve_cred_default (context, id, whichfields,
+                                         mcreds, creds);
+}
+
+/*
+ *  end seq
+ *
+ * just free up the storage assoicated with the cursor (if we can)
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_end_seq_get 
+        (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor)
+{
+       krb5_error_code                 retval;
+       stdccCacheDataPtr               ccapi_data = NULL;
+       int                             err;
+        cc_credentials_iterator_t      iterator;
+
+       ccapi_data = id->data;
+       
+        if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+
+       if (*cursor == NULL)
+               return 0;
+
+        iterator = *cursor;
+
+       err = cc_credentials_iterator_release(iterator);
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+       return(0);
+}
+     
+/*
+ * close
+ *
+ * - free our pointers to the NC
+ */
+krb5_error_code KRB5_CALLCONV 
+krb5_stdccv3_close(krb5_context context, krb5_ccache id)
+{
+       krb5_error_code retval;
+       stdccCacheDataPtr       ccapi_data = id->data;
+
+       if ((retval = stdccv3_setup(context, NULL)))
+               return retval;
+       
+       /* free it */
+       if (ccapi_data) {
+               if (ccapi_data->cache_name)
+                       free(ccapi_data->cache_name);
+               if (ccapi_data->NamedCache)
+                       cc_ccache_release(ccapi_data->NamedCache);
+               free(ccapi_data);
+               id->data = NULL;
+       }
+       free(id);
+       
+       return 0;
+}
+
+/*
+ * destroy
+ *
+ * - free our storage and the cache
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_stdccv3_destroy (krb5_context context, krb5_ccache id)
+{
+       int err;
+       krb5_error_code retval;
+       stdccCacheDataPtr       ccapi_data = id->data;
+
+       if ((retval = stdccv3_setup(context, ccapi_data))) {
+               return retval;
+       }
+
+       /* free memory associated with the krb5_ccache */
+       if (ccapi_data) {
+               if (ccapi_data->cache_name)
+                       free(ccapi_data->cache_name);
+               if (ccapi_data->NamedCache) {
+                       /* destroy the named cache */
+                       err = cc_ccache_destroy(ccapi_data->NamedCache);
+                       retval = cc_err_xlate(err);
+                       cache_changed();
+               }
+               free(ccapi_data);
+               id->data = NULL;
+       }
+       free(id);
+
+       /* If the cache does not exist when we tried to destroy it,
+          that's fine.  That means someone else destroyed it since
+          we resolved it. */
+       if (retval == ccErrCCacheNotFound)
+               return 0;
+       return retval;
+}
+
+/*
+ *  getname
+ *
+ * - return the name of the named cache
+ */
+const char * KRB5_CALLCONV krb5_stdccv3_get_name 
+        (krb5_context context, krb5_ccache id )
+{
+       stdccCacheDataPtr       ccapi_data = id->data;
+
+       if (!ccapi_data)
+               return 0;
+
+       return (ccapi_data->cache_name);
+}
+
+
+/* get_principal
+ *
+ * - return the principal associated with the named cache
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_principal
+       (krb5_context context, krb5_ccache id , krb5_principal *princ) 
+{
+       int                     err;
+       cc_string_t             name = NULL;
+       stdccCacheDataPtr       ccapi_data = id->data;
+       krb5_error_code         retval;
+       
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+
+       /* another wrapper */
+       err = cc_ccache_get_principal(ccapi_data->NamedCache, cc_credentials_v5, &name);
+
+       if (err != ccNoError) 
+               return cc_err_xlate(err);
+               
+       /* turn it into a krb principal */
+       err = krb5_parse_name(context, name->data, princ);
+
+       cc_string_release(name);
+       
+       return err;     
+}
+
+/*
+ * set_flags
+ *
+ * - currently a NOP since we don't store any flags in the NC
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_set_flags 
+        (krb5_context context, krb5_ccache id , krb5_flags flags)
+{
+       stdccCacheDataPtr       ccapi_data = id->data;
+       krb5_error_code         retval;
+       
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+
+       return 0;
+}
+
+/*
+ * get_flags
+ *
+ * - currently a NOP since we don't store any flags in the NC
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags 
+        (krb5_context context, krb5_ccache id , krb5_flags *flags)
+{
+       stdccCacheDataPtr       ccapi_data = id->data;
+       krb5_error_code         retval;
+       
+       if ((retval = stdccv3_setup(context, ccapi_data)))
+               return retval;
+
+       return 0;
+}
+
+/*
+ * remove
+ *
+ * - remove the specified credentials from the NC
+ */
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove 
+        (krb5_context context, krb5_ccache id,
+        krb5_flags flags, krb5_creds *creds)
+{
+       cc_credentials_t        c = NULL;
+       int                     err;
+       stdccCacheDataPtr       ccapi_data = id->data;
+       krb5_error_code         retval;
+       
+       if ((retval = stdccv3_setup(context, ccapi_data))) {
+               if (retval == KRB5_FCC_NOFILE)
+                       return 0;
+               return retval;
+       }
+       
+       /* convert to a cred union */
+       dupK5toCC3(context, creds, &c);
+       
+       /* remove it */
+       err = cc_ccache_remove_credentials(ccapi_data->NamedCache, c);
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+       
+       err = cc_credentials_release(c);
+       cache_changed();
+       if (err != ccNoError)
+               return cc_err_xlate(err);
+
+        return 0;
+}
+#else /* !USE_CCAPI_V3 */
 static krb5_error_code stdcc_setup(krb5_context context,
                                   stdccCacheDataPtr ccapi_data)
 {
@@ -192,7 +775,7 @@ void krb5_stdcc_shutdown()
 {
        if (gCntrlBlock)
                cc_shutdown(&gCntrlBlock);
-       gCntrlBlock = 0;
+       gCntrlBlock = NULL;
 }
 
 /*
@@ -289,9 +872,10 @@ krb5_error_code KRB5_CALLCONV  krb5_stdcc_resolve
        
        err = cc_open(gCntrlBlock, cName, CC_CRED_V5, 0L,
                      &ccapi_data->NamedCache);
-       if (err != CC_NOERROR)
-               ccapi_data->NamedCache = NULL;
-       
+        if (err != CC_NOERROR) {
+               ccapi_data->NamedCache = NULL;
+               goto errout;
+       }
        /* return new cache structure */
        *id = newCache;
        
@@ -388,7 +972,7 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_store
                
        /* free the cred union using our local version of cc_free_creds()
           since we allocated it locally */
-       err = krb5_free_cc_cred_union(&cu);
+       err = krb5int_free_cc_cred_union(&cu);
                 
        cache_changed();
        return err;
@@ -523,7 +1107,6 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_retrieve
        return KRB5_CC_NOTFOUND;
 }
 #else
-#include "k5-int.h"
 
 krb5_error_code KRB5_CALLCONV
 krb5_stdcc_retrieve(context, id, whichfields, mcreds, creds)
@@ -763,10 +1346,11 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_remove
        
        /* free the cred union using our local version of cc_free_creds()
               since we allocated it locally */
-       err = krb5_free_cc_cred_union(&cu);
+       err = krb5int_free_cc_cred_union(&cu);
        cache_changed();
        if (err != CC_NOERROR)
                return cc_err_xlate(err);
 
         return 0;
 }
+#endif /* !USE_CCAPI_V3 */
\ No newline at end of file
index 81ce883cb6c08d5226b2be10d16e0e8552aa649c..c0ce13b420494017b98d9cf61efc37a6a22c6c31 100644 (file)
@@ -1,13 +1,17 @@
-#include "krb5.h"
-#include "k5-int.h"
+#include "k5-int.h"    /* loads krb5.h */
        
+#ifdef USE_CCAPI_V3
+#include <CredentialsCache.h>
+#else
 #ifdef USE_CCAPI
 #include <CredentialsCache2.h>
-#endif
-
+#else
 #if defined(_WIN32)
 #include "cacheapi.h"
 #endif
+#endif
+#endif
+
 
 #define kStringLiteralLen 255
 
@@ -19,12 +23,71 @@ extern krb5_cc_ops krb5_cc_stdcc_ops;
  */
 typedef struct _stdccCacheData {
        char *cache_name;
+#ifdef USE_CCAPI_V3
+        cc_ccache_t NamedCache;
+#else
        ccache_p *NamedCache;
+#endif
 } stdccCacheData, *stdccCacheDataPtr;
 
 
 /* function protoypes  */
 
+#ifdef USE_CCAPI_V3
+void krb5_stdccv3_shutdown(void);
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_close
+        (krb5_context, krb5_ccache id );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_destroy 
+        (krb5_context, krb5_ccache id );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_end_seq_get 
+        (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_generate_new 
+        (krb5_context, krb5_ccache *id );
+
+const char * KRB5_CALLCONV krb5_stdccv3_get_name 
+        (krb5_context, krb5_ccache id );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_principal 
+        (krb5_context, krb5_ccache id , krb5_principal *princ );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_initialize 
+        (krb5_context, krb5_ccache id , krb5_principal princ );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred 
+        (krb5_context, 
+                  krb5_ccache id , 
+                  krb5_cc_cursor *cursor , 
+                  krb5_creds *creds );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_resolve 
+        (krb5_context, krb5_ccache *id , const char *residual );
+     
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_retrieve 
+        (krb5_context, 
+                  krb5_ccache id , 
+                  krb5_flags whichfields , 
+                  krb5_creds *mcreds , 
+                  krb5_creds *creds );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_start_seq_get 
+        (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_store 
+        (krb5_context, krb5_ccache id , krb5_creds *creds );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_set_flags 
+        (krb5_context, krb5_ccache id , krb5_flags flags );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags 
+        (krb5_context, krb5_ccache id , krb5_flags *flags );
+
+krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove 
+        (krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds);
+#else
 void krb5_stdcc_shutdown(void);
 
 krb5_error_code KRB5_CALLCONV krb5_stdcc_close
@@ -78,3 +141,4 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_get_flags
 
 krb5_error_code KRB5_CALLCONV krb5_stdcc_remove 
         (krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds);
+#endif
\ No newline at end of file
index 7f9358dca5644ba15b8e988b1c4a56aac26b7934..1969b6e718af29341818d82741be5cb263d99b5c 100644 (file)
 
 #define fieldSize 255
 
+#ifdef USE_CCAPI_V3
+/* krb5int_cc_credentials_release(cc_credentials_t creds)
+ * - function used to release internally generated cc_credentials_t objects
+ */
+static cc_int32 
+krb5int_cc_credentials_release(cc_credentials_t creds) {
+    free(creds);
+    return ccNoError;
+}
+
+static cc_int32 
+krb5int_cc_credentials_compare(cc_credentials_t creds,
+                              cc_credentials_t compare_to,
+                              cc_uint32* equal) {
+    return ccErrNotImplemented;
+}
+
+/*
+ * CopyCC3DataArrayToK5
+ * - copy and translate the null terminated arrays of data records
+ *      used in k5 tickets
+ */
+int 
+copyCC3DataArrayToK5(cc_credentials_v5_t *ccCreds, krb5_creds *v5Creds, char whichArray) {
+
+    switch (whichArray) {
+    case kAddressArray: 
+       if (ccCreds->addresses == NULL) {
+           v5Creds->addresses = NULL;
+       } else {
+
+           krb5_address        **addrPtr, *addr;
+           cc_data             **dataPtr, *data;
+           unsigned int        numRecords = 0;
+
+           /* Allocate the array of pointers: */
+           for (dataPtr = ccCreds->addresses; *dataPtr != NULL; numRecords++, dataPtr++) {}
+
+           v5Creds->addresses = (krb5_address **) malloc (sizeof(krb5_address *) * (numRecords + 1));
+           if (v5Creds->addresses == NULL)
+               return ENOMEM;
+
+           /* Fill in the array, allocating the address structures: */
+           for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *dataPtr != NULL; addrPtr++, dataPtr++) {
+
+               *addrPtr = (krb5_address *) malloc (sizeof(krb5_address));
+               if (*addrPtr == NULL)
+                   return ENOMEM;
+               data = *dataPtr;
+               addr = *addrPtr;
+
+               addr->addrtype = data->type;
+               addr->magic    = KV5M_ADDRESS;
+               addr->length   = data->length;
+               addr->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * addr->length);
+               if (addr->contents == NULL)
+                   return ENOMEM;
+               memmove(addr->contents, data->data, addr->length); /* copy contents */
+           }
+
+           /* Write terminator: */
+           *addrPtr = NULL;
+       }
+       break;
+    case kAuthDataArray:
+       if (ccCreds->authdata == NULL) {
+           v5Creds->authdata = NULL;
+       } else {
+           krb5_authdata       **authPtr, *auth;
+           cc_data             **dataPtr, *data;
+           unsigned int        numRecords = 0;
+
+           /* Allocate the array of pointers: */
+           for (dataPtr = ccCreds->authdata; *dataPtr != NULL; numRecords++, dataPtr++) {}
+
+           v5Creds->authdata = (krb5_authdata **) malloc (sizeof(krb5_authdata *) * (numRecords + 1));
+           if (v5Creds->authdata == NULL)
+               return ENOMEM;
+
+           /* Fill in the array, allocating the address structures: */
+           for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *dataPtr != NULL; authPtr++, dataPtr++) {
+
+               *authPtr = (krb5_authdata *) malloc (sizeof(krb5_authdata));
+               if (*authPtr == NULL)
+                   return ENOMEM;
+               data = *dataPtr;
+               auth = *authPtr;
+
+               auth->ad_type  = data->type;
+               auth->magic    = KV5M_AUTHDATA;
+               auth->length   = data->length;
+               auth->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * auth->length);
+               if (auth->contents == NULL)
+                   return ENOMEM;
+               memmove(auth->contents, data->data, auth->length); /* copy contents */
+           }
+
+           /* Write terminator: */
+           *authPtr = NULL;
+       }
+       break;
+    }
+
+    return 0;
+}
+
+/*
+ * copyK5DataArrayToCC
+ * - analagous to above, but in the other direction
+ */
+int 
+copyK5DataArrayToCC3(krb5_creds *v5Creds, cc_credentials_v5_t * ccCreds, char whichArray)
+{
+    switch (whichArray) {
+    case kAddressArray:
+       if (v5Creds->addresses == NULL) {
+           ccCreds->addresses = NULL;
+       } else {
+
+           krb5_address        **addrPtr, *addr;
+           cc_data             **dataPtr, *data;
+           unsigned int        numRecords = 0;
+
+           /* Allocate the array of pointers: */
+           for (addrPtr = v5Creds->addresses; *addrPtr != NULL; numRecords++, addrPtr++) {}
+
+           ccCreds->addresses = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1));
+           if (ccCreds->addresses == NULL)
+               return ENOMEM;
+
+           /* Fill in the array, allocating the address structures: */
+           for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *addrPtr != NULL; addrPtr++, dataPtr++) {
+
+               *dataPtr = (cc_data *) malloc (sizeof(cc_data));
+               if (*dataPtr == NULL)
+                   return ENOMEM;
+               data = *dataPtr;
+               addr = *addrPtr;
+
+               data->type   = addr->addrtype;
+               data->length = addr->length;
+               data->data   = malloc (sizeof(char) * data->length);
+               if (data->data == NULL)
+                   return ENOMEM;
+               memmove(data->data, addr->contents, data->length); /* copy contents */
+           }
+
+           /* Write terminator: */
+           *dataPtr = NULL;
+       }
+       break;
+    case kAuthDataArray:
+       if (v5Creds->authdata == NULL) {
+           ccCreds->authdata = NULL;
+       } else {
+           krb5_authdata       **authPtr, *auth;
+           cc_data                     **dataPtr, *data;
+           unsigned int                        numRecords = 0;
+
+           /* Allocate the array of pointers: */
+           for (authPtr = v5Creds->authdata; *authPtr != NULL; numRecords++, authPtr++) {}
+
+           ccCreds->authdata = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1));
+           if (ccCreds->authdata == NULL)
+               return ENOMEM;
+
+           /* Fill in the array, allocating the address structures: */
+           for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *authPtr != NULL; authPtr++, dataPtr++) {
+
+               *dataPtr = (cc_data *) malloc (sizeof(cc_data));
+               if (*dataPtr == NULL)
+                   return ENOMEM;
+               data = *dataPtr;
+               auth = *authPtr;
+
+               data->type   = auth->ad_type;
+               data->length = auth->length;
+               data->data   = malloc (sizeof(char) * data->length);
+               if (data->data == NULL)
+                   return ENOMEM;
+               memmove(data->data, auth->contents, data->length); /* copy contents */
+           }
+
+           /* Write terminator: */
+           *dataPtr = NULL;
+       }
+       break;
+    }
+
+    return 0;
+
+}
+
+/*
+ * dupCC3toK5
+ * - allocate an empty k5 style ticket and copy info from the cc_creds ticket
+ */
+
+krb5_error_code
+dupCC3toK5(krb5_context context, cc_credentials_t src, krb5_creds *dest)
+{
+    const cc_credentials_union         *cu = src->data;
+    cc_credentials_v5_t                *cv5;
+    krb5_int32 offset_seconds = 0, offset_microseconds = 0;
+    krb5_error_code err;
+
+    if (cu->version != cc_credentials_v5) 
+       return KRB5_CC_NOT_KTYPE;
+
+    cv5 = cu->credentials.credentials_v5;
+
+    /*
+     * allocate and copy
+     * copy all of those damn fields back
+     */
+    err = krb5_parse_name(context, cv5->client, &(dest->client));
+    err = krb5_parse_name(context, cv5->server, &(dest->server));
+    if (err) 
+       return err; /* parsename fails w/o krb5.ini for example */
+
+    /* copy keyblock */
+    dest->keyblock.enctype = cv5->keyblock.type;
+    dest->keyblock.length = cv5->keyblock.length;
+    dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length);
+    memcpy(dest->keyblock.contents, cv5->keyblock.data, dest->keyblock.length);
+
+    /* copy times */
+#if TARGET_OS_MAC
+    err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
+    if (err) 
+       return err;
+#endif
+    dest->times.authtime   = cv5->authtime     + offset_seconds;
+    dest->times.starttime  = cv5->starttime    + offset_seconds;
+    dest->times.endtime    = cv5->endtime      + offset_seconds;
+    dest->times.renew_till = cv5->renew_till   + offset_seconds;
+    dest->is_skey          = cv5->is_skey;
+    dest->ticket_flags     = cv5->ticket_flags;
+
+    /* more branching fields */
+    err = copyCC3DataArrayToK5(cv5, dest, kAddressArray);
+    if (err) 
+       return err;
+
+    /* first ticket */
+    dest->ticket.length = cv5->ticket.length;
+    dest->ticket.data = (char *)malloc(cv5->ticket.length);
+    memcpy(dest->ticket.data, cv5->ticket.data, cv5->ticket.length);
+
+    /* second ticket */
+    dest->second_ticket.length = cv5->second_ticket.length;
+    (dest->second_ticket).data = ( char *)malloc(cv5->second_ticket.length);
+    memcpy(dest->second_ticket.data, cv5->second_ticket.data, cv5->second_ticket.length);
+
+    /* zero out magic number */
+    dest->magic = 0;
+
+    /* authdata */
+    err = copyCC3DataArrayToK5(cv5, dest, kAuthDataArray);
+    if (err) 
+       return err;
+
+    return 0;
+}
+
+/*
+ * dupK5toCC3
+ * - analagous to above but in the reverse direction
+ */
+krb5_error_code
+dupK5toCC3(krb5_context context, krb5_creds *src, cc_credentials_t *dest)
+{
+    cc_credentials_v5_t *c;
+    cc_credentials_union *cu;
+    cc_credentials_f    *f;
+    int err;
+    krb5_int32 offset_seconds = 0, offset_microseconds = 0;
+    cc_credentials_t           creds = NULL;
+
+    if (dest == NULL) 
+       return KRB5_CC_NOMEM;
+
+    /* allocate the cc_credentials_t */
+    creds = (cc_credentials_t)malloc(sizeof(cc_credentials_d));
+    if (!creds) {
+       err = KRB5_CC_NOMEM;
+       goto cleanup;
+    }
+
+    /* allocate the cred_union */
+    creds->data = NULL;
+    creds->functions = NULL;
+#ifdef TARGET_OS_MAC
+    creds->otherFunctions = NULL;
+#endif
+    f = (cc_credentials_f *)malloc(sizeof(cc_credentials_f));
+    if (!f) {
+       err = KRB5_CC_NOMEM;
+       goto cleanup;
+    }
+    creds->functions = f;
+
+    cu = (cc_credentials_union *)malloc(sizeof(cc_credentials_union));
+    if (!creds->data) {
+       err = KRB5_CC_NOMEM;
+       goto cleanup;
+    }
+    creds->data = cu; 
+
+    f->release = krb5int_cc_credentials_release;
+    f->compare = krb5int_cc_credentials_compare;
+
+    cu->version = cc_credentials_v5;
+
+    c = (cc_credentials_v5_t*)malloc(sizeof(cc_credentials_v5_t));
+    if (!c) {
+       err = KRB5_CC_NOMEM;
+       goto cleanup;
+    }
+    cu->credentials.credentials_v5 = c;
+
+    /* convert krb5 principals to flat principals */
+    err = krb5_unparse_name(context, src->client, &(c->client));
+    if (err) 
+       goto cleanup;
+
+    err = krb5_unparse_name(context, src->server, &(c->server));
+    if (err) 
+       goto cleanup;
+
+    /* copy more fields */
+    c->keyblock.type = src->keyblock.enctype;
+    c->keyblock.length = src->keyblock.length;
+
+    if (src->keyblock.contents != NULL) {
+       c->keyblock.data = (unsigned char *)malloc(src->keyblock.length);
+       memcpy(c->keyblock.data, src->keyblock.contents, src->keyblock.length);
+    } else {
+       c->keyblock.data = NULL;
+    }
+
+#if TARGET_OS_MAC
+    err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
+    if (err) 
+       goto cleanup;
+#endif
+    c->authtime     = src->times.authtime   - offset_seconds;
+    c->starttime    = src->times.starttime  - offset_seconds;
+    c->endtime      = src->times.endtime    - offset_seconds;
+    c->renew_till   = src->times.renew_till - offset_seconds;
+    c->is_skey      = src->is_skey;
+    c->ticket_flags = src->ticket_flags;
+
+    err = copyK5DataArrayToCC3(src, c, kAddressArray);
+    if (err) 
+       goto cleanup;
+
+    c->ticket.length = src->ticket.length;
+    if (src->ticket.data != NULL) {
+       c->ticket.data = (unsigned char *)malloc(src->ticket.length);
+       memcpy(c->ticket.data, src->ticket.data, src->ticket.length);
+    } else {
+       c->ticket.data = NULL;
+    }
+
+    c->second_ticket.length = src->second_ticket.length;
+    if (src->second_ticket.data != NULL) {
+       c->second_ticket.data = (unsigned char *)malloc(src->second_ticket.length);
+       memcpy(c->second_ticket.data, src->second_ticket.data, src->second_ticket.length);
+    } else {
+       c->second_ticket.data = NULL;
+    }
+
+    err = copyK5DataArrayToCC3(src, c, kAuthDataArray);
+    if (err) 
+       goto cleanup;
+
+    *dest = creds;
+    return 0;
+
+  cleanup:
+    if (creds) {
+       if (creds->functions)
+           free((void *)creds->functions);
+       if (creds->data) {
+           if (creds->data->credentials.credentials_v5)
+               free(creds->data->credentials.credentials_v5);
+           free((void *)creds->data);
+       }
+       free(creds);
+    }
+
+    return err;
+}
+#else /* !USE_CCAPI_V3 */
 /*
  * CopyCCDataArrayToK5
  * - copy and translate the null terminated arrays of data records
@@ -323,6 +718,86 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu)
     return;
 }
 
+/* ----- free_cc_cred_union, etc -------------- */
+/*
+  Since the Kerberos5 library allocates a credentials cache structure
+  (in dupK5toCC() above) with its own memory allocation routines - which
+  may be different than how the CCache allocates memory - the Kerb5 library
+  must have its own version of cc_free_creds() to deallocate it.  These
+  functions do that.  The top-level function to substitue for cc_free_creds()
+  is krb5_free_cc_cred_union().
+
+  If the CCache library wants to use a cred_union structure created by
+  the Kerb5 library, it should make a deep copy of it to "translate" to its
+  own memory allocation space.
+*/
+static void deep_free_cc_data (cc_data data)
+{
+    if (data.data != NULL)
+       free (data.data);
+}
+
+static void deep_free_cc_data_array (cc_data** data) {
+
+    unsigned int       index;
+
+    if (data == NULL)
+       return;
+
+    for (index = 0; data [index] != NULL; index++) {
+       deep_free_cc_data (*(data [index]));
+       free (data [index]);
+    }
+
+    free (data);
+}
+
+static void deep_free_cc_v5_creds (cc_creds* creds)
+{
+    if (creds == NULL)
+       return;
+
+    if (creds -> client != NULL)
+       free (creds -> client);
+    if (creds -> server != NULL)
+       free (creds -> server);
+
+    deep_free_cc_data (creds -> keyblock);
+    deep_free_cc_data (creds -> ticket);
+    deep_free_cc_data (creds -> second_ticket);
+
+    deep_free_cc_data_array (creds -> addresses);
+    deep_free_cc_data_array (creds -> authdata);
+
+    free(creds);
+}
+
+static void deep_free_cc_creds (cred_union creds)
+{
+    if (creds.cred_type == CC_CRED_V4) {
+       /* we shouldn't get this, of course */
+       free (creds.cred.pV4Cred);
+    } else if (creds.cred_type == CC_CRED_V5) {
+       deep_free_cc_v5_creds (creds.cred.pV5Cred);
+    }
+}
+
+/* top-level exported function */
+cc_int32 krb5int_free_cc_cred_union (cred_union** creds)
+{
+    if (creds == NULL)
+       return CC_BAD_PARM;
+
+    if (*creds != NULL) {
+       deep_free_cc_creds (**creds);
+       free (*creds);
+       *creds = NULL;
+    }
+
+    return CC_NOERROR;
+}
+#endif
+
 /*
  * Utility functions...
  */
@@ -475,81 +950,4 @@ int stdccCredsMatch(krb5_context context, krb5_creds *base,
     return FALSE;
 }
 
-/* ----- free_cc_cred_union, etc -------------- */
-/*
-  Since the Kerberos5 library allocates a credentials cache structure
-  (in dupK5toCC() above) with its own memory allocation routines - which
-  may be different than how the CCache allocates memory - the Kerb5 library
-  must have its own version of cc_free_creds() to deallocate it.  These
-  functions do that.  The top-level function to substitue for cc_free_creds()
-  is krb5_free_cc_cred_union().
-
-  If the CCache library wants to use a cred_union structure created by
-  the Kerb5 library, it should make a deep copy of it to "translate" to its
-  own memory allocation space.
-*/
-static void deep_free_cc_data (cc_data data)
-{
-    if (data.data != NULL)
-       free (data.data);
-}
-
-static void deep_free_cc_data_array (cc_data** data) {
-
-    unsigned int       index;
-
-    if (data == NULL)
-       return;
 
-    for (index = 0; data [index] != NULL; index++) {
-       deep_free_cc_data (*(data [index]));
-       free (data [index]);
-    }
-
-    free (data);
-}
-
-static void deep_free_cc_v5_creds (cc_creds* creds)
-{
-    if (creds == NULL)
-       return;
-
-    if (creds -> client != NULL)
-       free (creds -> client);
-    if (creds -> server != NULL)
-       free (creds -> server);
-
-    deep_free_cc_data (creds -> keyblock);
-    deep_free_cc_data (creds -> ticket);
-    deep_free_cc_data (creds -> second_ticket);
-
-    deep_free_cc_data_array (creds -> addresses);
-    deep_free_cc_data_array (creds -> authdata);
-
-    free(creds);
-}
-
-static void deep_free_cc_creds (cred_union creds)
-{
-    if (creds.cred_type == CC_CRED_V4) {
-       /* we shouldn't get this, of course */
-       free (creds.cred.pV4Cred);
-    } else if (creds.cred_type == CC_CRED_V5) {
-       deep_free_cc_v5_creds (creds.cred.pV5Cred);
-    }
-}
-
-/* top-level exported function */
-cc_int32 krb5_free_cc_cred_union (cred_union** creds)
-{
-    if (creds == NULL)
-       return CC_BAD_PARM;
-
-    if (*creds != NULL) {
-       deep_free_cc_creds (**creds);
-       free (*creds);
-       *creds = NULL;
-    }
-
-    return CC_NOERROR;
-}
index 92bafc8fa6e682d3ca8300859142c2f68ceb4275..7476313dfa5c953ea38a7cb3d70dd0c365381c55 100644 (file)
@@ -5,6 +5,9 @@
 
 #include "autoconf.h"
 
+#if USE_CCAPI_V3
+#include <CredentialsCache.h>
+#else
 #if USE_CCAPI
 #include <CredentialsCache2.h>
 #endif
 #if defined(_WIN32)
 #include "cacheapi.h"
 #endif
+#endif
 
 #include "krb5.h"
 
 /* protoypes for private functions declared in stdcc_util.c */
+#ifdef USE_CCAPI_V3
+krb5_error_code dupCC3toK5(krb5_context context, cc_credentials_t src, krb5_creds *dest);
+krb5_error_code dupK5toCC3(krb5_context context, krb5_creds *src, cc_credentials_t *dest);
+cc_int32 krb5int_cc_credentials_release(cc_credentials_t creds);
+cc_int32 krb5int_cc_credentials_compare(cc_credentials_t creds,
+                                       cc_credentials_t compare_to,
+                                       cc_uint32* equal);
+int copyCC3DataArrayToK5(cc_credentials_v5_t *ccCreds, krb5_creds *v5Creds, char whichArray);
+int copyK5DataArrayToCC3(krb5_creds *v5Creds, cc_credentials_v5_t * ccCreds, char whichArray);
+#else
 int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray);
 int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray);
 void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest);
 void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu);
+cc_int32 krb5int_free_cc_cred_union (cred_union** creds);
+#endif
 int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields);
 int bitTst(int var, int mask);
-cc_int32 krb5_free_cc_cred_union (cred_union** creds);
 
 #define kAddressArray 4 
 #define kAuthDataArray 5
index e285d1faf66e99efe6c950e185f5c0d8e6208ff4..245ae245e2f0db708c8950f3b95d11d36ea18969 100644 (file)
@@ -6,12 +6,24 @@
 #ifndef KRB5_WINCCLD_H_
 #define KRB5_WINCCLD_H_
 
+#ifdef USE_CCAPI_V3
+#include <CredentialsCache.h>
+#else
+
 #ifndef CC_API_VER2
 #define CC_API_VER2
 #endif
 
 #include "cacheapi.h"
+#endif
 
+#ifdef USE_CCAPI_V3
+typedef CCACHE_API cc_int32 (*FP_cc_initialize) (
+        cc_context_t*           outContext,
+        cc_int32                inVersion,
+        cc_int32*               outSupportedVersion,
+        char const**            outVendor);
+#else
 typedef cc_int32 (*FP_cc_initialize)(apiCB**, const cc_int32, 
                        cc_int32*, const char**);     
 typedef cc_int32 (*FP_cc_shutdown)(apiCB**);            
@@ -49,6 +61,7 @@ typedef cc_int32 (*FP_cc_seq_fetch_creds_end)(apiCB*, ccache_cit**);
 typedef cc_int32 (*FP_cc_free_principal)(apiCB*, char**);
 typedef cc_int32 (*FP_cc_free_name)(apiCB*, char** name);
 typedef cc_int32 (*FP_cc_free_creds)(apiCB*, cred_union** pCred);
+#endif
 
 #ifdef KRB5_WINCCLD_C_
 typedef struct _FUNC_INFO {
@@ -64,6 +77,7 @@ typedef struct _FUNC_INFO {
 #endif
 
 DECL_FUNC_PTR(cc_initialize);
+#ifndef USE_CCAPI_V3
 DECL_FUNC_PTR(cc_shutdown);
 DECL_FUNC_PTR(cc_get_change_time);
 DECL_FUNC_PTR(cc_create);
@@ -100,10 +114,12 @@ DECL_FUNC_PTR(cc_seq_fetch_creds);
 DECL_FUNC_PTR(cc_free_principal);
 DECL_FUNC_PTR(cc_free_name);
 DECL_FUNC_PTR(cc_free_creds);
+#endif
 
 #ifdef KRB5_WINCCLD_C_
 FUNC_INFO krbcc_fi[] = {
     MAKE_FUNC_INFO(cc_initialize),
+#ifndef USE_CCAPI_V3
     MAKE_FUNC_INFO(cc_shutdown),
     MAKE_FUNC_INFO(cc_get_change_time),
     MAKE_FUNC_INFO(cc_create),
@@ -134,6 +150,7 @@ FUNC_INFO krbcc_fi[] = {
     MAKE_FUNC_INFO(cc_free_principal),
     MAKE_FUNC_INFO(cc_free_name),
     MAKE_FUNC_INFO(cc_free_creds),
+#endif
     END_FUNC_INFO
 };
 #undef MAKE_FUNC_INFO
@@ -141,6 +158,7 @@ FUNC_INFO krbcc_fi[] = {
 #else
 
 #define cc_initialize pcc_initialize
+#ifndef USE_CCAPI_V3
 #define cc_shutdown pcc_shutdown
 #define cc_get_change_time pcc_get_change_time
 #define cc_create pcc_create
@@ -178,6 +196,7 @@ FUNC_INFO krbcc_fi[] = {
 #define cc_free_name pcc_free_name
 #define cc_free_creds pcc_free_creds
 #endif
+#endif
 
 #undef DECL_FUNC_PTR