]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Need CCAPI v2 support for Windows
authorAlexandra Ellwood <lxs@mit.edu>
Wed, 6 Feb 2008 20:22:32 +0000 (20:22 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Wed, 6 Feb 2008 20:22:32 +0000 (20:22 +0000)
Added initial checkin of CCAPI v2 shim layer.

ticket: new
status: open

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20220 dc483132-0cff-0310-8789-dd5450dbe970

12 files changed:
src/ccapi/common/cci_cred_union.c
src/ccapi/common/cci_cred_union.h
src/ccapi/lib/ccapi_ccache.c
src/ccapi/lib/ccapi_ccache.h
src/ccapi/lib/ccapi_ccache_iterator.c
src/ccapi/lib/ccapi_ccache_iterator.h
src/ccapi/lib/ccapi_context.c
src/ccapi/lib/ccapi_credentials.c
src/ccapi/lib/ccapi_credentials_iterator.c
src/ccapi/lib/ccapi_credentials_iterator.h
src/ccapi/lib/ccapi_v2.c
src/ccapi/server/ccs_credentials.c

index 55da1e264b2ddfcd5e2bc5a8540d80c2a43db467..902013dec14cb35ac3821a42ecd6a0d8b95b9b28 100644 (file)
@@ -594,7 +594,7 @@ static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds,
 
 /* ------------------------------------------------------------------------ */
 
-cc_uint32 cci_cred_union_release (cc_credentials_union *io_cred_union)
+cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union)
 {
     cc_int32 err = ccNoError;
     
@@ -614,31 +614,31 @@ cc_uint32 cci_cred_union_release (cc_credentials_union *io_cred_union)
 
 /* ------------------------------------------------------------------------ */
 
-cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union,
-                               cci_stream_t           io_stream)
+cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union,
+                                      cci_stream_t           io_stream)
 {
     cc_int32 err = ccNoError;
-    cc_credentials_union *cred_union = NULL;
+    cc_credentials_union *credentials_union = NULL;
     
     if (!io_stream            ) { err = cci_check_error (ccErrBadParam); }
     if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
     
     if (!err) {
-        cred_union = malloc (sizeof (*cred_union));
-        if (!cred_union) { err = cci_check_error (ccErrNoMem); }
+        credentials_union = calloc (1, sizeof (*credentials_union));
+        if (!credentials_union) { err = cci_check_error (ccErrNoMem); }
     }
     
     if (!err) {
-        err = cci_stream_read_uint32 (io_stream, &cred_union->version);
+        err = cci_stream_read_uint32 (io_stream, &credentials_union->version);
     }
     
     if (!err) {
-        if (cred_union->version == cc_credentials_v4) {
-            err = cci_credentials_v4_read (&cred_union->credentials.credentials_v4,
+        if (credentials_union->version == cc_credentials_v4) {
+            err = cci_credentials_v4_read (&credentials_union->credentials.credentials_v4,
                                            io_stream);
         
-        } else if (cred_union->version == cc_credentials_v5) {
-            err = cci_credentials_v5_read (&cred_union->credentials.credentials_v5,
+        } else if (credentials_union->version == cc_credentials_v5) {
+            err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5,
                                            io_stream);
            
         
@@ -648,19 +648,19 @@ cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union,
     }
     
     if (!err) {
-        *out_credentials_union = cred_union;
-        cred_union = NULL;
+        *out_credentials_union = credentials_union;
+        credentials_union = NULL;
     }
     
-    if (cred_union) { cci_cred_union_release (cred_union); }
+    if (credentials_union) { cci_credentials_union_release (credentials_union); }
     
     return cci_check_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
 
-cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union,
-                                cci_stream_t                io_stream)
+cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union,
+                                       cci_stream_t                io_stream)
 {
     cc_int32 err = ccNoError;
     
@@ -687,3 +687,413 @@ cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union
     
     return cci_check_error (err);    
 }
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#pragma mark -- CCAPI v2 Compat --
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_credentials_v5_compat cci_credentials_v5_compat_initializer = {
+    NULL,
+    NULL,
+    { 0, 0, NULL },
+    0, 0, 0, 0, 0, 0, 
+    NULL,
+    { 0, 0, NULL },
+    { 0, 0, NULL },
+    NULL
+};
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 cci_cred_union_release (cred_union *io_cred_union)
+{
+    cc_int32 err = ccNoError;
+    
+    if (!io_cred_union) { err = ccErrBadParam; }
+    
+    if (!err) {
+        if (io_cred_union->cred_type == CC_CRED_V4) {
+            memset (io_cred_union->cred.pV4Cred, 0, sizeof (cc_credentials_v4_compat));
+            free (io_cred_union->cred.pV4Cred);
+            
+        } else if (io_cred_union->cred_type == CC_CRED_V5) {
+            free (io_cred_union->cred.pV5Cred->client);
+            free (io_cred_union->cred.pV5Cred->server);
+            cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock);
+            cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses);
+            cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket);
+            cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket);
+            cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata);
+            free (io_cred_union->cred.pV5Cred);        
+        }
+        free (io_cred_union);
+    }
+    
+    return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_uint32 cci_cc_data_copy_contents (cc_data      *io_ccdata,
+                                            cc_data      *in_ccdata)
+{
+    cc_int32 err = ccNoError;
+    char *data = NULL;
+    
+    if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err && in_ccdata->length > 0) {
+        data = malloc (in_ccdata->length);
+        if (data) {
+            memcpy (data, in_ccdata->data, in_ccdata->length);
+        } else { 
+            err = cci_check_error (ccErrNoMem); 
+        }
+    }
+    
+    if (!err) {
+        io_ccdata->type = in_ccdata->type;
+        io_ccdata->length = in_ccdata->length;
+        io_ccdata->data = data;
+        data = NULL;
+    }
+    
+    free (data);
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static cc_uint32 cci_cc_data_array_copy (cc_data      ***io_ccdata_array,
+                                         cc_data       **in_ccdata_array)
+{
+    cc_int32 err = ccNoError;
+    cc_uint32 count = 0;
+    cc_data **array = NULL;
+    cc_uint32 i;
+    
+    if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);
+    }
+    
+    if (!err && count > 0) {
+        array = malloc ((count + 1) * sizeof (*array));
+        if (array) { 
+            for (i = 0; i <= count; i++) { array[i] = NULL; }
+        } else {
+            err = cci_check_error (ccErrNoMem); 
+        }
+    }
+    
+    if (!err) {
+        for (i = 0; !err && i < count; i++) {
+            array[i] = malloc (sizeof (cc_data));
+            if (!array[i]) { err = cci_check_error (ccErrNoMem); }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]);
+            }
+        }
+    }
+    
+    if (!err) {
+        *io_ccdata_array = array;
+        array = NULL;
+    }
+    
+    cci_cc_data_array_release (array);
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union  *in_credentials_union,
+                                               cred_union                 **out_cred_union)
+{
+    cc_int32 err = ccNoError;
+    cred_union *compat_cred_union = NULL;
+    
+    if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
+    if (!out_cred_union      ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        compat_cred_union = calloc (1, sizeof (*compat_cred_union));
+        if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); }
+    }
+    
+    if (!err) {
+        if (in_credentials_union->version == cc_credentials_v4) {
+            cc_credentials_v4_compat *compat_v4creds = NULL;
+            
+            compat_v4creds = malloc (sizeof (*compat_v4creds));
+            if (!compat_v4creds) { err = cci_check_error (ccErrNoMem); }
+            
+            if (!err) {
+                cc_credentials_v4_t *v4creds = in_credentials_union->credentials.credentials_v4;
+                
+                compat_cred_union->cred_type = CC_CRED_V4;
+                compat_cred_union->cred.pV4Cred = compat_v4creds;
+                
+                compat_v4creds->kversion = v4creds->version;
+                strncpy (compat_v4creds->principal,          v4creds->principal,          KRB_NAME_SZ+1);
+                strncpy (compat_v4creds->principal_instance, v4creds->principal_instance, KRB_INSTANCE_SZ+1);
+                strncpy (compat_v4creds->service,            v4creds->service,            KRB_NAME_SZ+1);
+                strncpy (compat_v4creds->service_instance,   v4creds->service_instance,   KRB_INSTANCE_SZ+1);
+                strncpy (compat_v4creds->realm,              v4creds->realm,              KRB_REALM_SZ+1);
+                memcpy (compat_v4creds->session_key, v4creds->session_key, 8);
+                compat_v4creds->kvno       = v4creds->kvno;
+                compat_v4creds->str_to_key = v4creds->string_to_key_type;
+                compat_v4creds->issue_date = v4creds->issue_date;
+                compat_v4creds->lifetime   = v4creds->lifetime;
+                compat_v4creds->address    = v4creds->address;
+                compat_v4creds->ticket_sz  = v4creds->ticket_size;
+                memcpy (compat_v4creds->ticket, v4creds->ticket, MAX_V4_CRED_LEN);
+                compat_v4creds->oops = 0;
+            }
+            
+        } else if (in_credentials_union->version == cc_credentials_v5) {
+            cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5;
+            cc_credentials_v5_compat *compat_v5creds = NULL;
+            
+            compat_v5creds = malloc (sizeof (*compat_v5creds));
+            if (compat_v5creds) { 
+                *compat_v5creds = cci_credentials_v5_compat_initializer;
+            } else {
+                err = cci_check_error (ccErrNoMem); 
+            }
+            
+            if (!err) {
+                compat_v5creds->client = strdup (v5creds->client);
+                if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); }
+            }
+            
+            if (!err) {
+                compat_v5creds->server = strdup (v5creds->server);
+                if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); }
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata);
+            }
+            
+            if (!err) {
+                compat_cred_union->cred_type = CC_CRED_V5;
+                compat_cred_union->cred.pV5Cred = compat_v5creds;
+                
+                compat_v5creds->keyblock      = v5creds->keyblock;
+                compat_v5creds->authtime      = v5creds->authtime;
+                compat_v5creds->starttime     = v5creds->starttime;
+                compat_v5creds->endtime       = v5creds->endtime;
+                compat_v5creds->renew_till    = v5creds->renew_till;
+                compat_v5creds->is_skey       = v5creds->is_skey;
+                compat_v5creds->ticket_flags  = v5creds->ticket_flags;
+            }
+        } else {
+            err = cci_check_error (ccErrBadCredentialsVersion);
+        }
+    } 
+    
+    if (!err) {
+        *out_cred_union = compat_cred_union;
+        compat_cred_union = NULL;
+    }
+    
+    if (compat_cred_union) { cci_cred_union_release (compat_cred_union); }
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 cci_cred_union_to_credentials_union (const cred_union      *in_cred_union,
+                                               cc_credentials_union **out_credentials_union)
+{
+    cc_int32 err = ccNoError;
+    cc_credentials_union *creds_union = NULL;
+    
+    if (!in_cred_union        ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        creds_union = calloc (1, sizeof (*creds_union));
+        if (!creds_union) { err = cci_check_error (ccErrNoMem); }
+    }
+    
+    if (!err) {
+        if (in_cred_union->cred_type == CC_CRED_V4) {
+            cc_credentials_v4_compat *compat_v4creds = in_cred_union->cred.pV4Cred;
+            cc_credentials_v4_t *v4creds = NULL;
+            
+            if (!err) {
+                v4creds = malloc (sizeof (*v4creds));
+                if (!v4creds) { err = cci_check_error (ccErrNoMem); }
+            }
+            
+            if (!err) {
+                creds_union->version = cc_credentials_v4;
+                creds_union->credentials.credentials_v4 = v4creds;
+                
+                v4creds->version = compat_v4creds->kversion;
+                strncpy (v4creds->principal,          compat_v4creds->principal,          KRB_NAME_SZ);
+                strncpy (v4creds->principal_instance, compat_v4creds->principal_instance, KRB_INSTANCE_SZ);
+                strncpy (v4creds->service,            compat_v4creds->service,            KRB_NAME_SZ);
+                strncpy (v4creds->service_instance,   compat_v4creds->service_instance,   KRB_INSTANCE_SZ);
+                strncpy (v4creds->realm,              compat_v4creds->realm,              KRB_REALM_SZ);
+                memcpy (v4creds->session_key, compat_v4creds->session_key, 8);
+                v4creds->kvno               = compat_v4creds->kvno;
+                v4creds->string_to_key_type = compat_v4creds->str_to_key;
+                v4creds->issue_date         = compat_v4creds->issue_date;
+                v4creds->lifetime           = compat_v4creds->lifetime;
+                v4creds->address            = compat_v4creds->address;
+                v4creds->ticket_size        = compat_v4creds->ticket_sz;
+                memcpy (v4creds->ticket, compat_v4creds->ticket, MAX_V4_CRED_LEN);
+            }
+            
+        } else if (in_cred_union->cred_type == CC_CRED_V5) {
+            cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred;
+            cc_credentials_v5_t *v5creds = NULL;
+            
+            if (!err) {
+                v5creds = malloc (sizeof (*v5creds));
+                if (v5creds) { 
+                    *v5creds = cci_credentials_v5_initializer;
+                } else {
+                    err = cci_check_error (ccErrNoMem); 
+                }
+            }
+            
+            if (!err) {
+                v5creds->client = strdup (compat_v5creds->client);
+                if (!v5creds->client) { err = cci_check_error (ccErrNoMem); }
+            }
+            
+            if (!err) {
+                v5creds->server = strdup (compat_v5creds->server);
+                if (!v5creds->server) { err = cci_check_error (ccErrNoMem); }
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket);
+            }
+            
+            if (!err) {
+                err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata);
+            }
+            
+            if (!err) {
+                creds_union->version = cc_credentials_v5;
+                creds_union->credentials.credentials_v5 = v5creds;
+                
+                v5creds->authtime      = compat_v5creds->authtime;
+                v5creds->starttime     = compat_v5creds->starttime;
+                v5creds->endtime       = compat_v5creds->endtime;
+                v5creds->renew_till    = compat_v5creds->renew_till;
+                v5creds->is_skey       = compat_v5creds->is_skey;
+                v5creds->ticket_flags  = compat_v5creds->ticket_flags;
+            }
+            
+        } else {
+            err = cci_check_error (ccErrBadCredentialsVersion);
+        }
+    } 
+    
+    if (!err) {
+        *out_credentials_union = creds_union;
+        creds_union = NULL;
+    }
+    
+    if (creds_union) { cci_credentials_union_release (creds_union); }
+    
+    return cci_check_error (err);    
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union           *in_cred_union_compat,
+                                                       const cc_credentials_union *in_credentials_union,
+                                                       cc_uint32                  *out_equal) 
+{
+    cc_int32 err = ccNoError;
+    cc_uint32 equal = 0;
+    
+    if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); }
+    if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
+    if (!out_equal           ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        if (in_cred_union_compat->cred_type == CC_CRED_V4 && 
+            in_credentials_union->version == cc_credentials_v4) {
+            cc_credentials_v4_compat *old_creds_v4 = in_cred_union_compat->cred.pV4Cred;
+            cc_credentials_v4_t *new_creds_v4 = in_credentials_union->credentials.credentials_v4;
+            
+            if (old_creds_v4 && new_creds_v4 &&
+                !strcmp (old_creds_v4->principal, 
+                         new_creds_v4->principal) &&
+                !strcmp (old_creds_v4->principal_instance, 
+                         new_creds_v4->principal_instance) &&
+                !strcmp (old_creds_v4->service, 
+                         new_creds_v4->service) &&
+                !strcmp (old_creds_v4->service_instance, 
+                         new_creds_v4->service_instance) &&
+                !strcmp (old_creds_v4->realm, new_creds_v4->realm) &&
+                (old_creds_v4->issue_date == (long) new_creds_v4->issue_date)) { 
+                equal = 1;
+            }
+            
+        } else if (in_cred_union_compat->cred_type == CC_CRED_V5 && 
+               in_credentials_union->version == cc_credentials_v5) {
+            cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred;
+            cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5;
+            
+            /* Really should use krb5_parse_name and krb5_principal_compare */
+            if (old_creds_v5 && new_creds_v5 &&
+                !strcmp (old_creds_v5->client, new_creds_v5->client) &&
+                !strcmp (old_creds_v5->server, new_creds_v5->server) &&
+                (old_creds_v5->starttime == new_creds_v5->starttime)) { 
+                return 1;
+            }
+        }
+    }
+    
+    if (!err) {
+        *out_equal = equal;
+    }
+    
+    return cci_check_error (err);
+}
index f734d6a355a814acf18ddb299bca8dc4bda72f3c..3264d350a5f8a1748d2b744c79901bc9d8cae946 100644 (file)
 #define CCI_CRED_UNION_H
 
 #include "cci_types.h"
