1 #include <string.h>
2 #include "k5-platform.h"	/* pull in asprintf decl/defn */
3 #include "test_ccapi_v2.h"
4 #include <limits.h>
5 #include <time.h>
6 #include "test_ccapi_check.h"
7 #include "test_ccapi_util.h"
8 
9 // ---------------------------------------------------------------------------
10 
destroy_all_ccaches_v2(apiCB * context)11 static cc_result destroy_all_ccaches_v2(apiCB *context) {
12     cc_result err = CC_NOERROR;
13     infoNC **info = NULL;
14     int i = 0;
15 
16     err = cc_get_NC_info(context, &info);
17 
18     for (i = 0; !err && info[i]; i++) {
19         ccache_p *ccache = NULL;
20 
21         err = cc_open(context, info[i]->name, info[i]->vers, 0, &ccache);
22 
23         if (!err) { cc_destroy(context, &ccache); }
24     }
25 
26     if (info) { cc_free_NC_info(context, &info); }
27 
28     if (err) {
29         log_error("cc_get_NC_info or cc_open failed with %s (%d)", translate_ccapi_error(err), err);
30     }
31 
32     return err;
33 }
34 
35 // ---------------------------------------------------------------------------
36 // return zero when both unions are considered equal, non-zero when not
37 
compare_v5_creds_unions_compat(const cred_union * a,const cred_union * b)38 static int compare_v5_creds_unions_compat(const cred_union *a, const cred_union *b) {
39     int retval = -1;
40 
41     if (a && b && a->cred_type == b->cred_type) {
42         if (a->cred_type == CC_CRED_V5) {
43             if (!strcmp(a->cred.pV5Cred->client, b->cred.pV5Cred->client) &&
44                 !strcmp(a->cred.pV5Cred->server, b->cred.pV5Cred->server) &&
45                 a->cred.pV5Cred->starttime == b->cred.pV5Cred->starttime) {
46                 retval = 0;
47             }
48         }
49     }
50 
51     return retval;
52 }
53 
54 // ---------------------------------------------------------------------------
55 
new_v5_creds_union_compat(cred_union * out_union,const char * realm)56 static cc_result new_v5_creds_union_compat (cred_union *out_union, const char *realm)
57 {
58     cc_result err = CC_NOERROR;
59     cred_union *creds_union = NULL;
60     cc_credentials_v5_compat *v5creds = NULL;
61     static int num_runs = 1;
62     char *client = NULL;
63     char *server = NULL;
64 
65     if (!out_union) { err = CC_BAD_PARM; }
66 
67     if (!err) {
68         v5creds = malloc (sizeof (*v5creds));
69         if (!v5creds) {
70             err = CC_NOMEM;
71         }
72     }
73 
74     if (!err) {
75         asprintf(&client, "client@%s", realm);
76         asprintf(&server, "host/%d%s@%s", num_runs++, realm, realm);
77         if (!client || !server) {
78             err = CC_NOMEM;
79         }
80     }
81 
82     if (!err) {
83         v5creds->client = client;
84         v5creds->server = server;
85         v5creds->keyblock.type = 1;
86         v5creds->keyblock.length = 0;
87         v5creds->keyblock.data = NULL;
88         v5creds->authtime = time (NULL);
89         v5creds->starttime = time (NULL);
90         v5creds->endtime = time(NULL) + 1000;
91         v5creds->renew_till = time(NULL) + 10000;
92         v5creds->is_skey = 0;
93         v5creds->ticket_flags = TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE | TKT_FLG_RENEWABLE | TKT_FLG_INITIAL;
94         v5creds->addresses = NULL;
95         v5creds->ticket.type = 0;
96         v5creds->ticket.length = 0;
97         v5creds->ticket.data = NULL;
98         v5creds->second_ticket.type = 0;
99         v5creds->second_ticket.length = 0;
100         v5creds->second_ticket.data = NULL;
101         v5creds->authdata = NULL;
102     }
103 
104 
105     if (!err) {
106         creds_union = malloc (sizeof (*creds_union));
107         if (creds_union) {
108             creds_union->cred_type = CC_CRED_V5;
109             creds_union->cred.pV5Cred = v5creds;
110         } else {
111             err = CC_NOMEM;
112         }
113     }
114     if (!err) {
115         *out_union = *creds_union;
116         creds_union = NULL;
117     }
118 
119     return err;
120 }
121 
122 // ---------------------------------------------------------------------------
123 
release_v5_creds_union_compat(cred_union * creds_union)124 static void release_v5_creds_union_compat(cred_union *creds_union) {
125     cc_credentials_v5_compat *v5creds = NULL;
126 
127     if (creds_union) {
128         if (creds_union->cred.pV5Cred) {
129             v5creds = creds_union->cred.pV5Cred;
130             if (v5creds->client) { free(v5creds->client); }
131             if (v5creds->server) { free(v5creds->server); }
132             if (v5creds->keyblock.data) { free(v5creds->keyblock.data); }
133             if (v5creds->ticket.data) { free(v5creds->ticket.data); }
134             if (v5creds->second_ticket.data) { free(v5creds->second_ticket.data); }
135             free(v5creds);
136         }
137     }
138 }
139 
140 // ---------------------------------------------------------------------------
141 
check_cc_shutdown(void)142 int check_cc_shutdown(void) {
143     cc_result err = 0;
144     apiCB *context = NULL;
145 
146     BEGIN_TEST("cc_shutdown");
147 
148     // try with valid context
149     err = check_once_cc_shutdown(&context, CC_NOERROR, NULL);
150 
151     // try with NULL
152     err = check_once_cc_shutdown(NULL, CC_BAD_PARM, NULL);
153 
154     if (context) { cc_shutdown(&context); }
155 
156     END_TEST_AND_RETURN
157 }
158 
check_once_cc_shutdown(apiCB ** out_context,cc_result expected_err,const char * description)159 cc_result check_once_cc_shutdown(apiCB **out_context, cc_result expected_err, const char *description) {
160     cc_result err = 0;
161     apiCB *context = NULL;
162 
163     cc_result possible_return_values[2] = {
164         CC_NOERROR,
165         CC_BAD_PARM,
166     };
167 
168     BEGIN_CHECK_ONCE(description);
169 
170 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
171 
172     if (out_context) {
173         err = cc_initialize(out_context, ccapi_version_2, NULL, NULL);
174         if (!err) {
175             context = *out_context;
176         } else {
177             log_error("failure in cc_initialize, unable to perform check");
178             return err;
179         }
180     }
181 
182     if (!err) {
183         err = cc_shutdown(&context);
184         // check returned error
185         check_err(err, expected_err, possible_return_values);
186 
187     }
188 
189     if (out_context) {
190         *out_context = NULL;
191     }
192 
193     END_CHECK_ONCE;
194 
195     return err;
196 }
197 
198 // ---------------------------------------------------------------------------
199 
check_cc_get_change_time(void)200 int check_cc_get_change_time(void) {
201     cc_result err = 0;
202     apiCB *context = NULL;
203     cc_time_t last_change_time = 0;
204     ccache_p *ccache = NULL;
205     cred_union creds_union;
206 
207     BEGIN_TEST("cc_get_change_time");
208 
209     /*
210      * Make a context
211      * make sure the change time changes after:
212      * 	a ccache is created
213      * 	a ccache is destroyed
214      * 	a credential is stored
215      * 	a credential is removed
216      * 	a ccache principal is changed
217      * clean up memory
218      */
219 
220     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
221     if (!err) {
222 
223         // try bad parameters first
224         err = check_once_cc_get_change_time(context, NULL, CC_BAD_PARM, "NULL param, should fail");
225 
226         // get_change_time should always give something > 0
227         check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "first-run, should be > 0");
228 
229         // create a ccache
230         err = cc_create(context, "TEST_CCACHE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
231         if (err) {
232             log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err);
233             failure_count++;
234         }
235         check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after creating a new ccache");
236 
237         if (!err) {
238             // change principal
239             err = cc_set_principal(context, ccache, CC_CRED_V5, "foo@BAR.ORG");
240             if (err) {
241                 log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err);
242                 failure_count++;
243                 err = CC_NOERROR;
244             }
245         }
246         check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after changing a principle");
247 
248         new_v5_creds_union_compat(&creds_union, "BAR.ORG");
249 
250         // store a credential
251         if (!err) {
252             err = cc_store(context, ccache, creds_union);
253             if (err) {
254                 log_error("failed to store a credential - %s (%d)", translate_ccapi_error(err), err);
255                 failure_count++;
256                 err = CC_NOERROR;
257             }
258         }
259         check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after storing a credential");
260 
261         // remove a credential
262         if (!err) {
263             err = cc_remove_cred(context, ccache, creds_union);
264             if (err) {
265                 log_error("failed to remove a credential - %s (%d)", translate_ccapi_error(err), err);
266                 failure_count++;
267                 err = CC_NOERROR;
268             }
269         }
270         check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after removing a credential");
271 
272         release_v5_creds_union_compat(&creds_union);
273 
274         if (ccache) {
275             // destroy a ccache
276             err = cc_destroy(context, &ccache);
277             check_once_cc_get_change_time(context, &last_change_time, CC_NOERROR, "after destroying a ccache");
278         }
279     }
280 
281     if (context) { cc_shutdown(&context); }
282 
283     END_TEST_AND_RETURN
284 }
285 
286 // ---------------------------------------------------------------------------
287 
check_once_cc_get_change_time(apiCB * context,cc_time_t * last_time,cc_result expected_err,const char * description)288 cc_int32 check_once_cc_get_change_time(apiCB *context, cc_time_t *last_time, cc_result expected_err, const char *description) {
289     cc_result err = 0;
290     cc_time_t last_change_time;
291     cc_time_t current_change_time = 0;
292 
293     cc_result possible_return_values[3] = {
294         CC_NOERROR,
295         CC_BAD_PARM,
296         CC_NO_EXIST,
297     };
298 
299     BEGIN_CHECK_ONCE(description);
300 
301 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
302 
303     if (last_time != NULL) { // if we were passed NULL, then we're looking to pass a bad param
304         err = cc_get_change_time(context, &current_change_time);
305     } else {
306         err = cc_get_change_time(context, NULL);
307     }
308 
309     check_err(err, expected_err, possible_return_values);
310 
311     if (!err) {
312         last_change_time = *last_time;
313         check_if(current_change_time <= last_change_time, "context change time did not increase when it was supposed to (%d <= %d)", current_change_time, last_change_time);
314         *last_time = current_change_time;
315     }
316 
317     END_CHECK_ONCE;
318 
319     return err;
320 }
321 
322 // ---------------------------------------------------------------------------
323 
check_cc_open(void)324 int check_cc_open(void) {
325     cc_result err = 0;
326     apiCB *context = NULL;
327     ccache_p *ccache = NULL;
328     char *name = "TEST_OPEN_CCACHE";
329 
330     BEGIN_TEST("cc_open");
331 
332     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
333     if (!err) {
334         // create a ccache
335         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
336         if (err) {
337             log_error("failed to create a ccache - %s (%d)", translate_ccapi_error(err), err);
338             failure_count++;
339         }
340         if (!err) {
341             err = cc_close(context, &ccache);
342             ccache = NULL;
343         }
344 
345         // try default ccache
346         if (!err) {
347             err = check_once_cc_open(context, name, CC_CRED_V5, &ccache, CC_NOERROR, NULL);
348         }
349 
350         // try bad parameters
351         err = check_once_cc_open(context, NULL, CC_CRED_V5, &ccache, CC_BAD_PARM, NULL);
352         err = check_once_cc_open(context, name, CC_CRED_V5, NULL, CC_BAD_PARM, NULL);
353         err = check_once_cc_open(context, name, CC_CRED_UNKNOWN, &ccache, CC_ERR_CRED_VERSION, NULL);
354      }
355 
356     if (context) { cc_shutdown(&context); }
357 
358     END_TEST_AND_RETURN
359 }
360 
361 // ---------------------------------------------------------------------------
362 
check_once_cc_open(apiCB * context,const char * name,cc_int32 version,ccache_p ** ccache,cc_result expected_err,const char * description)363 cc_result check_once_cc_open(apiCB *context, const char *name, cc_int32 version, ccache_p **ccache, cc_result expected_err, const char *description) {
364     cc_result err = 0;
365     char *stored_name = NULL;
366 
367     cc_result possible_return_values[5] = {
368         CC_NOERROR,
369         CC_BAD_PARM,
370         CC_NO_EXIST,
371         CC_NOMEM,
372         CC_ERR_CRED_VERSION
373     };
374 
375     BEGIN_CHECK_ONCE(description);
376 
377 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
378 
379     if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param
380         err = cc_open(context, name, version, 0, ccache);
381     } else {
382         err = cc_open(context, name, version, 0, NULL);
383     }
384 
385     // check returned error
386     check_err(err, expected_err, possible_return_values);
387 
388     if (!err) {
389         check_if(*ccache == NULL, NULL);
390 
391         if (!err) {
392             err = cc_get_name(context, *ccache, &stored_name);
393         }
394         if (!err) {
395             check_if(strcmp(stored_name, name), NULL);
396         }
397         if (stored_name) { cc_free_name(context, &stored_name); }
398 
399 
400         if (ccache && *ccache) {
401             cc_ccache_release(*ccache);
402             *ccache = NULL;
403         }
404     }
405 
406     END_CHECK_ONCE;
407 
408     return err;
409 }
410 
411 // ---------------------------------------------------------------------------
412 
check_cc_create(void)413 int check_cc_create(void) {
414     cc_result err = 0;
415     apiCB *context = NULL;
416     ccache_p *ccache = NULL;
417     char *name = "TEST_CC_CREATE";
418 
419     BEGIN_TEST("cc_create");
420 
421     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
422     if (!err) {
423         if (!err) {
424             err = cc_open(context, name, CC_CRED_V5, 0, &ccache);
425             if (!err) {
426                 err = cc_destroy (context, &ccache);
427             } else {
428                 err = CC_NOERROR;  /* ccache does not exist */
429             }
430         }
431         // try making a ccache with a unique name (the now destroyed cache's name)
432         if (!err) {
433             err = check_once_cc_create(context, name, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_NOERROR, NULL);
434         }
435 
436         // try making a ccache with a non-unique name (the existing cache's name)
437         if (!err) {
438             err = check_once_cc_create(context, name, CC_CRED_V5, "foo/baz@BAR.ORG", &ccache, CC_NOERROR, NULL);
439         }
440 
441         // try bad parameters
442         err = check_once_cc_create(context, NULL, CC_CRED_V5, "foo@BAR.ORG", &ccache, CC_BAD_PARM, "NULL name");                    // NULL name
443         err = check_once_cc_create(context, "name", CC_CRED_MAX, "foo@BAR.ORG", &ccache, CC_ERR_CRED_VERSION, "invalid creds_vers"); // invalid creds_vers
444         err = check_once_cc_create(context, "name", CC_CRED_V5, NULL, &ccache, CC_BAD_PARM, "NULL principal");                          // NULL principal
445         err = check_once_cc_create(context, "name", CC_CRED_V5, "foo@BAR.ORG", NULL, CC_BAD_PARM, "NULL ccache");                    // NULL ccache
446     }
447 
448     if (ccache) { cc_destroy(context, &ccache); }
449     if (context) { cc_shutdown(&context); }
450 
451     END_TEST_AND_RETURN
452 }
453 
454 // ---------------------------------------------------------------------------
455 
check_once_cc_create(apiCB * context,const char * name,cc_int32 cred_vers,const char * principal,ccache_p ** ccache,cc_int32 expected_err,const char * description)456 cc_result check_once_cc_create(apiCB  *context, const char *name, cc_int32 cred_vers, const char *principal, ccache_p **ccache, cc_int32 expected_err, const char *description) {
457     cc_result err = 0;
458     char *stored_name = NULL;
459     char *stored_principal = NULL;
460     cc_int32 stored_creds_vers = 0;
461 
462     cc_result possible_return_values[6] = {
463         CC_NOERROR,
464         CC_BADNAME,
465         CC_BAD_PARM,
466         CC_NO_EXIST,
467         CC_NOMEM,
468         CC_ERR_CRED_VERSION,
469     };
470     BEGIN_CHECK_ONCE(description);
471 
472 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
473 
474     err = cc_create(context, name, principal, cred_vers, 0, ccache);
475 
476     // check returned error
477     check_err(err, expected_err, possible_return_values);
478 
479     if (!err) {
480         check_if(*ccache == NULL, NULL);
481 
482         // make sure all of the ccache's info matches what we gave it
483         // name
484         err = cc_get_name(context, *ccache, &stored_name);
485         if (!err) { check_if(strcmp(stored_name, name), NULL); }
486         if (stored_name) { cc_free_name(context, &stored_name); }
487         // cred_vers
488         err = cc_get_cred_version(context, *ccache, &stored_creds_vers);
489         if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
490         // principal
491         err = cc_get_principal(context, *ccache, &stored_principal);
492         if (!err) { check_if(strcmp(stored_principal, principal), NULL); }
493         if (stored_principal) { cc_free_principal(context, &stored_principal); }
494 
495         if (ccache && *ccache) {
496             cc_destroy(context, ccache);
497             *ccache = NULL;
498         }
499     }
500 
501     END_CHECK_ONCE;
502 
503     return err;
504 }
505 
506 // ---------------------------------------------------------------------------
507 
check_cc_close(void)508 int check_cc_close(void) {
509     cc_result err = 0;
510     apiCB *context = NULL;
511     ccache_p *ccache = NULL;
512     char *name = "TEST_CC_CLOSE";
513 
514     BEGIN_TEST("cc_close");
515 
516     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
517 
518     if (!err) {
519         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
520     }
521 
522     if (!err) {
523         check_once_cc_close(context, ccache, CC_NOERROR, NULL);
524         ccache = NULL;
525     }
526 
527     if (context) { cc_shutdown(&context); }
528 
529     END_TEST_AND_RETURN
530 }
531 
532 // ---------------------------------------------------------------------------
533 
check_once_cc_close(apiCB * context,ccache_p * ccache,cc_result expected_err,const char * description)534 cc_result check_once_cc_close(apiCB *context, ccache_p *ccache, cc_result expected_err, const char *description) {
535     cc_result err = CC_NOERROR;
536 
537     cc_result possible_return_values[2] = {
538         CC_NOERROR,
539         CC_BAD_PARM
540     };
541 
542     char *name = NULL;
543 
544     err = cc_get_name(context, ccache, &name);
545     err = cc_close(context, &ccache);
546     ccache = NULL;
547 
548     BEGIN_CHECK_ONCE(description);
549 
550 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
551 
552     // check returned error
553     check_err(err, expected_err, possible_return_values);
554 
555     if (!err && name) { // try opening released ccache to make sure it still exists
556         err = cc_open(context, name, CC_CRED_V5, 0, &ccache);
557     }
558     check_if(err == CC_NO_EXIST, "released ccache was actually destroyed instead");
559     check_if(err != CC_NOERROR, "released ccache cannot be opened");
560 
561     if (ccache) { cc_destroy(context, &ccache); }
562     if (name) { cc_free_name(context, &name); }
563 
564     END_CHECK_ONCE;
565 
566     return err;
567 }
568 
569 // ---------------------------------------------------------------------------
570 
check_cc_destroy(void)571 int check_cc_destroy(void) {
572     cc_result err = 0;
573     apiCB *context = NULL;
574     ccache_p *ccache = NULL;
575     char *name = "TEST_CC_DESTROY";
576 
577     BEGIN_TEST("cc_destroy");
578 
579     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
580 
581     if (!err) {
582         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
583     }
584 
585     if (!err) {
586         check_once_cc_destroy(context, ccache, CC_NOERROR, NULL);
587         ccache = NULL;
588     }
589 
590     if (context) { cc_shutdown(&context); }
591 
592     END_TEST_AND_RETURN
593 }
594 
595 // ---------------------------------------------------------------------------
596 
check_once_cc_destroy(apiCB * context,ccache_p * ccache,cc_int32 expected_err,const char * description)597 cc_result check_once_cc_destroy(apiCB *context, ccache_p *ccache, cc_int32 expected_err, const char *description) {
598     cc_result err = CC_NOERROR;
599 
600     cc_result possible_return_values[2] = {
601         CC_NOERROR,
602         CC_BAD_PARM,
603     };
604 
605     char *name = NULL;
606 
607     BEGIN_CHECK_ONCE(description);
608 
609 #ifdef cc_ccache_destroy
610 
611 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
612 
613     err = cc_get_name(context, ccache, &name);
614     err = cc_destroy(context, &ccache);
615     ccache = NULL;
616 
617     // check returned error
618     check_err(err, expected_err, possible_return_values);
619 
620     if (!err && name) { // try opening released ccache to make sure it still exists
621         err = cc_open(context, name, CC_CRED_V5, 0, &ccache);
622     }
623     check_if(err != CC_NO_EXIST, "destroyed ccache was actually released instead");
624 
625     if (ccache) { cc_destroy(context, &ccache); }
626     if (name) { cc_free_name(context, &name); }
627 
628 #endif /* cc_ccache_destroy */
629 
630     END_CHECK_ONCE;
631 
632     return err;
633 }
634 
635 // ---------------------------------------------------------------------------
636 
check_cc_get_cred_version(void)637 int check_cc_get_cred_version(void) {
638     cc_result err = 0;
639     apiCB *context = NULL;
640     ccache_p *ccache = NULL;
641     char *name = "TEST_CC_GET_CRED_VERSION_V5";
642 
643     BEGIN_TEST("cc_get_cred_version");
644 
645     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
646 
647     // try one created with v5 creds
648     if (!err) {
649         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
650     }
651     if (!err) {
652         check_once_cc_get_cred_version(context, ccache, CC_CRED_V5, CC_NOERROR, "v5 creds");
653     }
654     else {
655         log_error("cc_context_create_new_ccache failed, can't complete test");
656         failure_count++;
657     }
658 
659     if (ccache) {
660         cc_destroy(context, &ccache);
661         ccache = NULL;
662     }
663 
664     err = CC_NOERROR;
665 
666     if (ccache) {
667         cc_destroy(context, &ccache);
668         ccache = NULL;
669     }
670 
671     if (context) { cc_shutdown(&context); }
672 
673     END_TEST_AND_RETURN
674 }
675 
676 // ---------------------------------------------------------------------------
677 
check_once_cc_get_cred_version(apiCB * context,ccache_p * ccache,cc_int32 expected_cred_vers,cc_int32 expected_err,const char * description)678 cc_result check_once_cc_get_cred_version(apiCB *context, ccache_p *ccache, cc_int32 expected_cred_vers, cc_int32 expected_err, const char *description) {
679     cc_result err = CC_NOERROR;
680 
681     cc_result possible_return_values[3] = {
682         CC_NOERROR,
683         CC_BAD_PARM,
684         CC_NO_EXIST,
685     };
686 
687     cc_int32 stored_cred_vers = 0;
688 
689     BEGIN_CHECK_ONCE(description);
690 
691 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
692 
693     err = cc_get_cred_version(context, ccache, &stored_cred_vers);
694 
695     // check returned error
696     check_err(err, expected_err, possible_return_values);
697 
698     if (!err) {
699         check_if(stored_cred_vers != expected_cred_vers, NULL);
700     }
701 
702     END_CHECK_ONCE;
703 
704     return err;
705 }
706 
707 // ---------------------------------------------------------------------------
708 
check_cc_get_name(void)709 int check_cc_get_name(void) {
710     cc_result err = 0;
711     apiCB *context = NULL;
712     ccache_p *ccache = NULL;
713 
714     BEGIN_TEST("cc_get_name");
715 
716     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
717 
718     if (!err) {
719         err = destroy_all_ccaches_v2(context);
720     }
721 
722     // try with unique ccache (which happens to be default)
723     if (!err) {
724         err = cc_create(context, "0", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
725     }
726     if (!err) {
727         check_once_cc_get_name(context, ccache, "0", CC_NOERROR, "unique ccache (which happens to be default)");
728     }
729     else {
730         log_error("cc_context_create_ccache failed, can't complete test");
731         failure_count++;
732     }
733     if (ccache) {
734         cc_close(context, &ccache);
735         ccache = NULL;
736     }
737 
738     // try with unique ccache (which is not default)
739     if (!err) {
740         err = cc_context_create_ccache(context, "1", CC_CRED_V5, "foo@BAR.ORG", &ccache);
741     }
742     if (!err) {
743         check_once_cc_get_name(context, ccache, "1", CC_NOERROR, "unique ccache (which is not default)");
744     }
745     else {
746         log_error("cc_context_create_ccache failed, can't complete test");
747         failure_count++;
748     }
749 
750     // try with bad param
751     if (!err) {
752         check_once_cc_get_name(context, ccache, NULL, CC_BAD_PARM, "NULL param");
753     }
754     if (ccache) {
755         cc_close(context, &ccache);
756         ccache = NULL;
757     }
758 
759     if (context) {
760         err = destroy_all_ccaches_v2(context);
761         cc_shutdown(&context);
762     }
763 
764     END_TEST_AND_RETURN
765 }
766 
767 // ---------------------------------------------------------------------------
768 
check_once_cc_get_name(apiCB * context,ccache_p * ccache,const char * expected_name,cc_int32 expected_err,const char * description)769 cc_int32 check_once_cc_get_name(apiCB *context, ccache_p *ccache, const char *expected_name, cc_int32 expected_err, const char *description) {
770     cc_result err = CC_NOERROR;
771 
772     cc_result possible_return_values[4] = {
773         CC_NOERROR,
774         CC_NOMEM,
775         CC_BAD_PARM,
776         CC_NO_EXIST,
777     };
778 
779     char *stored_name = NULL;
780 
781     BEGIN_CHECK_ONCE(description);
782 
783 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
784 
785     if (expected_name == NULL) { // we want to try with a NULL param
786         err = cc_get_name(context, ccache, NULL);
787     }
788     else {
789         err = cc_get_name(context, ccache, &stored_name);
790     }
791 
792     // check returned error
793     check_err(err, expected_err, possible_return_values);
794 
795     if (!err) {
796         check_if(strcmp(stored_name, expected_name), NULL);
797     }
798 
799     if (stored_name) { cc_free_name(context, &stored_name); }
800 
801     END_CHECK_ONCE;
802 
803     return err;
804 }
805 
806 
807 // ---------------------------------------------------------------------------
808 
check_cc_get_principal(void)809 int check_cc_get_principal(void) {
810     cc_result err = 0;
811     apiCB *context = NULL;
812     ccache_p *ccache = NULL;
813     char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5";
814 
815     BEGIN_TEST("cc_get_principal");
816 
817     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
818 
819     if (!err) {
820         err = destroy_all_ccaches_v2(context);
821     }
822 
823     // try with krb5 principal
824     if (!err) {
825         err = cc_create(context, name_v5, "foo/BAR@BAZ.ORG", CC_CRED_V5, 0, &ccache);
826     }
827     if (!err) {
828         check_once_cc_get_principal(context, ccache, "foo/BAR@BAZ.ORG", CC_NOERROR, "trying to get krb5 princ for krb5 ccache");
829     }
830     else {
831         log_error("cc_create failed, can't complete test");
832         failure_count++;
833     }
834     if (ccache) {
835         cc_close(context, &ccache);
836         ccache = NULL;
837     }
838 
839     // try with bad param
840     if (!err) {
841         check_once_cc_get_principal(context, ccache, NULL, CC_BAD_PARM, "passed null out param");
842     }
843 
844     if (ccache) {
845         cc_close(context, &ccache);
846         ccache = NULL;
847     }
848 
849     if (context) {
850         err = destroy_all_ccaches_v2(context);
851         cc_shutdown(&context);
852     }
853 
854     END_TEST_AND_RETURN
855 }
856 
857 // ---------------------------------------------------------------------------
858 
check_once_cc_get_principal(apiCB * context,ccache_p * ccache,const char * expected_principal,cc_int32 expected_err,const char * description)859 cc_result check_once_cc_get_principal(apiCB *context,
860                                       ccache_p *ccache,
861                                       const char *expected_principal,
862                                       cc_int32 expected_err,
863                                       const char *description) {
864     cc_result err = CC_NOERROR;
865     char *stored_principal = NULL;
866 
867     cc_result possible_return_values[4] = {
868         CC_NOERROR,
869         CC_NOMEM,
870         CC_NO_EXIST,
871         CC_BAD_PARM
872     };
873 
874     BEGIN_CHECK_ONCE(description);
875 
876 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
877 
878     if (expected_principal == NULL) { // we want to try with a NULL param
879         err = cc_get_principal(context, ccache, NULL);
880     }
881     else {
882         err = cc_get_principal(context, ccache, &stored_principal);
883     }
884 
885     // check returned error
886     check_err(err, expected_err, possible_return_values);
887 
888     if (!err) {
889         check_if(strcmp(stored_principal, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal);
890     }
891 
892     if (stored_principal) { cc_free_principal(context, &stored_principal); }
893 
894     END_CHECK_ONCE;
895 
896     return err;
897 }
898 
899 // ---------------------------------------------------------------------------
900 
check_cc_set_principal(void)901 int check_cc_set_principal(void) {
902     cc_result err = 0;
903     apiCB *context = NULL;
904     ccache_p *ccache = NULL;
905     char *name_v5 = "TEST_CC_GET_PRINCIPAL_V5";
906 
907     BEGIN_TEST("cc_set_principal");
908 
909     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
910 
911     if (!err) {
912         err = destroy_all_ccaches_v2(context);
913     }
914 
915     // bad params
916     if (!err) {
917         err = cc_create(context, name_v5, "foo@BAZ.ORG", CC_CRED_V5, 0, &ccache);
918     }
919     if (!err) {
920         check_once_cc_set_principal(context, ccache, CC_CRED_MAX, "foo/BAZ@BAR.ORG", CC_ERR_CRED_VERSION, "CC_CRED_MAX (not allowed)");
921         check_once_cc_set_principal(context, ccache, CC_CRED_V5, NULL, CC_BAD_PARM, "NULL principal");
922     }
923     else {
924         log_error("cc_create failed, can't complete test");
925         failure_count++;
926     }
927     if (ccache) {
928         cc_destroy(context, &ccache);
929         ccache = NULL;
930     }
931 
932     if (ccache) {
933         cc_destroy(context, &ccache);
934         ccache = NULL;
935     }
936 
937     if (context) {
938         err = destroy_all_ccaches_v2(context);
939         cc_shutdown(&context);
940     }
941 
942     END_TEST_AND_RETURN
943 }
944 
945 // ---------------------------------------------------------------------------
946 
check_once_cc_set_principal(apiCB * context,ccache_p * ccache,cc_int32 cred_vers,const char * in_principal,cc_int32 expected_err,const char * description)947 cc_int32 check_once_cc_set_principal(apiCB *context, ccache_p *ccache, cc_int32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) {
948     cc_result err = CC_NOERROR;
949     char *stored_principal = NULL;
950 
951     cc_result possible_return_values[5] = {
952         CC_NOERROR,
953         CC_NOMEM,
954         CC_NO_EXIST,
955         CC_ERR_CRED_VERSION,
956         CC_BAD_PARM
957     };
958 
959     BEGIN_CHECK_ONCE(description);
960 
961 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
962 
963     err = cc_set_principal(context, ccache, cred_vers, (char *) in_principal);
964 
965     // check returned error
966     check_err(err, expected_err, possible_return_values);
967 
968     if (!err) {
969         err = cc_get_principal(context, ccache, &stored_principal);
970     }
971 
972     // compare stored with input
973     if (!err) {
974         check_if(strcmp(stored_principal, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal);
975     }
976 
977     if (stored_principal) { cc_free_principal(context, &stored_principal); }
978 
979     END_CHECK_ONCE;
980 
981     return err;
982 }
983 
984 // ---------------------------------------------------------------------------
985 
check_cc_store(void)986 int check_cc_store(void) {
987     cc_result err = 0;
988     apiCB *context = NULL;
989     ccache_p *ccache = NULL;
990     ccache_p *dup_ccache = NULL;
991     cred_union creds_union;
992     char *name = NULL;
993 
994     BEGIN_TEST("cc_store");
995 
996     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
997 
998     if (!err) {
999         err = destroy_all_ccaches_v2(context);
1000     }
1001 
1002     if (!err) {
1003         err = cc_create(context, "TEST_CC_STORE", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1004     }
1005 
1006     // cred with matching version and realm
1007     if (!err) {
1008         err = new_v5_creds_union_compat(&creds_union, "BAR.ORG");
1009 
1010         if (!err) {
1011             check_once_cc_store(context, ccache, creds_union, CC_NOERROR, "ok creds");
1012             release_v5_creds_union_compat(&creds_union);
1013         }
1014     }
1015 
1016     // invalid creds
1017     if (!err) {
1018         err = new_v5_creds_union_compat(&creds_union, "BAR.ORG");
1019 
1020         if (!err) {
1021             if (creds_union.cred.pV5Cred->client) {
1022                 free(creds_union.cred.pV5Cred->client);
1023                 creds_union.cred.pV5Cred->client = NULL;
1024             }
1025             check_once_cc_store(context, ccache, creds_union, CC_BAD_PARM, "invalid creds (NULL client string)");
1026 
1027             release_v5_creds_union_compat(&creds_union);
1028         }
1029     }
1030 
1031     // non-existent ccache
1032     if (ccache) {
1033         err = cc_get_name(context, ccache, &name);
1034         if (!err) {
1035             err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache);
1036         }
1037         if (name) { cc_free_name(context, &name); }
1038         if (dup_ccache) { cc_destroy(context, &dup_ccache); }
1039     }
1040 
1041     if (!err) {
1042         err = new_v5_creds_union_compat(&creds_union, "BAR.ORG");
1043 
1044         if (!err) {
1045             check_once_cc_store(context, ccache, creds_union, CC_NO_EXIST, "invalid ccache");
1046 
1047             release_v5_creds_union_compat(&creds_union);
1048         }
1049     }
1050 
1051     if (ccache) { cc_close(context, &ccache); }
1052     if (context) {
1053         destroy_all_ccaches_v2(context);
1054         cc_shutdown(&context);
1055     }
1056 
1057     END_TEST_AND_RETURN
1058 }
1059 
1060 // ---------------------------------------------------------------------------
1061 
check_once_cc_store(apiCB * context,ccache_p * ccache,const cred_union in_creds,cc_int32 expected_err,const char * description)1062 cc_result check_once_cc_store(apiCB *context, ccache_p *ccache, const cred_union in_creds, cc_int32 expected_err, const char *description) {
1063     cc_result err = CC_NOERROR;
1064     ccache_cit *iterator = NULL;
1065     int found = 0;
1066 
1067     cc_result possible_return_values[5] = {
1068         CC_NOERROR,
1069         CC_BAD_PARM,
1070         CC_ERR_CACHE_FULL,
1071         CC_ERR_CRED_VERSION,
1072         CC_NO_EXIST
1073     };
1074 
1075     BEGIN_CHECK_ONCE(description);
1076 
1077 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1078 
1079     err = cc_store(context, ccache, in_creds);
1080 
1081     // check returned error
1082     check_err(err, expected_err, possible_return_values);
1083 
1084     // make sure credentials were truly stored
1085     if (!err) {
1086         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1087     }
1088     while (!err && !found) {
1089         cred_union *creds = NULL;
1090 
1091         err = cc_seq_fetch_creds_next(context, &creds, iterator);
1092         if (!err) {
1093             found = !compare_v5_creds_unions_compat(&in_creds, creds);
1094         }
1095 
1096         if (creds) { cc_free_creds(context, &creds); }
1097     }
1098 
1099     if (err == CC_END) {
1100         check_if(found, "stored credentials not found in ccache");
1101         err = CC_NOERROR;
1102     }
1103 
1104     if (iterator) { cc_seq_fetch_creds_end(context, &iterator); }
1105 
1106     END_CHECK_ONCE;
1107 
1108     return err;
1109 }
1110 
1111 // ---------------------------------------------------------------------------
1112 
check_cc_remove_cred(void)1113 int check_cc_remove_cred(void) {
1114     cc_result err = 0;
1115     apiCB *context = NULL;
1116     ccache_p *ccache = NULL;
1117     cred_union *creds_array[10];
1118     ccache_cit *iterator = NULL;
1119     char *name = NULL;
1120     unsigned int i;
1121 
1122     BEGIN_TEST("cc_remove_cred");
1123 
1124     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1125 
1126     if (!err) {
1127         err = destroy_all_ccaches_v2(context);
1128     }
1129 
1130     if (!err) {
1131         err = cc_create(context, "TEST_CC_REMOVE_CRED", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1132     }
1133 
1134     // store 10 creds and retrieve their cc_credentials_t representations
1135     for(i = 0; !err && (i < 10); i++) {
1136         cred_union creds;
1137 
1138         new_v5_creds_union_compat(&creds, "BAR.ORG");
1139         err = cc_store(context, ccache, creds);
1140         if (err) {
1141             log_error("failure to store creds_union in remove_creds test");
1142         }
1143         release_v5_creds_union_compat(&creds);
1144     }
1145 
1146     if (!err) {
1147         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1148     }
1149 
1150     for (i = 0; !err && i < 10; i++) {
1151         creds_array[i] = NULL;
1152         err = cc_seq_fetch_creds_next(context, &creds_array[i], iterator);
1153     }
1154     if (err == CC_END) { err = CC_NOERROR; }
1155 
1156     // remove 10 valid creds
1157     for (i = 0; !err && (i < 10); i++) {
1158         check_once_cc_remove_cred(context, ccache, *creds_array[i], CC_NOERROR, "10 ok creds");
1159     }
1160 
1161     // non-existent creds (remove same one twice)
1162     check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NOTFOUND, "removed same creds twice");
1163 
1164     // non-existent ccache
1165     if (ccache) {
1166         ccache_p *dup_ccache = NULL;
1167 
1168         err = cc_get_name(context, ccache, &name);
1169 
1170         if (!err) {
1171             err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache);
1172         }
1173 
1174         if (!err) {
1175             err = cc_destroy(context, &dup_ccache);
1176             check_once_cc_remove_cred(context, ccache, *creds_array[0], CC_NO_EXIST, "invalid ccache");
1177         }
1178 
1179         if (name) { cc_free_name(context, &name); }
1180     }
1181 
1182      for(i = 0; i < 10 && creds_array[i]; i++) {
1183         cc_free_creds(context, &creds_array[i]);
1184     }
1185 
1186 
1187     if (iterator) { cc_seq_fetch_creds_end(context, &iterator); iterator = NULL; }
1188     if (ccache) { cc_close(context, &ccache); }
1189     if (context) {
1190         destroy_all_ccaches_v2(context);
1191         cc_shutdown(&context);
1192     }
1193 
1194     END_TEST_AND_RETURN
1195 }
1196 
1197 // ---------------------------------------------------------------------------
1198 
check_once_cc_remove_cred(apiCB * context,ccache_p * ccache,cred_union in_creds,cc_int32 expected_err,const char * description)1199 cc_result check_once_cc_remove_cred(apiCB *context, ccache_p *ccache, cred_union in_creds, cc_int32 expected_err, const char *description) {
1200     cc_result err = CC_NOERROR;
1201     ccache_cit *iterator = NULL;
1202     int found = 0;
1203 
1204     cc_result possible_return_values[5] = {
1205         CC_NOERROR,
1206         CC_BAD_PARM,
1207         CC_ERR_CRED_VERSION,
1208         CC_NOTFOUND,
1209         CC_NO_EXIST
1210     };
1211 
1212     BEGIN_CHECK_ONCE(description);
1213 
1214 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1215 
1216     err = cc_remove_cred(context, ccache, in_creds);
1217 
1218     // check returned error
1219     check_err(err, expected_err, possible_return_values);
1220 
1221     // make sure credentials were truly stored
1222     if (!err) {
1223         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1224     }
1225 
1226     while (!err && !found) {
1227         cred_union *creds = NULL;
1228 
1229         err = cc_seq_fetch_creds_next(context, &creds, iterator);
1230         if (!err) {
1231             found = !compare_v5_creds_unions_compat(&in_creds, creds);
1232         }
1233 
1234         if (creds) { cc_free_creds(context, &creds); }
1235     }
1236 
1237     if (err == CC_END) {
1238         check_if(found, "credentials not removed from ccache");
1239         err = CC_NOERROR;
1240     }
1241 
1242     if (iterator) { cc_seq_fetch_creds_end(context, &iterator); }
1243 
1244     END_CHECK_ONCE;
1245 
1246     return err;
1247 }
1248 
1249 // ---------------------------------------------------------------------------
1250 
check_cc_seq_fetch_NCs_begin(void)1251 int check_cc_seq_fetch_NCs_begin(void) {
1252     cc_result err = 0;
1253     apiCB *context = NULL;
1254     ccache_p *ccache = NULL;
1255     ccache_cit *iterator = NULL;
1256 
1257     BEGIN_TEST("cc_seq_fetch_NCs_begin");
1258 
1259     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1260     if (!err) {
1261         err = destroy_all_ccaches_v2(context);
1262     }
1263     if (!err) {
1264         // try making when there are no existing ccaches (shouldn't make a difference, but just in case)
1265         check_once_cc_seq_fetch_NCs_begin(context, &iterator, CC_NOERROR, "when there are no existing ccaches");
1266 
1267         err = cc_create(context, "TEST_CC_SEQ_FETCH_NCS_BEGIN", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1268     }
1269     if (!err) {
1270         // try making when at least one ccache already exists (just to cover all our bases)
1271         check_once_cc_seq_fetch_NCs_begin(context, &iterator, CC_NOERROR, "when at least one ccache already exists");
1272 
1273         // try bad parameters
1274         check_once_cc_seq_fetch_NCs_begin(context, NULL, CC_BAD_PARM, "NULL param"); // NULL iterator
1275     }
1276     // we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite
1277 
1278     if (ccache ) { cc_close(context, &ccache); }
1279     if (context) { cc_shutdown(&context); }
1280 
1281     END_TEST_AND_RETURN
1282 }
1283 
1284 // ---------------------------------------------------------------------------
1285 
check_once_cc_seq_fetch_NCs_begin(apiCB * context,ccache_cit ** iterator,cc_result expected_err,const char * description)1286 cc_result check_once_cc_seq_fetch_NCs_begin(apiCB *context, ccache_cit **iterator, cc_result expected_err, const char *description) {
1287     cc_result err = CC_NOERROR;
1288 
1289     cc_result possible_return_values[4] = {
1290         CC_NOERROR,
1291         CC_BAD_PARM,
1292         CC_NOMEM,
1293         CC_NO_EXIST
1294     };
1295 
1296     BEGIN_CHECK_ONCE(description);
1297 
1298 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1299 
1300      err = cc_seq_fetch_NCs_begin(context, iterator);
1301 
1302     // check returned error
1303     check_err(err, expected_err, possible_return_values);
1304 
1305     // we'll do a comprehensive test of cc_ccache_iterator related functions later
1306 
1307     return err;
1308 }
1309 
1310 // ---------------------------------------------------------------------------
1311 
check_cc_seq_fetch_NCs_next(void)1312 int check_cc_seq_fetch_NCs_next(void) {
1313     cc_result err = 0;
1314     apiCB *context = NULL;
1315     ccache_p *ccache = NULL;
1316     ccache_cit *iterator = NULL;
1317     unsigned int i;
1318 
1319     BEGIN_TEST("cc_seq_fetch_NCs_next");
1320 
1321     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1322 
1323     if (!err) {
1324         err = destroy_all_ccaches_v2(context);
1325     }
1326 
1327     // iterate with no ccaches
1328     if (!err) {
1329         err = cc_seq_fetch_NCs_begin(context, &iterator);
1330     }
1331     check_once_cc_seq_fetch_NCs_next(context, iterator, 0, CC_NOERROR, "iterating over an empty collection");
1332     if (iterator) {
1333         cc_seq_fetch_creds_end(context, &iterator);
1334         iterator = NULL;
1335     }
1336 
1337     // iterate with one ccache
1338     if (!err) {
1339         destroy_all_ccaches_v2(context);
1340         err = cc_create(context, "TEST_CC_SEQ_FETCH_NCS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1341     }
1342     if (ccache) {
1343         cc_close(context, &ccache);
1344         ccache = NULL;
1345     }
1346     if (!err) {
1347         err = cc_seq_fetch_NCs_begin(context, &iterator);
1348     }
1349     check_once_cc_seq_fetch_NCs_next(context, iterator, 1, CC_NOERROR, "iterating over a collection of 1 ccache");
1350     if (iterator) {
1351         cc_seq_fetch_creds_end(context, &iterator);
1352         iterator = NULL;
1353     }
1354 
1355     // iterate with several ccaches
1356     if (!err) {
1357         destroy_all_ccaches_v2(context);
1358     }
1359     for(i = 0; !err && (i < 1000); i++)
1360     {
1361         char *name = NULL;
1362 
1363         if (i%100 == 0) fprintf(stdout, ".");
1364         asprintf (&name, "TEST_CC_SEQ_FETCH_NCS_NEXT_%d", i);
1365         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1366         if (ccache) {
1367             cc_close(context, &ccache);
1368             ccache = NULL;
1369         }
1370         free (name);
1371     }
1372     if (!err) {
1373         err = cc_seq_fetch_NCs_begin(context, &iterator);
1374     }
1375     check_once_cc_seq_fetch_NCs_next(context, iterator, 1000, CC_NOERROR, "iterating over a collection of 1000 ccache");
1376     if (iterator) {
1377         cc_seq_fetch_creds_end(context, &iterator);
1378         iterator = NULL;
1379     }
1380 
1381 
1382     if (ccache) { cc_close(context, &ccache); }
1383     if (iterator) { cc_seq_fetch_creds_end(context, &iterator); }
1384     if (context) {
1385         destroy_all_ccaches_v2(context);
1386         cc_shutdown(&context);
1387     }
1388 
1389     END_TEST_AND_RETURN
1390 }
1391 
1392 // ---------------------------------------------------------------------------
1393 
check_once_cc_seq_fetch_NCs_next(apiCB * context,ccache_cit * iterator,cc_uint32 expected_count,cc_result expected_err,const char * description)1394 cc_result check_once_cc_seq_fetch_NCs_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description) {
1395     cc_result err = CC_NOERROR;
1396 
1397     cc_result possible_return_values[5] = {
1398         CC_NOERROR,
1399         CC_END,
1400         CC_BAD_PARM,
1401         CC_NOMEM,
1402         CC_NO_EXIST
1403     };
1404 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1405 
1406     ccache_p *ccache = NULL;
1407     cc_uint32 actual_count = 0;
1408 
1409     BEGIN_CHECK_ONCE(description);
1410 
1411     while (!err) {
1412         err = cc_seq_fetch_NCs_next(context, &ccache, iterator);
1413         if (ccache) {
1414             actual_count++;
1415             cc_close(context, &ccache);
1416             ccache = NULL;
1417         }
1418     }
1419     if (err == CC_END) {
1420         err = CC_NOERROR;
1421     }
1422 
1423     // check returned error
1424     check_err(err, expected_err, possible_return_values);
1425 
1426     check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches");
1427 
1428     END_CHECK_ONCE;
1429 
1430     return err;
1431 }
1432 
1433 // ---------------------------------------------------------------------------
1434 
check_cc_get_NC_info(void)1435 int check_cc_get_NC_info(void) {
1436     cc_result err = 0;
1437     apiCB *context = NULL;
1438     ccache_p *ccache = NULL;
1439     unsigned int i;
1440 
1441     BEGIN_TEST("cc_get_NC_info");
1442 
1443     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1444 
1445     if (!err) {
1446         err = destroy_all_ccaches_v2(context);
1447     }
1448 
1449     // iterate with no ccaches
1450     check_once_cc_get_NC_info(context, "", "", CC_CRED_MAX, 0, CC_NOERROR, "iterating over an empty collection");
1451 
1452     // iterate with one ccache
1453     if (!err) {
1454         destroy_all_ccaches_v2(context);
1455         err = cc_create(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1456     }
1457     if (ccache) {
1458         cc_close(context, &ccache);
1459         ccache = NULL;
1460     }
1461     check_once_cc_get_NC_info(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 1, CC_NOERROR, "iterating over a collection of 1 ccache");
1462 
1463     // iterate with several ccaches
1464     if (!err) {
1465         destroy_all_ccaches_v2(context);
1466     }
1467     for(i = 0; !err && (i < 1000); i++)
1468     {
1469         char *name = NULL;
1470 
1471         if (i%100 == 0) fprintf(stdout, ".");
1472         asprintf (&name, "TEST_CC_GET_NC_INFO_%d", i);
1473         err = cc_create(context, name, "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1474         if (ccache) {
1475             cc_close(context, &ccache);
1476             ccache = NULL;
1477         }
1478         free (name);
1479     }
1480     check_once_cc_get_NC_info(context, "TEST_CC_GET_NC_INFO", "foo@BAR.ORG", CC_CRED_V5, 1000, CC_NOERROR, "iterating over a collection of 1000 ccache");
1481 
1482     if (ccache) { cc_close(context, &ccache); }
1483     if (context) {
1484         destroy_all_ccaches_v2(context);
1485         cc_shutdown(&context);
1486     }
1487 
1488     END_TEST_AND_RETURN
1489 }
1490 
1491 // ---------------------------------------------------------------------------
1492 
check_once_cc_get_NC_info(apiCB * context,const char * expected_name_prefix,const char * expected_principal,cc_int32 expected_version,cc_uint32 expected_count,cc_result expected_err,const char * description)1493 cc_result check_once_cc_get_NC_info(apiCB *context,
1494                                     const char *expected_name_prefix,
1495                                     const char *expected_principal,
1496                                     cc_int32 expected_version,
1497                                     cc_uint32 expected_count,
1498                                     cc_result expected_err,
1499                                     const char *description) {
1500     cc_result err = CC_NOERROR;
1501     infoNC **info = NULL;
1502 
1503     cc_result possible_return_values[4] = {
1504         CC_NOERROR,
1505         CC_BAD_PARM,
1506         CC_NOMEM,
1507         CC_NO_EXIST
1508     };
1509 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1510 
1511     cc_uint32 actual_count = 0;
1512 
1513     BEGIN_CHECK_ONCE(description);
1514 
1515     err = cc_get_NC_info(context, &info);
1516 
1517     for (actual_count = 0; !err && info[actual_count]; actual_count++) {
1518         check_if(strncmp(info[actual_count]->name, expected_name_prefix, strlen(expected_name_prefix)), "got incorrect ccache name");
1519         check_if(strcmp(info[actual_count]->principal, expected_principal), "got incorrect principal name");
1520         check_if(info[actual_count]->vers != expected_version, "got incorrect cred version");
1521     }
1522 
1523     // check returned error
1524     check_err(err, expected_err, possible_return_values);
1525 
1526     check_if(actual_count != expected_count, "NC info didn't list all ccaches");
1527 
1528     if (info) { cc_free_NC_info (context, &info); }
1529     END_CHECK_ONCE;
1530 
1531     return err;
1532 }
1533 
1534 // ---------------------------------------------------------------------------
1535 
check_cc_seq_fetch_creds_begin(void)1536 int check_cc_seq_fetch_creds_begin(void) {
1537     cc_result err = 0;
1538     apiCB *context = NULL;
1539     ccache_p *ccache = NULL;
1540     ccache_p *dup_ccache = NULL;
1541     ccache_cit *creds_iterator = NULL;
1542     char *name = NULL;
1543 
1544     BEGIN_TEST("cc_seq_fetch_creds_begin");
1545 
1546     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1547 
1548     if (!err) {
1549         err = destroy_all_ccaches_v2(context);
1550     }
1551 
1552     if (!err) {
1553         err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_BEGIN", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1554     }
1555 
1556     // valid params
1557     if (!err) {
1558         check_once_cc_seq_fetch_creds_begin(context, ccache, &creds_iterator, CC_NOERROR, "valid params");
1559     }
1560     if (creds_iterator) {
1561         cc_seq_fetch_creds_end(context, &creds_iterator);
1562         creds_iterator = NULL;
1563     }
1564 
1565     // NULL out param
1566     if (!err) {
1567         check_once_cc_seq_fetch_creds_begin(context, ccache, NULL, CC_BAD_PARM, "NULL out iterator param");
1568     }
1569     if (creds_iterator) {
1570         cc_seq_fetch_creds_end(context, &creds_iterator);
1571         creds_iterator = NULL;
1572     }
1573 
1574     // non-existent ccache
1575     if (ccache) {
1576         err = cc_get_name(context, ccache, &name);
1577         if (!err) {
1578             err = cc_open(context, name, CC_CRED_V5, 0, &dup_ccache);
1579         }
1580         if (name) { cc_free_name(context, &name); }
1581         if (dup_ccache) { cc_destroy(context, &dup_ccache); }
1582     }
1583 
1584     if (!err) {
1585         check_once_cc_seq_fetch_creds_begin(context, ccache, &creds_iterator, CC_NO_EXIST, "invalid ccache");
1586     }
1587 
1588     if (creds_iterator) {
1589         cc_seq_fetch_creds_end(context, &creds_iterator);
1590         creds_iterator = NULL;
1591     }
1592     if (ccache) { cc_close(context, &ccache); }
1593     if (context) {
1594         destroy_all_ccaches_v2(context);
1595         cc_shutdown(&context);
1596     }
1597 
1598     END_TEST_AND_RETURN
1599 }
1600 
1601 // ---------------------------------------------------------------------------
1602 
check_once_cc_seq_fetch_creds_begin(apiCB * context,ccache_p * ccache,ccache_cit ** iterator,cc_result expected_err,const char * description)1603 cc_result check_once_cc_seq_fetch_creds_begin(apiCB *context, ccache_p *ccache, ccache_cit **iterator, cc_result expected_err, const char *description) {
1604     cc_result err = CC_NOERROR;
1605 
1606     cc_result possible_return_values[5] = {
1607         CC_NOERROR,
1608         CC_BAD_PARM,
1609         CC_NOMEM,
1610         CC_NO_EXIST
1611     };
1612 
1613     BEGIN_CHECK_ONCE(description);
1614 
1615 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1616 
1617     err = cc_seq_fetch_creds_begin(context, ccache, iterator);
1618 
1619     // check returned error
1620     check_err(err, expected_err, possible_return_values);
1621 
1622     END_CHECK_ONCE;
1623 
1624     return err;
1625 }
1626 
1627 // ---------------------------------------------------------------------------
1628 
check_cc_seq_fetch_creds_next(void)1629 int check_cc_seq_fetch_creds_next(void) {
1630     cc_result err = 0;
1631     apiCB *context = NULL;
1632     ccache_p *ccache = NULL;
1633     cred_union creds_union;
1634     ccache_cit *iterator = NULL;
1635     unsigned int i;
1636 
1637     BEGIN_TEST("cc_seq_fetch_creds_next");
1638 
1639     err = cc_initialize(&context, ccapi_version_2, NULL, NULL);
1640 
1641     if (!err) {
1642         err = destroy_all_ccaches_v2(context);
1643     }
1644 
1645     // iterate with no creds
1646     if (!err) {
1647         err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1648     }
1649     if (!err) {
1650         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1651     }
1652     check_once_cc_seq_fetch_creds_next(context, iterator, 0, CC_NOERROR, "iterating over an empty ccache");
1653     if (iterator) {
1654         cc_seq_fetch_creds_end(context, &iterator);
1655         iterator = NULL;
1656     }
1657     if (ccache) {
1658         cc_close(context, &ccache);
1659         ccache = NULL;
1660     }
1661 
1662     // iterate with one cred
1663     if (!err) {
1664         destroy_all_ccaches_v2(context);
1665         err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1666     }
1667     if (!err) {
1668         new_v5_creds_union_compat(&creds_union, "BAR.ORG");
1669         err = cc_store(context, ccache, creds_union);
1670         release_v5_creds_union_compat(&creds_union);
1671     }
1672     if (!err) {
1673         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1674     }
1675     check_once_cc_seq_fetch_creds_next(context, iterator, 1, CC_NOERROR, "iterating over a ccache with 1 cred");
1676     if (iterator) {
1677         cc_seq_fetch_creds_end(context, &iterator);
1678         iterator = NULL;
1679     }
1680     if (ccache) {
1681         cc_close(context, &ccache);
1682         ccache = NULL;
1683     }
1684 
1685     // iterate with several creds
1686     if (!err) {
1687         destroy_all_ccaches_v2(context);
1688         err = cc_create(context, "TEST_CC_SEQ_FETCH_CREDS_NEXT", "foo@BAR.ORG", CC_CRED_V5, 0, &ccache);
1689     }
1690     for(i = 0; !err && (i < 1000); i++) {
1691         if (i%100 == 0) fprintf(stdout, ".");
1692         new_v5_creds_union_compat(&creds_union, "BAR.ORG");
1693         err = cc_store(context, ccache, creds_union);
1694         release_v5_creds_union_compat(&creds_union);
1695     }
1696     if (!err) {
1697         err = cc_seq_fetch_creds_begin(context, ccache, &iterator);
1698     }
1699     check_once_cc_seq_fetch_creds_next(context, iterator, 1000, CC_NOERROR, "iterating over a ccache with 1000 creds");
1700 
1701     if (ccache) { cc_close(context, &ccache); }
1702     if (iterator) { cc_seq_fetch_creds_end(context, &iterator); }
1703     if (context) {
1704         destroy_all_ccaches_v2(context);
1705         cc_shutdown(&context);
1706     }
1707 
1708     END_TEST_AND_RETURN
1709 }
1710 
1711 // ---------------------------------------------------------------------------
1712 
check_once_cc_seq_fetch_creds_next(apiCB * context,ccache_cit * iterator,cc_uint32 expected_count,cc_result expected_err,const char * description)1713 cc_result check_once_cc_seq_fetch_creds_next(apiCB *context, ccache_cit *iterator, cc_uint32 expected_count, cc_result expected_err, const char *description) {
1714     cc_result   err             = CC_NOERROR;
1715     cred_union *creds           = NULL;
1716     cc_uint32   actual_count    = 0;
1717 
1718     cc_result possible_return_values[5] = {
1719         CC_NOERROR,
1720         CC_END,
1721         CC_BAD_PARM,
1722         CC_NOMEM,
1723         CC_NO_EXIST,
1724     };
1725 
1726     BEGIN_CHECK_ONCE(description);
1727 
1728 #define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1729 
1730     while (!err) {
1731         err = cc_seq_fetch_creds_next(context, &creds, iterator);
1732         if (creds) {
1733             actual_count++;
1734             cc_free_creds(context, &creds);
1735             creds = NULL;
1736         }
1737     }
1738     if (err == CC_END) {
1739         err = CC_NOERROR;
1740     }
1741 
1742     // check returned error
1743     check_err(err, expected_err, possible_return_values);
1744 
1745     check_if(actual_count != expected_count, "iterator didn't iterate over all ccaches");
1746 
1747     END_CHECK_ONCE;
1748 
1749     return err;
1750 }
1751