+#include <CredentialsCache2.h>
 
-cc_uint32 cci_cred_union_release (cc_credentials_union *io_credentials);
+cc_uint32 cci_credentials_union_release (cc_credentials_union *io_credentials);
 
-cc_uint32 cci_cred_union_read (cc_credentials_union **out_credentials_union,
-                               cci_stream_t           io_stream);
+cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union,
+                                      cci_stream_t           io_stream);
 
-cc_uint32 cci_cred_union_write (const cc_credentials_union *in_credentials_union,
-                                cci_stream_t                io_stream);
+cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union,
+                                       cci_stream_t                io_stream);
 
+cc_uint32 cci_cred_union_release (cred_union *io_cred_union);
+
+cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union  *in_credentials_union,
+                                               cred_union                 **out_cred_union);
+
+cc_uint32 cci_cred_union_to_credentials_union (const cred_union      *in_cred_union,
+                                               cc_credentials_union **out_credentials_union);
+
+cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union           *in_cred_union_compat,
+                                                       const cc_credentials_union *in_credentials_union,
+                                                       cc_uint32                  *out_equal);
 
 #endif /* CCI_CRED_UNION_H */
index f168c0a3280fd29bd45213e10a0afe4862143919..c36a2b0ef3e2486f3374e1910af684be473b8367 100644 (file)
@@ -45,6 +45,7 @@ typedef struct cci_ccache_d {
 #endif
     cci_identifier_t identifier;
     cc_time_t last_wait_for_change_time;
+    cc_uint32 compat_version;
 } *cci_ccache_t;
 
 /* ------------------------------------------------------------------------ */
@@ -379,7 +380,7 @@ cc_int32 ccapi_ccache_store_credentials (cc_ccache_t                 io_ccache,
     }
     
     if (!err) {
-        err = cci_cred_union_write (in_credentials_union, request);
+        err = cci_credentials_union_write (in_credentials_union, request);
     }
     
     if (!err) {
@@ -770,3 +771,42 @@ cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,
     
     return cci_check_error (err);
 }
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_get_compat_version (cc_ccache_t  in_ccache,
+                                        cc_uint32   *out_compat_version)
+{
+    cc_int32 err = ccNoError;
+    cci_ccache_t ccache = (cci_ccache_t) in_ccache;
+    
+    if (!in_ccache         ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_compat_version) { err = cci_check_error (ccErrBadParam); }
+   
+    if (!err) {
+        *out_compat_version = ccache->compat_version;
+    }
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,
+                                        cc_uint32   in_compat_version)
+{
+    cc_int32 err = ccNoError;
+    cci_ccache_t ccache = (cci_ccache_t) io_ccache;
+
+    if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        ccache->compat_version = in_compat_version;
+    }
+    
+    return cci_check_error (err);
+}
index 82a9f6c1c4dd69f8fffb8e3cf4a6faa8e1ebbe00..73091b7a0d7559366984e1a49a532d906924175e 100644 (file)
@@ -96,4 +96,11 @@ cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache,
 cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,
                                              cc_uint32   in_credentials_version);
 
+cc_int32 cci_ccache_get_compat_version (cc_ccache_t  in_ccache,
+                                        cc_uint32   *out_compat_version);
+
+cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,
+                                        cc_uint32   in_compat_version);
+
+
 #endif /* CCAPI_CCACHE_H */
index 815da36f1928131d6edd4d6e621ccba4e73cbc4a..26162af327d8a1e9fae6a4f6243976adff081362 100644 (file)
@@ -36,6 +36,7 @@ typedef struct cci_ccache_iterator_d {
     cc_ccache_iterator_f *vector_functions;
 #endif
     cci_identifier_t identifier;
+    char *saved_ccache_name;
 } *cci_ccache_iterator_t;
 
 /* ------------------------------------------------------------------------ */
@@ -43,6 +44,7 @@ typedef struct cci_ccache_iterator_d {
 struct cci_ccache_iterator_d cci_ccache_iterator_initializer = { 
     NULL 
     VECTOR_FUNCTIONS_INITIALIZER, 
+    NULL,
     NULL
 };
 
@@ -125,6 +127,7 @@ cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator)
     if (!err) {
         free ((char *) ccache_iterator->functions);
         cci_identifier_release (ccache_iterator->identifier);
+        free (ccache_iterator->saved_ccache_name);
         free (ccache_iterator);
     }
     
@@ -222,3 +225,49 @@ cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t  in_ccache_iterator,
     
     return cci_check_error (err);
 }
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t   in_ccache_iterator,
+                                                    const char           **out_saved_ccache_name)
+{
+    cc_int32 err = ccNoError;
+    cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
+    
+    if (!in_ccache_iterator   ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_saved_ccache_name) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        *out_saved_ccache_name = ccache_iterator->saved_ccache_name;
+    }
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t  io_ccache_iterator,
+                                                    const char            *in_saved_ccache_name)
+{
+    cc_int32 err = ccNoError;
+    cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;
+    char *new_saved_ccache_name = NULL;
+    
+    if (!io_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err && in_saved_ccache_name) {
+        new_saved_ccache_name = strdup (in_saved_ccache_name);
+        if (!new_saved_ccache_name) { err = ccErrNoMem; }
+    }
+    
+    if (!err) {
+        free (ccache_iterator->saved_ccache_name);
+        
+        ccache_iterator->saved_ccache_name = new_saved_ccache_name;
+        new_saved_ccache_name = NULL; /* take ownership */
+    }
+    
+    free (new_saved_ccache_name);
+    
+    return cci_check_error (err);
+}
index 0a5a4f4567f1a77a3dba4ec455eda04cf8812075..8b07b076398e643c866a69d7d5aa64d2008aeaf8 100644 (file)
@@ -43,4 +43,10 @@ cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t  in_ccache_iterator,
 cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t  in_ccache_iterator,
                                       cc_ccache_iterator_t *out_ccache_iterator);
 
+cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t   in_ccache_iterator,
+                                                    const char           **out_saved_ccache_name);
+
+cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t  io_ccache_iterator,
+                                                    const char           *in_saved_ccache_name);
+
 #endif /* CCAPI_CCACHE_ITERATOR_H */
index 7a165cf98031234b63fb118722a809a2bc336b5d..3b8d60e3eb700f16df6ded5f7eeab619451d75ec 100644 (file)
@@ -122,9 +122,6 @@ cc_int32 cc_initialize (cc_context_t  *out_context,
     if (!err) {
         switch (in_version) { 
             case ccapi_version_2: 
-                err = CC_BAD_API_VERSION;
-                break;
-                
             case ccapi_version_3:
             case ccapi_version_4:
             case ccapi_version_5:
index 4e1f48e016fd2ba611381b7ba78b69fc86759d4b..3c40478fbed12b2a90dadaf16972b945d6fd0f4e 100644 (file)
@@ -53,7 +53,7 @@ cc_credentials_f cci_credentials_f_initializer = {
     ccapi_credentials_compare
 };
 
-cc_credentials_union cci_cred_union_initializer = {
+cc_credentials_union cci_credentials_union_initializer = {
     0,
     { NULL }
 };
@@ -92,7 +92,7 @@ cc_int32 cci_credentials_read (cc_credentials_t *out_credentials,
     }
     
     if (!err) {
-        err = cci_cred_union_read (&credentials->data, in_stream);
+        err = cci_credentials_union_read (&credentials->data, in_stream);
     }
     
     if (!err) {
@@ -156,7 +156,7 @@ cc_int32 ccapi_credentials_release (cc_credentials_t io_credentials)
     if (!io_credentials) { err = ccErrBadParam; }
     
     if (!err) {
-        cci_cred_union_release (credentials->data);
+        cci_credentials_union_release (credentials->data);
         free ((char *) credentials->functions);
         cci_identifier_release (credentials->identifier);
         free (credentials);
index a99e52b499a83bc41a9d8a26fa60b6828e601efb..4f38d0745631fc1d08199354d04a1412ee9391dd 100644 (file)
@@ -36,6 +36,7 @@ typedef struct cci_credentials_iterator_d {
     cc_credentials_iterator_f *vector_functions;
 #endif
     cci_identifier_t identifier;
+    cc_uint32 compat_version;
 } *cci_credentials_iterator_t;
 
 /* ------------------------------------------------------------------------ */
@@ -43,7 +44,8 @@ typedef struct cci_credentials_iterator_d {
 struct cci_credentials_iterator_d cci_credentials_iterator_initializer = { 
     NULL 
     VECTOR_FUNCTIONS_INITIALIZER, 
-    NULL
+    NULL,
+    0
 };
 
 cc_credentials_iterator_f cci_credentials_iterator_f_initializer = { 
@@ -192,3 +194,42 @@ cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t  in_credent
     
     return cci_check_error (err);
 }
+
+#ifdef TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t  in_credentials_iterator,
+                                                      cc_uint32                 *out_compat_version)
+{
+    cc_int32 err = ccNoError;
+    cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) in_credentials_iterator;
+    
+    if (!in_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+    if (!out_compat_version     ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        *out_compat_version = credentials_iterator->compat_version;
+    }
+    
+    return cci_check_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator,
+                                                      cc_uint32                 in_compat_version)
+{
+    cc_int32 err = ccNoError;
+    cci_credentials_iterator_t credentials_iterator = (cci_credentials_iterator_t) io_credentials_iterator;
+    
+    if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        credentials_iterator->compat_version = in_compat_version;
+    }
+    
+    return cci_check_error (err);
+}
index 7ffbd23011c13dada70e63defebf0ed17175f7c3..12647d4ee24fbdfffcbbb9c0ff85b31b96235387 100644 (file)
@@ -43,4 +43,10 @@ cc_int32 ccapi_credentials_iterator_next (cc_credentials_iterator_t  in_credenti
 cc_int32 ccapi_credentials_iterator_clone (cc_credentials_iterator_t  in_credentials_iterator,
                                            cc_credentials_iterator_t *out_credentials_iterator);
 
+cc_int32 cci_credentials_iterator_get_compat_version (cc_credentials_iterator_t  in_credentials_iterator,
+                                                      cc_uint32                 *out_compat_version);
+
+cc_int32 cci_credentials_iterator_set_compat_version (cc_credentials_iterator_t io_credentials_iterator,
+                                                      cc_uint32                 in_compat_version);
+
 #endif /* CCAPI_CREDENTIALS_ITERATOR_H */
index 0036c70d31e6fc4d768abfa047b008fdf70fac47..8a25ae6e9fdd277e068933e652c3f8a4b40bdf6e 100644 (file)
  */
 
 #include "cci_common.h"
+#include "ccapi_string.h"
+#include "ccapi_context.h"
+#include "ccapi_ccache.h"
+#include "ccapi_ccache_iterator.h"
+#include "ccapi_credentials.h"
+#include "ccapi_credentials_iterator.h"
 #include <CredentialsCache2.h>
 
+infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN };
+
 /* ------------------------------------------------------------------------ */
 
-cc_result cc_shutdown (apiCB **io_context) 
+static cc_int32 cci_remap_version (cc_int32   in_v2_version,
+                                   cc_uint32 *out_v3_version) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!out_v3_version) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        if (in_v2_version == CC_CRED_V4) {
+            *out_v3_version = cc_credentials_v4;
+            
+        } else if (in_v2_version == CC_CRED_V5) { 
+            *out_v3_version = cc_credentials_v5;
+            
+        } else {
+            err = ccErrBadCredentialsVersion;
+        }
+    }
+    
+    return cci_check_error (err);
+}    
+
+/* ------------------------------------------------------------------------ */
+
+static cc_result cci_remap_error (cc_result in_error) 
+{
+    switch (in_error) {
+        case ccNoError:
+            return CC_NOERROR;
+            
+        case ccIteratorEnd:
+            return CC_END;
+            
+        case ccErrBadParam:
+        case ccErrInvalidCredentials:
+        case ccErrInvalidCCacheIterator:
+        case ccErrInvalidCredentialsIterator:
+        case ccErrBadLockType:
+            return CC_BAD_PARM;
+            
+        case ccErrNoMem:
+            return CC_NOMEM;
+            
+        case ccErrInvalidContext:
+        case ccErrInvalidCCache:
+        case ccErrCCacheNotFound:
+            return CC_NO_EXIST;
+            
+        case ccErrCredentialsNotFound:
+            return CC_NOTFOUND;
+            
+        case ccErrBadName:
+            return CC_BADNAME;
+            
+        case ccErrContextLocked:
+        case ccErrContextUnlocked:
+        case ccErrCCacheLocked:
+        case ccErrCCacheUnlocked:
+            return CC_LOCKED;
+            
+        case ccErrServerUnavailable:
+        case ccErrServerInsecure:
+            return CC_IO;
+            
+        default:
+            cci_debug_printf ("%s(): Unhandled error", __FUNCTION__);
+            return CC_BAD_PARM;
+    }
 }
 
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
 /* ------------------------------------------------------------------------ */
 
-cc_result cc_get_NC_info (apiCB    *in_context,
-                          infoNC ***out_info)
+cc_result cc_shutdown (apiCB **io_context) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!io_context) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_context_release (*io_context);
+    }
+    
+    if (!err) {
+        *io_context = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -47,9 +135,115 @@ cc_result cc_get_NC_info (apiCB    *in_context,
 cc_result cc_get_change_time (apiCB     *in_context,
                               cc_time_t *out_change_time) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context     ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_context_get_change_time (in_context, out_change_time);
+    }
+    
+    return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_get_NC_info (apiCB    *in_context,
+                          infoNC ***out_info)
+{
+    cc_result err = CC_NOERROR;
+    infoNC **info = NULL;
+    cc_uint64 count = 0; /* Preflight the size */
+    cc_uint64 i;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!out_info  ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        ccache_cit *iterator = NULL;
+        
+        err = cc_seq_fetch_NCs_begin (in_context, &iterator);
+        
+        while (!err) {
+            ccache_p *ccache = NULL;
+            
+            err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
+            
+            if (!err) { count++; }
+            
+            if (ccache) { cc_close (in_context, &ccache); }
+        }
+        if (err == CC_END) { err = CC_NOERROR; }
+        
+        if (!err) {
+            err = cc_seq_fetch_NCs_end (in_context, &iterator);
+        }    
+    }
+    
+    if (!err) {
+        info = malloc (sizeof (*info) * (count + 1));
+        if (info) { 
+            for (i = 0; i < count + 1; i++) { info[i] = NULL; }
+        } else { 
+            err = cci_check_error (CC_NOMEM); 
+        }
+    }
+    
+    if (!err) {
+        ccache_cit *iterator = NULL;
+        
+        err = cc_seq_fetch_NCs_begin (in_context, &iterator);
+        
+        for (i = 0; !err && i < count; i++) {
+            ccache_p *ccache = NULL;
+            infoNC *item = NULL;
+            
+            err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
+            
+            if (!err) {
+                info[i] = malloc (sizeof (*item));
+                if (info[i]) { 
+                    *info[i] = infoNC_initializer; 
+                } else {
+                    err = cci_check_error (CC_NOMEM); 
+                }
+            }
+            
+            if (!err) {
+                err = cc_get_name (in_context, ccache, &info[i]->name);
+            }
+            
+            if (!err) {
+                err = cc_get_principal (in_context, ccache, &info[i]->principal);
+            }
+            
+            if (!err) {
+                err = cc_get_cred_version (in_context, ccache, &info[i]->vers);
+            }
+            
+            if (ccache) { cc_close (in_context, &ccache); }
+        }
+        
+        if (!err) {
+            err = cc_seq_fetch_NCs_end (in_context, &iterator);
+        }
+    }
+    
+    if (!err) {
+        *out_info = info;
+        info = NULL;
+    }
+    
+    if (info) { cc_free_NC_info (in_context, &info); }
+    
+    return cci_check_error (err);
 }
 
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
 /* ------------------------------------------------------------------------ */
 
 cc_int32 cc_open (apiCB       *in_context,
@@ -58,7 +252,48 @@ cc_int32 cc_open (apiCB       *in_context,
                   cc_uint32    in_flags,
                   ccache_p   **out_ccache) 
 {    
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_ccache_t ccache = NULL;
+    cc_uint32 compat_version;
+    cc_uint32 real_version;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!in_name   ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_ccache) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_remap_version (in_version, &compat_version);
+    }
+
+    if (!err) {
+        err = ccapi_context_open_ccache (in_context, in_name, &ccache);
+    }
+    
+    /* We must not allow a CCAPI v2 caller to open a v5-only ccache
+     as a v4 ccache and vice versa. Allowing that would break 
+     (valid) assumptions made by CCAPI v2 callers. */
+    
+    if (!err) {
+        err = ccapi_ccache_get_credentials_version (ccache, &real_version);
+    } 
+    
+    if (!err) {
+        /* check the version and set up the ccache to use it */
+        if (compat_version & real_version) {
+            err = cci_ccache_set_compat_version (ccache, compat_version);
+        } else {
+            err = ccErrInvalidCCache;
+        }
+    }
+    
+    if (!err) {
+        *out_ccache = ccache;
+        ccache = NULL;
+    }
+    
+    if (ccache) { ccapi_ccache_release (ccache); }
+    
+    return cci_remap_error (err);
 }    
 
 /* ------------------------------------------------------------------------ */
@@ -70,7 +305,35 @@ cc_result cc_create (apiCB       *in_context,
                      cc_uint32    in_flags,
                      ccache_p   **out_ccache) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_ccache_t        ccache = NULL;
+    cc_uint32 compat_version;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!in_name   ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_ccache) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_remap_version (in_version, &compat_version);
+    }
+    
+    if (!err) {
+        err = ccapi_context_create_ccache (in_context, in_name, compat_version,
+                                           in_principal, &ccache);
+    }
+    
+    if (!err) {
+        err = cci_ccache_set_compat_version (ccache, compat_version);
+    }
+    
+    if (!err) {
+        *out_ccache = ccache;
+        ccache = NULL;
+    }
+    
+    if (ccache) { ccapi_ccache_release (ccache); }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -78,7 +341,20 @@ cc_result cc_create (apiCB       *in_context,
 cc_result cc_close (apiCB     *in_context,
                     ccache_p **io_ccache) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_ccache_release (*io_ccache);
+    }
+        
+    if (!err) {
+        *io_ccache = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -86,36 +362,20 @@ cc_result cc_close (apiCB     *in_context,
 cc_result cc_destroy (apiCB     *in_context,
                       ccache_p **io_ccache) 
 {
-    return CC_NOT_SUPP;
-}
-
-/* ------------------------------------------------------------------------ */
-
-cc_result cc_seq_fetch_NCs_begin (apiCB       *in_context,
-                                  ccache_cit **out_iterator) 
-{
-    return CC_NOT_SUPP;
-}
-
-/* ------------------------------------------------------------------------ */
-
-// CCache iterators need to return some ccaches twice (when v3 ccache has
-// two kinds of credentials). To do that, we use a single v3 iterator, but
-// sometimes don't advance it.
-
-cc_result cc_seq_fetch_NCs_next (apiCB       *in_context,
-                                 ccache_p   **out_ccache,
-                                 ccache_cit  *in_iterator) 
-{
-    return CC_NOT_SUPP;
-}
-
-/* ------------------------------------------------------------------------ */
-
-cc_result cc_seq_fetch_NCs_end (apiCB       *in_context,
-                                ccache_cit **io_iterator) 
-{
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_ccache_destroy (*io_ccache);
+    }
+    
+    if (!err) {
+        *io_ccache = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -124,7 +384,29 @@ cc_result cc_get_name (apiCB     *in_context,
                        ccache_p  *in_ccache,
                        char     **out_name) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_string_t name = NULL;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_name  ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_ccache_get_name (in_ccache, &name);
+    }
+    
+    if (!err) {
+        char *string = strdup (name->data);
+        if (string) { 
+            *out_name = string;
+        } else { 
+            err = cci_check_error (ccErrNoMem); 
+        }
+    }
+    
+    if (name) { ccapi_string_release (name); }
+    
+    return cci_remap_error (err);    
 }
 
 /* ------------------------------------------------------------------------ */
@@ -133,7 +415,30 @@ cc_result cc_get_cred_version (apiCB    *in_context,
                                ccache_p *in_ccache,
                                cc_int32 *out_version) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_uint32 compat_version;
+    
+    if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccache  ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_version) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_ccache_get_compat_version (in_ccache, &compat_version);
+    }
+    
+    if (!err) {
+        if (compat_version == cc_credentials_v4) {
+            *out_version = CC_CRED_V4;
+            
+        } else if (compat_version == cc_credentials_v5) { 
+            *out_version = CC_CRED_V5;
+            
+        } else {
+            err = ccErrBadCredentialsVersion;
+        }
+    }
+    
+    return cci_remap_error (err);    
 }
 
 /* ------------------------------------------------------------------------ */
@@ -143,7 +448,22 @@ cc_result cc_set_principal (apiCB    *in_context,
                             cc_int32  in_version,
                             char     *in_principal) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_uint32 version;
+    
+    if (!in_context  ) { err = cci_check_error (ccErrBadParam); }
+    if (!io_ccache   ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_principal) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_remap_version (in_version, &version);
+    }
+
+    if (!err) {
+        err = ccapi_ccache_set_principal (io_ccache, version, in_principal);
+    }
+    
+    return cci_remap_error (err);    
 }
 
 /* ------------------------------------------------------------------------ */
@@ -152,7 +472,34 @@ cc_result cc_get_principal (apiCB      *in_context,
                             ccache_p   *in_ccache,
                             char      **out_principal) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_uint32 compat_version;
+    cc_string_t principal = NULL;
+    
+    if (!in_context   ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccache    ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_principal) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_ccache_get_compat_version (in_ccache, &compat_version);
+    }
+    
+    if (!err) {
+        err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal);
+    }
+    
+    if (!err) {
+        char *string = strdup (principal->data);
+        if (string) { 
+            *out_principal = string;
+        } else { 
+            err = cci_check_error (ccErrNoMem); 
+        }
+    }
+    
+    if (principal) { ccapi_string_release (principal); }
+    
+    return cci_remap_error (err);    
 }
 
 /* ------------------------------------------------------------------------ */
@@ -161,7 +508,23 @@ cc_result cc_store (apiCB      *in_context,
                     ccache_p   *io_ccache,
                     cred_union  in_credentials) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_credentials_union *creds_union = NULL;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_cred_union_to_credentials_union (&in_credentials,
+                                                   &creds_union);
+    }
+    
+    if (!err) {
+        err = ccapi_ccache_store_credentials (io_ccache, creds_union);
+    }
+    
+    if (creds_union) { cci_credentials_union_release (creds_union); }
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -170,16 +533,207 @@ cc_result cc_remove_cred (apiCB      *in_context,
                           ccache_p   *in_ccache,
                           cred_union  in_credentials) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_credentials_iterator_t iterator = NULL;
+    
+    if (!in_context    ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccache     ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator);
+    }
+    
+    while (!err) {
+        cc_credentials_t creds = NULL;
+        cc_uint32 equal = 0;
+        
+        err = ccapi_credentials_iterator_next (iterator, &creds);
+        
+        if (!err) {
+            err = cci_cred_union_compare_to_credentials_union (&in_credentials, 
+                                                               creds->data,
+                                                               &equal);
+        }
+        
+        if (!err && equal) {
+            err = ccapi_ccache_remove_credentials (in_ccache, creds);
+        }
+        
+        ccapi_credentials_release (creds);
+    }
+    if (err) { err = cci_check_error (ccErrCredentialsNotFound); }
+    
+    return cci_remap_error (err);    
 }      
 
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_begin (apiCB       *in_context,
+                                  ccache_cit **out_iterator) 
+{
+    cc_result err = ccNoError;
+    cc_ccache_iterator_t iterator = NULL;
+    
+    if (!in_context  ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_context_new_ccache_iterator (in_context, &iterator);
+    }
+    
+    if (!err) {
+        *out_iterator = (ccache_cit *) iterator;
+        iterator = NULL; /* take ownership */
+    }
+    
+    if (iterator) { ccapi_ccache_iterator_release (iterator); }
+    
+    return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_next (apiCB       *in_context,
+                                 ccache_p   **out_ccache,
+                                 ccache_cit  *in_iterator) 
+{
+    cc_result err = ccNoError;
+    cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator;
+    cc_ccache_t ccache = NULL;
+    const char *saved_ccache_name;
+    
+    if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    /* CCache iterators need to return some ccaches twice (when v3 ccache has
+     * two kinds of credentials). To do that, we return such ccaches twice
+     * v4 first, then v5. */
+
+    if (!err) {
+        err = cci_ccache_iterator_get_saved_ccache_name (iterator,
+                                                         &saved_ccache_name);
+    }
+    
+    if (!err) {
+        if (saved_ccache_name) {
+            err = ccapi_context_open_ccache (in_context, saved_ccache_name, 
+                                             &ccache);
+            
+            if (!err) {
+                err = cci_ccache_set_compat_version (ccache, cc_credentials_v5);
+            }
+            
+            if (!err) {
+                err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL);
+            }
+            
+        } else {
+            cc_uint32 version = 0;
+            
+            err = ccapi_ccache_iterator_next (iterator, &ccache);
+            
+            if (!err) {
+                err = ccapi_ccache_get_credentials_version (ccache, &version);
+            }
+            
+            if (!err) {
+                if (version == cc_credentials_v4_v5) {
+                    cc_string_t name = NULL;
+                    
+                    err = cci_ccache_set_compat_version (ccache, cc_credentials_v4);
+                    
+                    if (!err) {                    
+                        err = ccapi_ccache_get_name (ccache, &name);
+                    } 
+                
+                    if (!err) {
+                        err = cci_ccache_iterator_set_saved_ccache_name (iterator,  
+                                                                         name->data);
+                    }
+                    
+                    if (name) { ccapi_string_release (name); }
+                    
+                } else {
+                    err = cci_ccache_set_compat_version (ccache, version);
+                }
+            }
+        }
+    }
+    
+    if (!err) {
+        *out_ccache = ccache;
+        ccache = NULL; /* take ownership */
+    }
+    
+    if (ccache) { ccapi_ccache_release (ccache); }
+        
+    return cci_remap_error (err);
+}
+
+/* ------------------------------------------------------------------------ */
+
+cc_result cc_seq_fetch_NCs_end (apiCB       *in_context,
+                                ccache_cit **io_iterator) 
+{
+    cc_result err = ccNoError;
+    cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) io_iterator;
+    
+    if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+    if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_ccache_iterator_release (iterator);
+    }
+    
+    return cci_remap_error (err);
+}
+
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
 /* ------------------------------------------------------------------------ */
 
 cc_result cc_seq_fetch_creds_begin (apiCB           *in_context,
                                     const ccache_p  *in_ccache,
                                     ccache_cit     **out_iterator) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_credentials_iterator_t iterator = NULL;
+    cc_uint32 compat_version;
+    
+    if (!in_context  ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_ccache   ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache, 
+                                             &compat_version);
+    }
+    
+    if (!err) {
+        err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache, 
+                                                     &iterator);
+    }
+    
+    if (!err) {
+        err = cci_credentials_iterator_set_compat_version (iterator, 
+                                                           compat_version);
+    }
+    
+    if (!err) {
+        *out_iterator = (ccache_cit *) iterator;
+        iterator = NULL; /* take ownership */
+    }
+    
+    if (iterator) { ccapi_credentials_iterator_release (iterator); }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -188,7 +742,35 @@ cc_result cc_seq_fetch_creds_next (apiCB       *in_context,
                                    cred_union **out_creds,
                                    ccache_cit  *in_iterator) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator;
+    cc_uint32 compat_version;
+    
+    if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+    if (!out_creds  ) { err = cci_check_error (ccErrBadParam); }
+    if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_credentials_iterator_get_compat_version (iterator, 
+                                                           &compat_version);
+    }
+
+    while (!err) {
+        cc_credentials_t credentials = NULL;
+        
+        err = ccapi_credentials_iterator_next (iterator, &credentials);
+        
+        if (!err && (credentials->data->version & compat_version)) {
+            /* got the next credentials for the correct version */
+            err = cci_credentials_union_to_cred_union (credentials->data, 
+                                                       out_creds);
+            break;
+        }
+        
+        if (credentials) { ccapi_credentials_release (credentials); }
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -196,15 +778,43 @@ cc_result cc_seq_fetch_creds_next (apiCB       *in_context,
 cc_result cc_seq_fetch_creds_end (apiCB       *in_context,
                                   ccache_cit **io_iterator) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    cc_credentials_iterator_t *iterator = (cc_credentials_iterator_t *) io_iterator;
+    
+    if (!in_context ) { err = cci_check_error (ccErrBadParam); }
+    if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = ccapi_credentials_iterator_release (*iterator);
+    }
+    
+    if (!err) {
+        *iterator = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
+#if TARGET_OS_MAC
+#pragma mark -
+#endif
+
 /* ------------------------------------------------------------------------ */
 
 cc_result cc_free_principal (apiCB  *in_context,
                              char  **io_principal) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context  ) { err = cci_check_error (ccErrBadParam); }
+    if (!io_principal) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        free (*io_principal);
+        *io_principal = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -212,7 +822,17 @@ cc_result cc_free_principal (apiCB  *in_context,
 cc_result cc_free_name (apiCB  *in_context,
                         char  **io_name) 
 {    
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!io_name   ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        free (*io_name);
+        *io_name = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -220,7 +840,17 @@ cc_result cc_free_name (apiCB  *in_context,
 cc_result cc_free_creds (apiCB       *in_context,
                          cred_union **io_credentials) 
 {
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context    ) { err = cci_check_error (ccErrBadParam); }
+    if (!io_credentials) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err) {
+        err = cci_cred_union_release (*io_credentials);
+        if (!err) { *io_credentials = NULL; } 
+    }
+    
+    return cci_remap_error (err);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -228,5 +858,24 @@ cc_result cc_free_creds (apiCB       *in_context,
 cc_result cc_free_NC_info (apiCB    *in_context,
                            infoNC ***io_info) 
 {    
-    return CC_NOT_SUPP;
+    cc_result err = ccNoError;
+    
+    if (!in_context) { err = cci_check_error (ccErrBadParam); }
+    if (!io_info   ) { err = cci_check_error (ccErrBadParam); }
+    
+    if (!err && *io_info) {
+        infoNC **data = *io_info;
+        int i;
+        
+        for (i = 0; data[i] != NULL; i++) {
+            cc_free_principal (in_context, &data[i]->principal);
+            cc_free_name (in_context, &data[i]->name);
+            free (data[i]);
+        }
+        free (data);
+        
+        *io_info = NULL;
+    }
+    
+    return cci_remap_error (err);
 }
index 04c8e21b57abbbf9bf674c8bae06e22ccfc60c0a..72721e68a1eb48d3f615970732c78f8d49e5dcda 100644 (file)
@@ -56,7 +56,7 @@ cc_int32 ccs_credentials_new (ccs_credentials_t      *out_credentials,
     }
     
     if (!err) {
-        err = cci_cred_union_read (&credentials->cred_union, in_stream);
+        err = cci_credentials_union_read (&credentials->cred_union, in_stream);
     }
     
     if (!err && !(credentials->cred_union->version & in_ccache_version)) {
@@ -89,7 +89,7 @@ cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials)
     cc_int32 err = ccNoError;
     
     if (!err && io_credentials) {
-        cci_cred_union_release (io_credentials->cred_union);
+        cci_credentials_union_release (io_credentials->cred_union);
         cci_identifier_release (io_credentials->identifier);
         free (io_credentials);
     }
@@ -112,7 +112,7 @@ cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials,
     }
     
     if (!err) {
-        err = cci_cred_union_write (in_credentials->cred_union, io_stream);
+        err = cci_credentials_union_write (in_credentials->cred_union, io_stream);
     }
     
     return cci_check_error (err);