1
2#include <string.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <limits.h>
6#include "test_ccapi_check.h"
7#include "test_ccapi_util.h"
8#include "test_ccapi_context.h"
9#include "test_ccapi_ccache.h"
10
11// ---------------------------------------------------------------------------
12
13
14int check_cc_ccache_release(void) {
15	cc_int32 err = 0;
16	cc_context_t context = NULL;
17	cc_ccache_t ccache = NULL;
18
19	BEGIN_TEST("cc_ccache_release");
20
21	#ifndef cc_ccache_release
22	log_error("cc_ccache_release is not implemented yet");
23	failure_count++;
24	#else
25
26	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
27
28	if (!err) {
29		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
30	}
31
32
33
34	if (!err) {
35		check_once_cc_ccache_release(context, ccache, ccNoError, NULL);
36		ccache = NULL;
37	}
38
39	if (context) { cc_context_release(context); }
40
41	#endif /* cc_ccache_release */
42
43	END_TEST_AND_RETURN
44}
45
46cc_int32 check_once_cc_ccache_release(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) {
47	cc_int32 err = ccNoError;
48
49	cc_int32 possible_return_values[2] = {
50		ccNoError,
51		ccErrInvalidCCache,
52	};
53
54	cc_string_t name = NULL;
55
56	err = cc_ccache_get_name(ccache, &name);
57	err = cc_ccache_release(ccache);
58	ccache = NULL;
59
60    BEGIN_CHECK_ONCE(description);
61
62	#ifdef cc_ccache_release
63
64	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
65
66	// check returned error
67	check_err(err, expected_err, possible_return_values);
68
69	if (!err && name) { // try opening released ccache to make sure it still exists
70		err = cc_context_open_ccache(context, name->data, &ccache);
71	}
72	check_if(err == ccErrCCacheNotFound, "released ccache was actually destroyed instead");
73
74	if (ccache) { cc_ccache_destroy(ccache); }
75	if (name) { cc_string_release(name); }
76
77	#endif /* cc_ccache_release */
78
79	END_CHECK_ONCE;
80
81	return err;
82}
83
84
85// ---------------------------------------------------------------------------
86
87
88int check_cc_ccache_destroy(void) {
89	cc_int32 err = 0;
90	cc_context_t context = NULL;
91	cc_ccache_t ccache = NULL;
92
93	BEGIN_TEST("cc_ccache_destroy");
94
95	#ifndef cc_ccache_destroy
96	log_error("cc_ccache_destroy is not implemented yet");
97	failure_count++;
98	#else
99
100	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
101
102	if (!err) {
103		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
104	}
105
106
107
108	if (!err) {
109		check_once_cc_ccache_destroy(context, ccache, ccNoError, NULL);
110		ccache = NULL;
111	}
112
113	if (context) { cc_context_release(context); }
114
115	#endif /* cc_ccache_destroy */
116
117	END_TEST_AND_RETURN
118}
119
120cc_int32 check_once_cc_ccache_destroy(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) {
121	cc_int32 err = ccNoError;
122
123	cc_int32 possible_return_values[2] = {
124		ccNoError,
125		ccErrInvalidCCache,
126	};
127
128	cc_string_t name = NULL;
129
130    BEGIN_CHECK_ONCE(description);
131
132	#ifdef cc_ccache_destroy
133
134	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
135
136	err = cc_ccache_get_name(ccache, &name);
137	err = cc_ccache_destroy(ccache);
138	ccache = NULL;
139
140	// check returned error
141	check_err(err, expected_err, possible_return_values);
142
143	if (!err && name) { // try opening released ccache to make sure it still exists
144		err = cc_context_open_ccache(context, name->data, &ccache);
145	}
146	check_if(err != ccErrCCacheNotFound, "destroyed ccache was actually released instead");
147
148	if (ccache) { cc_ccache_destroy(ccache); }
149	if (name) { cc_string_release(name); }
150
151	#endif /* cc_ccache_destroy */
152
153	END_CHECK_ONCE;
154
155	return err;
156}
157
158
159// ---------------------------------------------------------------------------
160
161
162int check_cc_ccache_set_default(void) {
163	cc_int32 err = 0;
164	cc_context_t context = NULL;
165	cc_ccache_t ccache = NULL;
166
167	BEGIN_TEST("cc_ccache_set_default");
168
169	#ifndef cc_ccache_set_default
170	log_error("cc_ccache_set_default is not implemented yet");
171	failure_count++;
172	#else
173
174	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
175
176	// try when it's the only ccache (already default)
177	if (!err) {
178		err = destroy_all_ccaches(context);
179	}
180	if (!err) {
181		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
182	}
183	if (!err) {
184		check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's the only ccache (already default)");
185	}
186	if (ccache) {
187		err = cc_ccache_release(ccache);
188		ccache = NULL;
189	}
190
191	// try when it's not the only ccache (and not default)
192	if (!err) {
193		err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache);
194	}
195	if (!err) {
196		check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and not default)");
197	}
198	if (ccache) {
199		err = cc_ccache_release(ccache);
200		ccache = NULL;
201	}
202
203	// try when it's not the only ccache (and already default)
204	if (!err) {
205		err = cc_context_open_default_ccache(context, &ccache);
206	}
207	if (!err) {
208		check_once_cc_ccache_set_default(context, ccache, ccNoError, "when it's not the only ccache (and already default)");
209	}
210	if (ccache) {
211		err = cc_ccache_release(ccache);
212		ccache = NULL;
213	}
214
215	if (!err) {
216		err = destroy_all_ccaches(context);
217	}
218
219	if (context) { cc_context_release(context); }
220
221	#endif /* cc_ccache_set_default */
222
223	END_TEST_AND_RETURN
224}
225
226cc_int32 check_once_cc_ccache_set_default(cc_context_t context, cc_ccache_t ccache, cc_int32 expected_err, const char *description) {
227	cc_int32 err = ccNoError;
228
229	cc_int32 possible_return_values[3] = {
230		ccNoError,
231		ccErrInvalidCCache,
232		ccErrCCacheNotFound,
233	};
234
235	cc_ccache_t default_ccache = NULL;
236	cc_string_t name = NULL;
237	cc_string_t default_name = NULL;
238
239    BEGIN_CHECK_ONCE(description);
240
241	#ifdef cc_ccache_set_default
242
243	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
244
245	err = cc_ccache_set_default(ccache);
246	// check returned error
247	check_err(err, expected_err, possible_return_values);
248
249	if (!err) {
250		err = cc_ccache_get_name(ccache, &name);
251	}
252	if (!err) {
253		err = cc_context_open_default_ccache(context, &default_ccache);
254	}
255	if (!err) {
256		err = cc_ccache_get_name(default_ccache, &default_name);
257	}
258	if (name && default_name) {
259		check_if(strcmp(name->data, default_name->data), NULL);
260	}
261	else {
262		check_if(1, "cc_ccache_get_name failed");
263	}
264
265	if (default_ccache) { cc_ccache_release(default_ccache); }
266	//if (ccache) { cc_ccache_destroy(ccache); } // ccache is released by the caller
267	if (default_name) { cc_string_release(default_name); }
268	if (name) { cc_string_release(name); }
269
270	#endif /* cc_ccache_set_default */
271
272	END_CHECK_ONCE;
273
274	return err;
275}
276
277
278// ---------------------------------------------------------------------------
279
280
281int check_cc_ccache_get_credentials_version(void) {
282	cc_int32 err = 0;
283	cc_context_t context = NULL;
284	cc_ccache_t ccache = NULL;
285
286	BEGIN_TEST("cc_ccache_get_credentials_version");
287
288	#ifndef cc_ccache_get_credentials_version
289	log_error("cc_ccache_get_credentials_version is not implemented yet");
290	failure_count++;
291	#else
292
293	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
294
295	// try one created with v5 creds
296	if (!err) {
297		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
298	}
299	if (!err) {
300		check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v5, ccNoError, "v5 creds");
301	}
302	else {
303		log_error("cc_context_create_new_ccache failed, can't complete test");
304		failure_count++;
305	}
306
307#if 0
308	// try it with added v4 creds
309	if (!err) {
310		err = cc_ccache_set_principal(ccache, cc_credentials_v4, "foo@BAR.ORG");
311	}
312	if (!err) {
313		check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v5 with v4 creds added");
314	}
315	else {
316		log_error("cc_ccache_set_principal failed, can't complete test");
317		failure_count++;
318	}
319#endif
320	if (ccache) {
321		cc_ccache_destroy(ccache);
322		ccache = NULL;
323	}
324
325	err = ccNoError;
326
327#if 0
328	// try one created with v4 creds
329	if (!err) {
330		err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAR.ORG", &ccache);
331	}
332	if (!err) {
333		check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4, ccNoError, "v4 creds");
334	}
335	else {
336		log_error("cc_context_create_new_ccache failed, can't complete test");
337		failure_count++;
338	}
339
340	// try it with added v5 creds
341	if (!err) {
342		err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG");
343	}
344	if (!err) {
345		check_once_cc_ccache_get_credentials_version(ccache, cc_credentials_v4_v5, ccNoError, "v4 with v5 creds added");
346	}
347	else {
348		log_error("cc_ccache_set_principal failed, can't complete test");
349		failure_count++;
350	}
351#endif
352	if (ccache) {
353		cc_ccache_destroy(ccache);
354		ccache = NULL;
355	}
356
357	if (context) { cc_context_release(context); }
358
359	#endif /* cc_ccache_get_credentials_version */
360
361	END_TEST_AND_RETURN
362}
363
364cc_int32 check_once_cc_ccache_get_credentials_version(cc_ccache_t ccache, cc_uint32 expected_cred_vers, cc_int32 expected_err, const char *description) {
365	cc_int32 err = ccNoError;
366
367	cc_int32 possible_return_values[4] = {
368		ccNoError,
369		ccErrInvalidCCache,
370		ccErrBadParam,
371		ccErrCCacheNotFound,
372	};
373
374	cc_uint32 stored_cred_vers = 0;
375
376    BEGIN_CHECK_ONCE(description);
377
378	#ifdef cc_ccache_get_credentials_version
379
380	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
381
382	err = cc_ccache_get_credentials_version(ccache, &stored_cred_vers);
383
384	// check returned error
385	check_err(err, expected_err, possible_return_values);
386
387	if (!err) {
388		check_if(stored_cred_vers != expected_cred_vers, NULL);
389	}
390
391	#endif /* cc_ccache_get_credentials_version */
392
393	END_CHECK_ONCE;
394
395	return err;
396}
397
398
399// ---------------------------------------------------------------------------
400
401
402int check_cc_ccache_get_name(void) {
403	cc_int32 err = 0;
404	cc_context_t context = NULL;
405	cc_ccache_t ccache = NULL;
406
407	BEGIN_TEST("cc_ccache_get_name");
408
409	#ifndef cc_ccache_get_name
410	log_error("cc_ccache_get_name is not implemented yet");
411	failure_count++;
412	#else
413
414	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
415
416	if (!err) {
417		err = destroy_all_ccaches(context);
418	}
419
420	// try with unique ccache (which happens to be default)
421	if (!err) {
422		err = cc_context_create_ccache(context, "0", cc_credentials_v5, "foo@BAR.ORG", &ccache);
423	}
424	if (!err) {
425		check_once_cc_ccache_get_name(ccache, "0", ccNoError, "unique ccache (which happens to be default)");
426	}
427	else {
428		log_error("cc_context_create_ccache failed, can't complete test");
429		failure_count++;
430	}
431	if (ccache) {
432		cc_ccache_release(ccache);
433		ccache = NULL;
434	}
435
436	// try with unique ccache (which is not default)
437	if (!err) {
438		err = cc_context_create_ccache(context, "1", cc_credentials_v5, "foo@BAR.ORG", &ccache);
439	}
440	if (!err) {
441		check_once_cc_ccache_get_name(ccache, "1", ccNoError, "unique ccache (which is not default)");
442	}
443	else {
444		log_error("cc_context_create_ccache failed, can't complete test");
445		failure_count++;
446	}
447
448	// try with bad param
449	if (!err) {
450		check_once_cc_ccache_get_name(ccache, NULL, ccErrBadParam, "NULL param");
451	}
452	if (ccache) {
453		cc_ccache_release(ccache);
454		ccache = NULL;
455	}
456
457	if (context) {
458		err = destroy_all_ccaches(context);
459		cc_context_release(context);
460	}
461
462	#endif /* cc_ccache_get_name */
463
464	END_TEST_AND_RETURN
465}
466
467cc_int32 check_once_cc_ccache_get_name(cc_ccache_t ccache, const char *expected_name, cc_int32 expected_err, const char *description) {
468	cc_int32 err = ccNoError;
469
470	cc_int32 possible_return_values[4] = {
471		ccNoError,
472		ccErrInvalidCCache,
473		ccErrBadParam,
474		ccErrCCacheNotFound,
475	};
476
477	cc_string_t stored_name = NULL;
478
479    BEGIN_CHECK_ONCE(description);
480
481	#ifdef cc_ccache_get_name
482
483	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
484
485	if (expected_name == NULL) { // we want to try with a NULL param
486		err = cc_ccache_get_name(ccache, NULL);
487	}
488	else {
489		err = cc_ccache_get_name(ccache, &stored_name);
490	}
491
492	// check returned error
493	check_err(err, expected_err, possible_return_values);
494
495	if (!err) {
496		check_if(strcmp(stored_name->data, expected_name), NULL);
497	}
498
499	if (stored_name) { cc_string_release(stored_name); }
500
501	#endif /* cc_ccache_get_name */
502
503	END_CHECK_ONCE;
504
505	return err;
506}
507
508
509// ---------------------------------------------------------------------------
510
511cc_int32 check_once_cc_ccache_get_principal(cc_ccache_t ccache,
512                                            cc_uint32 cred_vers,
513                                            const char *expected_principal,
514                                            cc_int32 expected_err,
515                                            const char *description) {
516	cc_int32 err = ccNoError;
517	cc_string_t stored_principal = NULL;
518
519	cc_int32 possible_return_values[6] = {
520		ccNoError,
521		ccErrNoMem,
522		ccErrBadCredentialsVersion,
523		ccErrBadParam,
524		ccErrInvalidCCache,
525		ccErrCCacheNotFound,
526	};
527
528    BEGIN_CHECK_ONCE(description);
529
530	#ifdef cc_ccache_get_principal
531
532	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
533
534	if (expected_principal == NULL) { // we want to try with a NULL param
535		err = cc_ccache_get_principal(ccache, cred_vers, NULL);
536	}
537	else {
538		err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal);
539	}
540
541	// check returned error
542	check_err(err, expected_err, possible_return_values);
543
544	if (!err) {
545		check_if(strcmp(stored_principal->data, expected_principal), "expected princ == \"%s\" stored princ == \"%s\"", expected_principal, stored_principal->data);
546	}
547
548	if (stored_principal) { cc_string_release(stored_principal); }
549
550	#endif /* cc_ccache_get_principal */
551
552	END_CHECK_ONCE;
553
554	return err;
555}
556
557// ---------------------------------------------------------------------------
558
559int check_cc_ccache_get_principal(void) {
560	cc_int32 err = 0;
561	cc_context_t context = NULL;
562	cc_ccache_t ccache = NULL;
563
564	BEGIN_TEST("cc_ccache_get_principal");
565
566	#ifndef cc_ccache_get_principal
567	log_error("cc_ccache_get_principal is not implemented yet");
568	failure_count++;
569	#else
570
571	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
572
573	if (!err) {
574		err = destroy_all_ccaches(context);
575	}
576
577	// try with krb5 principal
578	if (!err) {
579		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo/BAR@BAZ.ORG", &ccache);
580	}
581	if (!err) {
582		check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, "foo/BAR@BAZ.ORG", ccNoError, "trying to get krb5 princ for krb5 ccache");
583	}
584	else {
585		log_error("cc_context_create_new_ccache failed, can't complete test");
586		failure_count++;
587	}
588	if (ccache) {
589		cc_ccache_release(ccache);
590		ccache = NULL;
591	}
592
593#if 0
594	// try with krb4 principal
595	if (!err) {
596		err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo.BAR@BAZ.ORG", &ccache);
597	}
598	if (!err) {
599		check_once_cc_ccache_get_principal(ccache, cc_credentials_v4, "foo.BAR@BAZ.ORG", ccNoError, "trying to get krb4 princ for krb4 ccache");
600	}
601	else {
602		log_error("cc_context_create_new_ccache failed, can't complete test");
603		failure_count++;
604	}
605	// try with bad param
606	if (!err) {
607		// cc_ccache_t doesn't have any concept of the difference between a v4 and v5 principal
608		check_once_cc_ccache_get_principal(ccache, cc_credentials_v4_v5, "foo.BAR@BAZ.ORG",
609			ccErrBadCredentialsVersion,
610			"passing cc_credentials_v4_v5 (shouldn't be allowed)");
611		check_once_cc_ccache_get_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam, "passed null out param");
612	}
613#endif
614
615	if (ccache) {
616		cc_ccache_release(ccache);
617		ccache = NULL;
618	}
619
620	if (context) {
621		err = destroy_all_ccaches(context);
622		cc_context_release(context);
623	}
624
625	#endif /* cc_ccache_get_principal */
626
627	END_TEST_AND_RETURN
628}
629
630// ---------------------------------------------------------------------------
631
632int check_cc_ccache_set_principal(void) {
633	cc_int32 err = 0;
634	cc_context_t context = NULL;
635	cc_ccache_t ccache = NULL;
636
637	BEGIN_TEST("cc_ccache_set_principal");
638
639	#ifndef cc_ccache_set_principal
640	log_error("cc_ccache_set_principal is not implemented yet");
641	failure_count++;
642	#else
643
644	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
645
646	if (!err) {
647		err = destroy_all_ccaches(context);
648	}
649
650	// bad params
651	if (!err) {
652		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache);
653	}
654	if (!err) {
655		check_once_cc_ccache_set_principal(ccache, cc_credentials_v4_v5, "foo/BAZ@BAR.ORG", ccErrBadCredentialsVersion, "cc_credentials_v4_v5 (not allowed)");
656		check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL principal");
657	}
658	else {
659		log_error("cc_context_create_new_ccache failed, can't complete test");
660		failure_count++;
661	}
662	if (ccache) {
663		cc_ccache_destroy(ccache);
664		ccache = NULL;
665	}
666
667
668	// empty ccache
669
670		// replace v5 only ccache's principal
671		if (!err) {
672			err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache);
673		}
674		if (!err) {
675			check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "replace v5 only ccache's principal (empty ccache)");
676		}
677		else {
678			log_error("cc_context_create_new_ccache failed, can't complete test");
679			failure_count++;
680		}
681		if (ccache) {
682			cc_ccache_destroy(ccache);
683			ccache = NULL;
684		}
685
686		// add v4 principal to v5 only ccache
687		if (!err) {
688			err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache);
689		}
690#if 0
691		if (!err) {
692			check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "add v4 principal to v5 only ccache (empty ccache)");
693		}
694		else {
695			log_error("cc_context_create_new_ccache failed, can't complete test");
696			failure_count++;
697		}
698#endif
699		if (ccache) {
700			cc_ccache_destroy(ccache);
701			ccache = NULL;
702		}
703
704#if 0
705		// replace v4 only ccache's principal
706		if (!err) {
707			err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache);
708		}
709		if (!err) {
710			check_once_cc_ccache_set_principal(ccache, cc_credentials_v4, "foo.BAZ@BAR.ORG", ccNoError, "replace v4 only ccache's principal (empty ccache)");
711		}
712		else {
713			log_error("cc_context_create_new_ccache failed, can't complete test");
714			failure_count++;
715		}
716		if (ccache) {
717			cc_ccache_destroy(ccache);
718			ccache = NULL;
719		}
720
721		// add v5 principal to v4 only ccache
722		if (!err) {
723			err = cc_context_create_new_ccache(context, cc_credentials_v4, "foo@BAZ.ORG", &ccache);
724		}
725		if (!err) {
726			check_once_cc_ccache_set_principal(ccache, cc_credentials_v5, "foo/BAZ@BAR.ORG", ccNoError, "add v5 principal to v4 only ccache (empty ccache)");
727		}
728		else {
729			log_error("cc_context_create_new_ccache failed, can't complete test");
730			failure_count++;
731		}
732		if (ccache) {
733			cc_ccache_destroy(ccache);
734			ccache = NULL;
735		}
736#endif
737
738	// with credentials
739
740		// replace v5 only ccache's principal
741
742		// add v4 principal to v5 only ccache
743
744		// replace v4 only ccache's principal
745
746		// add v5 principal to v4 only ccache
747
748	if (context) {
749		err = destroy_all_ccaches(context);
750		cc_context_release(context);
751	}
752
753	#endif /* cc_ccache_set_principal */
754
755	END_TEST_AND_RETURN
756}
757
758cc_int32 check_once_cc_ccache_set_principal(cc_ccache_t ccache, cc_uint32 cred_vers, const char *in_principal, cc_int32 expected_err, const char *description) {
759	cc_int32 err = ccNoError;
760	cc_string_t stored_principal = NULL;
761
762	cc_int32 possible_return_values[6] = {
763		ccNoError,
764		ccErrNoMem,
765		ccErrInvalidCCache,
766		ccErrBadCredentialsVersion,
767		ccErrBadParam,
768		ccErrCCacheNotFound,
769	};
770
771    BEGIN_CHECK_ONCE(description);
772
773	#ifdef cc_ccache_set_principal
774
775	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
776
777	err = cc_ccache_set_principal(ccache, cred_vers, in_principal);
778
779	// check returned error
780	check_err(err, expected_err, possible_return_values);
781
782	if (!err) {
783		err = cc_ccache_get_principal(ccache, cred_vers, &stored_principal);
784	}
785
786	// compare stored with input
787	if (!err) {
788		check_if(strcmp(stored_principal->data, in_principal), "expected princ == \"%s\" stored princ == \"%s\"", in_principal, stored_principal->data);
789	}
790
791	if (stored_principal) { cc_string_release(stored_principal); }
792
793	#endif /* cc_ccache_set_principal */
794
795	END_CHECK_ONCE;
796
797	return err;
798}
799
800
801// ---------------------------------------------------------------------------
802
803
804int check_cc_ccache_store_credentials(void) {
805	cc_int32 err = 0;
806	cc_context_t context = NULL;
807	cc_ccache_t ccache = NULL;
808	cc_ccache_t dup_ccache = NULL;
809	cc_credentials_union creds_union;
810	cc_string_t name = NULL;
811
812	BEGIN_TEST("cc_ccache_store_credentials");
813
814	#ifndef cc_ccache_store_credentials
815	log_error("cc_ccache_store_credentials is not implemented yet");
816	failure_count++;
817	#else
818
819	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
820
821	if (!err) {
822		err = destroy_all_ccaches(context);
823	}
824
825	if (!err) {
826		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
827	}
828
829	// cred with matching version and realm
830	if (!err) {
831		err = new_v5_creds_union(&creds_union, "BAR.ORG");
832	}
833
834	if (!err) {
835		check_once_cc_ccache_store_credentials(ccache, &creds_union, ccNoError, "ok creds");
836	}
837
838	if (&creds_union) { release_v5_creds_union(&creds_union); }
839
840	// try with bad params
841	check_once_cc_ccache_store_credentials(ccache, NULL, ccErrBadParam, "NULL creds param");
842
843	// invalid creds
844	if (!err) {
845		err = new_v5_creds_union(&creds_union, "BAR.ORG");
846	}
847
848	if (!err) {
849		if (creds_union.credentials.credentials_v5->client) {
850			free(creds_union.credentials.credentials_v5->client);
851			creds_union.credentials.credentials_v5->client = NULL;
852		}
853		check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadParam, "invalid creds (NULL client string)");
854	}
855
856	if (&creds_union) { release_v5_creds_union(&creds_union); }
857
858	// bad creds version
859	if (!err) {
860		err = new_v5_creds_union(&creds_union, "BAR.ORG");
861	}
862
863	if (!err) {
864		creds_union.version = cc_credentials_v4_v5;
865		check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4_v5 creds (invalid) into a ccache with only v5 princ");
866		creds_union.version = cc_credentials_v4;
867		check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrBadCredentialsVersion, "v4 creds into a ccache with only v5 princ");
868		creds_union.version = cc_credentials_v5;
869	}
870
871	if (&creds_union) { release_v5_creds_union(&creds_union); }
872
873	// non-existent ccache
874	if (ccache) {
875		err = cc_ccache_get_name(ccache, &name);
876		if (!err) {
877			err = cc_context_open_ccache(context, name->data, &dup_ccache);
878		}
879		if (name) { cc_string_release(name); }
880		if (dup_ccache) { cc_ccache_destroy(dup_ccache); }
881	}
882
883	if (!err) {
884		err = new_v5_creds_union(&creds_union, "BAR.ORG");
885	}
886
887	if (!err) {
888		check_once_cc_ccache_store_credentials(ccache, &creds_union, ccErrInvalidCCache, "invalid ccache");
889	}
890
891	if (!err && &creds_union) { release_v5_creds_union(&creds_union); }
892	if (ccache) { cc_ccache_release(ccache); }
893	if (context) {
894		destroy_all_ccaches(context);
895		cc_context_release(context);
896	}
897
898	#endif /* cc_ccache_store_credentials */
899
900	END_TEST_AND_RETURN
901}
902
903cc_int32 check_once_cc_ccache_store_credentials(cc_ccache_t ccache, const cc_credentials_union *credentials, cc_int32 expected_err, const char *description) {
904	cc_int32 err = ccNoError;
905	cc_credentials_iterator_t creds_iterator = NULL;
906	cc_credentials_t creds = NULL;
907
908	cc_int32 possible_return_values[6] = {
909		ccNoError,
910		ccErrBadParam,
911		ccErrInvalidCCache,
912		ccErrInvalidCredentials,
913		ccErrBadCredentialsVersion,
914		ccErrCCacheNotFound,
915	};
916
917    BEGIN_CHECK_ONCE(description);
918
919	#ifdef cc_ccache_store_credentials
920
921	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
922
923	err = cc_ccache_store_credentials(ccache, credentials);
924
925	// check returned error
926	check_err(err, expected_err, possible_return_values);
927
928	// make sure credentials were truly stored
929	if (!err) {
930		err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator);
931	}
932	while (!err) {
933		err = cc_credentials_iterator_next(creds_iterator, &creds);
934		if (creds) {
935			if (compare_v5_creds_unions(credentials, creds->data) == 0) {
936				break;
937			}
938			cc_credentials_release(creds);
939			creds = NULL;
940		}
941	}
942
943	if (err == ccIteratorEnd) {
944		check_if((creds != NULL), "stored credentials not found in ccache");
945		err = ccNoError;
946	}
947	if (creds) { cc_credentials_release(creds); }
948
949	#endif /* cc_ccache_store_credentials */
950
951	END_CHECK_ONCE;
952
953	return err;
954}
955
956
957// ---------------------------------------------------------------------------
958
959
960int check_cc_ccache_remove_credentials(void) {
961	cc_int32 err = 0;
962	cc_context_t context = NULL;
963	cc_ccache_t ccache = NULL;
964	cc_ccache_t dup_ccache = NULL;
965	cc_credentials_t creds_array[10];
966	cc_credentials_t creds = NULL;
967	cc_credentials_union creds_union;
968	cc_credentials_iterator_t creds_iterator = NULL;
969	cc_string_t name = NULL;
970	unsigned int i;
971
972	BEGIN_TEST("cc_ccache_remove_credentials");
973
974	#ifndef cc_ccache_remove_credentials
975	log_error("cc_ccache_remove_credentials is not implemented yet");
976	failure_count++;
977	#else
978
979	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
980
981	if (!err) {
982		err = destroy_all_ccaches(context);
983	}
984
985	if (!err) {
986		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
987	}
988
989	// store 10 creds and retrieve their cc_credentials_t representations
990	for(i = 0; !err && (i < 10); i++) {
991		new_v5_creds_union(&creds_union, "BAR.ORG");
992		err = cc_ccache_store_credentials(ccache, &creds_union);
993		if (&creds_union) { release_v5_creds_union(&creds_union); }
994	}
995	if (err) {
996		log_error("failure to store creds_union in remove_creds test");
997	}
998	if (!err) {
999		err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator);
1000	}
1001	i = 0;
1002	while (!err && i < 10) {
1003		err = cc_credentials_iterator_next(creds_iterator, &creds);
1004		if (creds) {
1005			creds_array[i++] = creds;
1006			creds = NULL;
1007		}
1008	}
1009	if (err == ccIteratorEnd) { err = ccNoError; }
1010
1011	// remove 10 valid creds
1012	for (i = 0; !err && (i < 8); i++) {
1013		check_once_cc_ccache_remove_credentials(ccache, creds_array[i], ccNoError, "10 ok creds");
1014	}
1015
1016	// NULL param
1017	check_once_cc_ccache_remove_credentials(ccache, NULL, ccErrBadParam, "NULL creds in param");
1018
1019	// non-existent creds (remove same one twice)
1020	check_once_cc_ccache_remove_credentials(ccache, creds_array[0], ccErrCredentialsNotFound, "removed same creds twice");
1021
1022	// non-existent ccache
1023	if (ccache) {
1024		err = cc_ccache_get_name(ccache, &name);
1025		if (!err) {
1026			err = cc_context_open_ccache(context, name->data, &dup_ccache);
1027		}
1028		if (name) { cc_string_release(name); }
1029		if (dup_ccache) { cc_ccache_destroy(dup_ccache); }
1030	}
1031
1032	if (!err) {
1033		err = new_v5_creds_union(&creds_union, "BAR.ORG");
1034	}
1035
1036	if (!err) {
1037		check_once_cc_ccache_remove_credentials(ccache, creds_array[8], ccErrCredentialsNotFound, "invalid ccache");
1038	}
1039
1040	for(i = 0; i < 10; i++) {
1041		if (creds_array[i]) { cc_credentials_release(creds_array[i]); }
1042	}
1043
1044	if (ccache) { cc_ccache_release(ccache); }
1045	if (context) {
1046		destroy_all_ccaches(context);
1047		cc_context_release(context);
1048	}
1049
1050	#endif /* cc_ccache_remove_credentials */
1051
1052	END_TEST_AND_RETURN
1053}
1054
1055cc_int32 check_once_cc_ccache_remove_credentials(cc_ccache_t ccache, cc_credentials_t in_creds, cc_int32 expected_err, const char *description) {
1056	cc_int32 err = ccNoError;
1057	cc_credentials_iterator_t creds_iterator = NULL;
1058	cc_credentials_t creds = NULL;
1059
1060	cc_int32 possible_return_values[6] = {
1061		ccNoError,
1062		ccErrBadParam,
1063		ccErrInvalidCCache,
1064		ccErrInvalidCredentials,
1065		ccErrCredentialsNotFound,
1066		ccErrCCacheNotFound,
1067	};
1068
1069    BEGIN_CHECK_ONCE(description);
1070
1071	#ifdef cc_ccache_remove_credentials
1072
1073	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1074
1075	err = cc_ccache_remove_credentials(ccache, in_creds);
1076
1077	// check returned error
1078	check_err(err, expected_err, possible_return_values);
1079
1080	// make sure credentials were truly removed
1081	if (!err) {
1082		err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator);
1083	}
1084	while (!err) {
1085		err = cc_credentials_iterator_next(creds_iterator, &creds);
1086		if (creds) {
1087			if (compare_v5_creds_unions(in_creds->data, creds->data) == 0) {
1088				break;
1089			}
1090			cc_credentials_release(creds);
1091			creds = NULL;
1092		}
1093	}
1094
1095	if (err == ccIteratorEnd) {
1096		err = ccNoError;
1097	}
1098	else {
1099		check_if((creds != NULL), "credentials not removed from ccache");
1100	}
1101	if (creds) { cc_credentials_release(creds); }
1102
1103	#endif /* cc_ccache_remove_credentials */
1104
1105	END_CHECK_ONCE;
1106
1107	return err;
1108}
1109
1110
1111// ---------------------------------------------------------------------------
1112
1113
1114int check_cc_ccache_new_credentials_iterator(void) {
1115	cc_int32 err = 0;
1116	cc_context_t context = NULL;
1117	cc_ccache_t ccache = NULL;
1118	cc_ccache_t dup_ccache = NULL;
1119	cc_credentials_iterator_t creds_iterator = NULL;
1120	cc_string_t name = NULL;
1121
1122	BEGIN_TEST("cc_ccache_new_credentials_iterator");
1123
1124	#ifndef cc_ccache_new_credentials_iterator
1125	log_error("cc_ccache_new_credentials_iterator is not implemented yet");
1126	failure_count++;
1127	#else
1128
1129	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1130
1131	if (!err) {
1132		err = destroy_all_ccaches(context);
1133	}
1134
1135	if (!err) {
1136		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
1137	}
1138
1139	// valid params
1140	if (!err) {
1141		check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccNoError, "valid params");
1142	}
1143	if (creds_iterator) {
1144		cc_credentials_iterator_release(creds_iterator);
1145		creds_iterator = NULL;
1146	}
1147
1148	// NULL out param
1149	if (!err) {
1150		check_once_cc_ccache_new_credentials_iterator(ccache, NULL, ccErrBadParam, "NULL out iterator param");
1151	}
1152	if (creds_iterator) {
1153		cc_credentials_iterator_release(creds_iterator);
1154		creds_iterator = NULL;
1155	}
1156
1157	// non-existent ccache
1158	if (ccache) {
1159		err = cc_ccache_get_name(ccache, &name);
1160		if (!err) {
1161			err = cc_context_open_ccache(context, name->data, &dup_ccache);
1162		}
1163		if (name) { cc_string_release(name); }
1164		if (dup_ccache) { cc_ccache_destroy(dup_ccache); }
1165	}
1166
1167	if (!err) {
1168		check_once_cc_ccache_new_credentials_iterator(ccache, &creds_iterator, ccErrInvalidCCache, "invalid ccache");
1169	}
1170
1171	if (creds_iterator) {
1172		cc_credentials_iterator_release(creds_iterator);
1173		creds_iterator = NULL;
1174	}
1175	if (ccache) { cc_ccache_release(ccache); }
1176	if (context) {
1177		destroy_all_ccaches(context);
1178		cc_context_release(context);
1179	}
1180
1181	#endif /* cc_ccache_new_credentials_iterator */
1182
1183	END_TEST_AND_RETURN
1184}
1185
1186
1187cc_int32 check_once_cc_ccache_new_credentials_iterator(cc_ccache_t ccache, cc_credentials_iterator_t *iterator, cc_int32 expected_err, const char *description) {
1188	cc_int32 err = ccNoError;
1189
1190	cc_int32 possible_return_values[5] = {
1191		ccNoError,
1192		ccErrBadParam,
1193		ccErrNoMem,
1194		ccErrCCacheNotFound,
1195		ccErrInvalidCCache,
1196	};
1197
1198    BEGIN_CHECK_ONCE(description);
1199
1200	#ifdef cc_ccache_new_credentials_iterator
1201
1202	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1203
1204	err = cc_ccache_new_credentials_iterator(ccache, iterator);
1205
1206	// check returned error
1207	check_err(err, expected_err, possible_return_values);
1208
1209	#endif /* cc_ccache_new_credentials_iterator */
1210
1211	END_CHECK_ONCE;
1212
1213	return err;
1214}
1215
1216
1217// ---------------------------------------------------------------------------
1218
1219cc_int32 check_once_cc_ccache_get_change_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) {
1220	cc_int32 err = ccNoError;
1221	cc_time_t this_time = 0;
1222
1223	cc_int32 possible_return_values[4] = {
1224		ccNoError,
1225		ccErrInvalidCCache,
1226		ccErrBadParam,
1227		ccErrCCacheNotFound,
1228	};
1229
1230    BEGIN_CHECK_ONCE(description);
1231
1232	#ifdef cc_ccache_get_change_time
1233
1234	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1235
1236	if (last_time == NULL) {
1237		err = cc_ccache_get_change_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead
1238	} else {
1239		err = cc_ccache_get_change_time(ccache, &this_time);
1240	}
1241
1242	// check returned error
1243	check_err(err, expected_err, possible_return_values);
1244
1245	if ((!err) && last_time) {
1246		check_if(this_time <= *last_time, "change time didn't increase when expected");
1247		*last_time = this_time;
1248	}
1249
1250	#endif /* cc_ccache_get_change_time */
1251
1252	END_CHECK_ONCE;
1253
1254	return err;
1255}
1256
1257// ---------------------------------------------------------------------------
1258
1259int check_cc_ccache_get_change_time(void) {
1260	cc_int32 err = 0;
1261	cc_context_t context = NULL;
1262	cc_ccache_t dummy_ccache = NULL;
1263	cc_ccache_t ccache = NULL;
1264	cc_credentials_union creds_union;
1265	cc_credentials_iterator_t creds_iterator = NULL;
1266	cc_credentials_t credentials = NULL;
1267	cc_time_t last_time = 0;
1268
1269    BEGIN_TEST("cc_ccache_get_change_time");
1270
1271	#ifndef cc_ccache_get_change_time
1272	log_error("cc_ccache_get_change_time is not implemented yet");
1273	failure_count++;
1274	#else
1275
1276	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1277
1278	if (!err) {
1279		err = destroy_all_ccaches(context);
1280	}
1281
1282	// create some ccaches (so that the one we keep around as 'ccache' is not default)
1283	if (!err) {
1284		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
1285	}
1286	if (ccache) {
1287		cc_ccache_release(ccache);
1288	}
1289	if (!err) {
1290		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAZ.ORG", &ccache);
1291	}
1292
1293	// change it in all the ways it can change, checking after each
1294
1295	// the ccache is created
1296	if (!err) {
1297		check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "new ccache (change time should be > 0)");
1298	}
1299
1300	// the ccache is made default
1301	if (!err) {
1302		err = cc_ccache_set_default(ccache);
1303	}
1304	if (!err) {
1305		check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "non-default ccache became default");
1306	}
1307
1308	// the ccache is made not-default
1309	if (!err) {
1310		err = cc_context_create_new_ccache(context, cc_credentials_v5, "something@ELSE.COM", &dummy_ccache);
1311	}
1312	if (!err) {
1313		err = cc_ccache_set_default(dummy_ccache);
1314	}
1315	if (dummy_ccache) {
1316		cc_ccache_release(dummy_ccache);
1317	}
1318	if (!err) {
1319		check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "default ccache became non-default");
1320	}
1321
1322	// try with bad params
1323
1324	// NULL out param
1325	if (!err) {
1326		check_once_cc_ccache_get_change_time(ccache, NULL, ccErrBadParam, "NULL out param for time");
1327	}
1328
1329	// store a credential
1330	if (!err) {
1331		new_v5_creds_union(&creds_union, "BAR.ORG");
1332		err = cc_ccache_store_credentials(ccache, &creds_union);
1333		release_v5_creds_union(&creds_union);
1334	}
1335	check_once_cc_ccache_get_change_time(ccache, &last_time, ccNoError, "stored new credential");
1336
1337	if (!err) {
1338		// change principal (fails with ccErrBadInternalMessage)
1339		err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG");
1340		if (err) {
1341			log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err);
1342			failure_count++;
1343			err = ccNoError;
1344		}
1345	}
1346	check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after changing a principle");
1347
1348	// remove a credential
1349	if (!err) {
1350		err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator);
1351	}
1352	if (!err) {
1353		err = cc_credentials_iterator_next(creds_iterator, &credentials);
1354	}
1355	if (err == ccIteratorEnd) {
1356		err = ccNoError;
1357	}
1358	if (!err) {
1359		err = cc_ccache_remove_credentials(ccache, credentials);
1360	}
1361	check_once_cc_context_get_change_time(context, &last_time, ccNoError, "after removing a credential");
1362
1363
1364	// invalid ccache
1365	if (!err) {
1366		err = destroy_all_ccaches(context);
1367	}
1368	if (!err) {
1369		check_once_cc_ccache_get_change_time(ccache, &last_time, ccErrInvalidCCache, "getting change time on destroyed ccache");
1370	}
1371
1372	if (ccache) { cc_ccache_release(ccache); }
1373	if (context) {
1374		destroy_all_ccaches(context);
1375		cc_context_release(context);
1376	}
1377
1378	#endif /* cc_ccache_get_change_time */
1379
1380	END_TEST_AND_RETURN
1381}
1382
1383
1384// ---------------------------------------------------------------------------
1385
1386cc_int32 check_once_cc_ccache_get_last_default_time(cc_ccache_t ccache, cc_time_t *last_time, cc_int32 expected_err, const char *description) {
1387	cc_int32 err = ccNoError;
1388	cc_time_t this_time = 0;
1389
1390	cc_int32 possible_return_values[5] = {
1391		ccNoError,
1392		ccErrInvalidCCache,
1393		ccErrBadParam,
1394		ccErrNeverDefault,
1395		ccErrCCacheNotFound,
1396	};
1397
1398    BEGIN_CHECK_ONCE(description);
1399
1400	#ifdef cc_ccache_get_last_default_time
1401
1402	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1403
1404	if (last_time == NULL) {
1405		err = cc_ccache_get_last_default_time(ccache, NULL); // passed NULL to compare against because intention is actually to pass bad param instead
1406	} else {
1407		err = cc_ccache_get_last_default_time(ccache, &this_time);
1408	}
1409
1410	// check returned error
1411	check_err(err, expected_err, possible_return_values);
1412
1413	if (!err && last_time) {
1414		check_if(this_time > *last_time, "last default time isn't as expected");
1415		*last_time = this_time;
1416	}
1417
1418	#endif /* cc_ccache_get_last_default_time */
1419
1420	END_CHECK_ONCE;
1421
1422	return err;
1423}
1424
1425// ---------------------------------------------------------------------------
1426
1427int check_cc_ccache_get_last_default_time(void) {
1428	cc_int32 err = 0;
1429	cc_context_t context = NULL;
1430	cc_ccache_t ccache_1 = NULL;
1431	cc_ccache_t ccache_2 = NULL;
1432	cc_time_t last_time_1 = 0;
1433	cc_time_t last_time_2 = 0;
1434	cc_string_t name = NULL;
1435
1436	BEGIN_TEST("cc_ccache_get_last_default_time");
1437
1438	#ifndef cc_ccache_get_last_default_time
1439	log_error("cc_ccache_get_last_default_time is not implemented yet");
1440	failure_count++;
1441	#else
1442
1443	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1444
1445	if (!err) {
1446		err = destroy_all_ccaches(context);
1447	}
1448
1449	// create 2 ccaches
1450	if (!err) {
1451		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &ccache_1);
1452	}
1453	if (!err) {
1454		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &ccache_2);
1455	}
1456
1457	if (!err) {
1458		err = cc_ccache_get_change_time(ccache_1, &last_time_1);
1459	}
1460
1461	// since we destroyed all ccaches before creating these two,
1462	// ccache_1 should be default and ccache_2 should never have been default
1463	if (!err) {
1464		check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 default at creation");
1465		check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccErrNeverDefault, "ccache_2 never default");
1466	}
1467
1468	// make ccache_2 default and check each of their times again
1469	if (!err) {
1470		err = cc_ccache_set_default(ccache_2);
1471	}
1472	if (!err) {
1473		err = cc_ccache_get_change_time(ccache_2, &last_time_2);
1474	}
1475	if (!err) {
1476		check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccNoError, "ccache_1 no longer default");
1477		check_once_cc_ccache_get_last_default_time(ccache_2, &last_time_2, ccNoError, "ccache_2 newly default");
1478	}
1479
1480	// NULL param
1481	if (!err) {
1482		check_once_cc_ccache_get_last_default_time(ccache_1, NULL, ccErrBadParam, "NULL out param");
1483	}
1484
1485	// non-existent ccache
1486	if (ccache_2) {
1487		cc_ccache_release(ccache_2);
1488		ccache_2 = NULL;
1489	}
1490	if (!err) {
1491		err = cc_ccache_get_name(ccache_1, &name);
1492	}
1493	if (!err) {
1494		err = cc_context_open_ccache(context, name->data, &ccache_2);
1495	}
1496	if (!err) {
1497		cc_ccache_destroy(ccache_2);
1498		ccache_2 = NULL;
1499	}
1500
1501	if (!err) {
1502		check_once_cc_ccache_get_last_default_time(ccache_1, &last_time_1, ccErrInvalidCCache, "destroyed ccache");
1503	}
1504
1505	if (ccache_1) { cc_ccache_release(ccache_1); }
1506
1507	if (context) {
1508		destroy_all_ccaches(context);
1509		cc_context_release(context);
1510	}
1511
1512	#endif /* cc_ccache_get_last_default_time */
1513
1514	END_TEST_AND_RETURN
1515}
1516
1517// ---------------------------------------------------------------------------
1518
1519int check_cc_ccache_move(void) {
1520	cc_int32 err = 0;
1521	cc_context_t context = NULL;
1522	cc_ccache_t source = NULL;
1523	cc_ccache_t destination = NULL;
1524
1525	cc_credentials_union creds_union;
1526	unsigned int i = 0;
1527
1528	BEGIN_TEST("cc_ccache_move");
1529
1530	#ifndef cc_ccache_move
1531	log_error("cc_ccache_move is not implemented yet");
1532	failure_count++;
1533	#else
1534
1535	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1536
1537	if (!err) {
1538		err = destroy_all_ccaches(context);
1539	}
1540
1541	// create 2 ccaches
1542	if (!err) {
1543		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@ONE.ORG", &source);
1544	}
1545	if (!err) {
1546		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@TWO.ORG", &destination);
1547	}
1548
1549	// store credentials in each
1550	for (i = 0; !err && (i < 10); i++) {
1551		new_v5_creds_union(&creds_union, "ONE.ORG");
1552		err = cc_ccache_store_credentials(source, &creds_union);
1553	}
1554	for (i = 0; !err && (i < 10); i++) {
1555		new_v5_creds_union(&creds_union, "TWO.ORG");
1556		err = cc_ccache_store_credentials(destination, &creds_union);
1557	}
1558
1559	// move source into destination
1560	if (!err) {
1561		check_once_cc_ccache_move(source, destination, ccNoError, "valid params");
1562	}
1563
1564	// NULL param
1565	if (!err) {
1566		check_once_cc_ccache_move(destination, NULL, ccErrBadParam, "NULL destination param");
1567	}
1568
1569	// non-existent ccache
1570	if (!err) {
1571		check_once_cc_ccache_move(destination, source, ccErrInvalidCCache, "recently moved source as destination param");
1572	}
1573
1574	if (source) { cc_ccache_release(source); }
1575	if (destination) { cc_ccache_release(destination); }
1576
1577	if (context) {
1578		destroy_all_ccaches(context);
1579		cc_context_release(context);
1580	}
1581
1582	#endif /* cc_ccache_move */
1583
1584	END_TEST_AND_RETURN
1585
1586
1587}
1588
1589cc_int32 check_once_cc_ccache_move(cc_ccache_t source, cc_ccache_t destination, cc_int32 expected_err, const char *description) {
1590	cc_int32 err = ccNoError;
1591	cc_credentials_t dst_creds[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, };
1592	cc_credentials_t creds = NULL;
1593	cc_credentials_iterator_t cred_iterator = NULL;
1594	unsigned int i = 0;
1595
1596	cc_string_t src_principal = NULL;
1597	cc_string_t dst_principal = NULL;
1598
1599	cc_int32 possible_return_values[4] = {
1600		ccNoError,
1601		ccErrBadParam,
1602		ccErrInvalidCCache,
1603		ccErrCCacheNotFound,
1604	};
1605
1606    BEGIN_CHECK_ONCE(description);
1607
1608	#ifdef cc_ccache_move
1609
1610	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1611
1612	if (destination) {
1613		// verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response)
1614		if (!err) {
1615			err = cc_ccache_new_credentials_iterator(destination, &cred_iterator);
1616		}
1617		while (!err && (i < 10)) {
1618			err = cc_credentials_iterator_next(cred_iterator, &creds);
1619			if (creds) {
1620				dst_creds[i++] = creds;
1621			}
1622		}
1623		if (err == ccIteratorEnd) {
1624			err = ccNoError;
1625		}
1626		if (cred_iterator) {
1627			cc_credentials_iterator_release(cred_iterator);
1628			cred_iterator = NULL;
1629		}
1630
1631		// verify that destination's principal has changed to source's (strcmp)
1632		if (!err) {
1633			err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal);
1634		}
1635	}
1636
1637
1638	if (!err) {
1639		err = cc_ccache_move(source, destination);
1640	}
1641
1642	// check returned error
1643	check_err(err, expected_err, possible_return_values);
1644
1645
1646	if (!err) {
1647		// verify all of destination's credentials are no longer there (save a list and call remove_cred for each, expecting an err in response)
1648		i = 0;
1649		while (dst_creds[i] && (i < 10)) {
1650			err = cc_ccache_remove_credentials(destination, dst_creds[i]);
1651			check_if(!(!err || err == ccErrCredentialsNotFound || ccErrInvalidCredentials), "credentials in destination not removed as promised");
1652			cc_credentials_release(dst_creds[i]);
1653			i++;
1654		}
1655		err = ccNoError;
1656	}
1657
1658		// verify that destination's principal has changed to source's (strcmp)
1659		if (!err) {
1660			err = cc_ccache_get_principal(destination, cc_credentials_v5, &dst_principal);
1661		}
1662		if (!err) {
1663			check_if(strcmp(src_principal->data, dst_principal->data), "destination principal not overwritten by source");
1664		}
1665
1666		// verify that handles for source are no longer valid (get_change_time)
1667		if (src_principal) {
1668			cc_string_release(src_principal);
1669			src_principal = NULL;
1670		}
1671		if (!err) {
1672			err = cc_ccache_get_principal(source, cc_credentials_v5, &src_principal);
1673			check_if(err != ccErrInvalidCCache, "source ccache was not invalidated after move");
1674		}
1675
1676
1677	if (cred_iterator) { cc_credentials_iterator_release(cred_iterator); }
1678	if (src_principal) { cc_string_release(src_principal); }
1679	if (dst_principal) { cc_string_release(dst_principal); }
1680
1681	#endif /* cc_ccache_move */
1682
1683	END_CHECK_ONCE;
1684
1685	return err;
1686}
1687
1688
1689// ---------------------------------------------------------------------------
1690
1691int check_cc_ccache_compare(void) {
1692	cc_int32 err = 0;
1693	cc_context_t context = NULL;
1694	cc_ccache_t ccache_a = NULL;
1695	cc_ccache_t ccache_b = NULL;
1696	cc_uint32 equal = 0;
1697
1698	BEGIN_TEST("cc_ccache_compare");
1699
1700	#ifndef cc_ccache_compare
1701	log_error("cc_ccache_compare is not implemented yet");
1702	failure_count++;
1703	#else
1704
1705	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1706
1707	if (!err) {
1708		err = destroy_all_ccaches(context);
1709	}
1710	if (!err) {
1711		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache_a);
1712	}
1713	if (!err) {
1714		err = cc_context_open_default_ccache(context, &ccache_b);
1715	}
1716
1717	equal = 1;
1718	check_once_cc_ccache_compare(ccache_a, ccache_a, &equal, ccNoError, "compare ccache with same pointer");
1719	equal = 1;
1720	check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different handles to same ccache");
1721
1722	if (ccache_b) {
1723		cc_ccache_release(ccache_b);
1724		ccache_b = NULL;
1725	}
1726	if (!err) {
1727		err = cc_context_create_new_ccache(context, cc_credentials_v5, "baz@BAR.ORG", &ccache_b);
1728	}
1729	equal = 0;
1730	check_once_cc_ccache_compare(ccache_a, ccache_b, &equal, ccNoError, "compare different ccaches");
1731	check_once_cc_ccache_compare(ccache_a, NULL, &equal, ccErrBadParam, "NULL compare_to ccache");
1732	check_once_cc_ccache_compare(ccache_a, ccache_b, NULL, ccErrBadParam, "NULL out param");
1733
1734	if (ccache_a) { cc_ccache_release(ccache_a); }
1735	if (ccache_b) { cc_ccache_release(ccache_b); }
1736
1737	if (context) {
1738		err = destroy_all_ccaches(context);
1739		cc_context_release(context);
1740	}
1741
1742	#endif /* cc_ccache_compare */
1743
1744	END_TEST_AND_RETURN
1745}
1746
1747cc_int32 check_once_cc_ccache_compare(cc_ccache_t ccache, cc_ccache_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) {
1748	cc_int32 err = ccNoError;
1749	cc_uint32 actually_equal = 0;
1750
1751	cc_int32 possible_return_values[4] = {
1752		ccNoError,
1753		ccErrInvalidContext,
1754		ccErrBadParam,
1755		ccErrServerUnavailable,
1756	};
1757
1758    BEGIN_CHECK_ONCE(description);
1759
1760	#ifdef cc_ccache_compare
1761
1762	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1763
1764	if (equal) {
1765		actually_equal = *equal;
1766	}
1767
1768	err = cc_ccache_compare(ccache, compare_to, equal);
1769
1770	if (!err && equal) {
1771		if (actually_equal) {
1772			check_if(actually_equal != *equal, "equal ccaches not considered equal");
1773		}
1774		else {
1775			check_if(actually_equal != *equal, "non-equal ccaches considered equal");
1776		}
1777	}
1778
1779	// check returned error
1780	check_err(err, expected_err, possible_return_values);
1781
1782	#endif /* cc_ccache_compare */
1783
1784	return err;
1785}
1786
1787
1788// ---------------------------------------------------------------------------
1789
1790int check_cc_ccache_get_kdc_time_offset(void) {
1791	cc_int32 err = 0;
1792	cc_context_t context = NULL;
1793	cc_ccache_t ccache = NULL;
1794	cc_time_t time_offset = 0;
1795
1796	BEGIN_TEST("cc_ccache_get_kdc_time_offset");
1797
1798	#ifndef cc_ccache_get_kdc_time_offset
1799	log_error("cc_ccache_get_kdc_time_offset is not implemented yet");
1800	failure_count++;
1801	#else
1802
1803	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1804
1805	if (!err) {
1806		err = destroy_all_ccaches(context);
1807	}
1808	if (!err) {
1809		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
1810	}
1811
1812	time_offset = 0;
1813	check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccErrTimeOffsetNotSet, "brand new ccache (offset not yet set)");
1814
1815	time_offset = 10;
1816	if (!err) {
1817		err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, time_offset);
1818	}
1819	if (!err) {
1820		check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, &time_offset, ccNoError, "offset set for v5 but not v4");
1821	}
1822#if 0
1823	if (!err) {
1824		check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccErrTimeOffsetNotSet, "asking for v4 offset when only v5 is set");
1825	}
1826	if (!err) {
1827		err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, time_offset);
1828	}
1829	if (!err) {
1830		check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4, &time_offset, ccNoError, "asking for v4 offset when v4 and v5 are set");
1831	}
1832#endif
1833
1834	check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v5, NULL, ccErrBadParam, "NULL time_offset out param");
1835#if 0
1836	check_once_cc_ccache_get_kdc_time_offset(ccache, cc_credentials_v4_v5, &time_offset, ccErrBadCredentialsVersion, "v4_v5 creds_vers in param (invalid)");
1837#endif
1838
1839	if (ccache) { cc_ccache_release(ccache); }
1840
1841	if (context) {
1842		err = destroy_all_ccaches(context);
1843		cc_context_release(context);
1844	}
1845
1846	#endif /* cc_ccache_get_kdc_time_offset */
1847
1848	END_TEST_AND_RETURN
1849}
1850
1851cc_int32 check_once_cc_ccache_get_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t *time_offset, cc_int32 expected_err, const char *description) {
1852	cc_int32 err = ccNoError;
1853	cc_time_t expected_offset;
1854
1855	cc_int32 possible_return_values[7] = {
1856		ccNoError,
1857		ccErrTimeOffsetNotSet,
1858		ccErrCCacheNotFound,
1859		ccErrInvalidCCache,
1860		ccErrBadParam,
1861		ccErrServerUnavailable,
1862		ccErrBadCredentialsVersion,
1863	};
1864
1865    BEGIN_CHECK_ONCE(description);
1866
1867	#ifdef cc_ccache_get_kdc_time_offset
1868
1869	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1870
1871	if (time_offset) {
1872		expected_offset = *time_offset;
1873	}
1874
1875	err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, time_offset);
1876
1877	// check returned error
1878	check_err(err, expected_err, possible_return_values);
1879
1880	if (!err && time_offset) {
1881		check_if(*time_offset != expected_offset, "kdc time offset doesn't match expected value");
1882	}
1883
1884	#endif /* cc_ccache_get_kdc_time_offset */
1885
1886	return err;
1887}
1888
1889
1890// ---------------------------------------------------------------------------
1891
1892int check_cc_ccache_set_kdc_time_offset(void) {
1893	cc_int32 err = 0;
1894	cc_context_t context = NULL;
1895	cc_ccache_t ccache = NULL;
1896
1897	BEGIN_TEST("cc_ccache_set_kdc_time_offset");
1898
1899	#ifndef cc_ccache_set_kdc_time_offset
1900	log_error("cc_ccache_set_kdc_time_offset is not implemented yet");
1901	failure_count++;
1902	#else
1903
1904	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1905
1906	if (!err) {
1907		err = destroy_all_ccaches(context);
1908	}
1909	if (!err) {
1910		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
1911	}
1912
1913	check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0, ccNoError, "first time setting offset (v5)");
1914#if 0
1915	check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0, ccNoError, "first time setting offset (v4)");
1916
1917	check_once_cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4_v5, 0, ccErrBadCredentialsVersion, "invalid creds_vers (v4_v5)");
1918#endif
1919
1920	if (ccache) { cc_ccache_release(ccache); }
1921
1922	if (context) {
1923		err = destroy_all_ccaches(context);
1924		cc_context_release(context);
1925	}
1926
1927	#endif /* cc_ccache_set_kdc_time_offset */
1928
1929	END_TEST_AND_RETURN
1930}
1931
1932cc_int32 check_once_cc_ccache_set_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_time_t time_offset, cc_int32 expected_err, const char *description) {
1933	cc_int32 err = ccNoError;
1934	cc_time_t stored_offset = 0;
1935
1936	cc_int32 possible_return_values[6] = {
1937		ccNoError,
1938		ccErrCCacheNotFound,
1939		ccErrInvalidCCache,
1940		ccErrBadParam,
1941		ccErrServerUnavailable,
1942		ccErrBadCredentialsVersion,
1943	};
1944
1945    BEGIN_CHECK_ONCE(description);
1946
1947	#ifdef cc_ccache_set_kdc_time_offset
1948
1949	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
1950
1951	err = cc_ccache_set_kdc_time_offset(ccache, credentials_version, time_offset);
1952
1953	// check returned error
1954	check_err(err, expected_err, possible_return_values);
1955
1956	if (!err) {
1957		err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset);
1958	}
1959
1960	if (!err) {
1961		check_if(time_offset != stored_offset, "kdc time offset doesn't match expected value");
1962	}
1963
1964	#endif /* cc_ccache_set_kdc_time_offset */
1965
1966	return err;
1967}
1968
1969
1970// ---------------------------------------------------------------------------
1971
1972int check_cc_ccache_clear_kdc_time_offset(void) {
1973	cc_int32 err = 0;
1974	cc_context_t context = NULL;
1975	cc_ccache_t ccache = NULL;
1976
1977	BEGIN_TEST("cc_ccache_clear_kdc_time_offset");
1978
1979	#ifndef cc_ccache_clear_kdc_time_offset
1980	log_error("cc_ccache_clear_kdc_time_offset is not implemented yet");
1981	failure_count++;
1982	#else
1983
1984	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
1985
1986	if (!err) {
1987		err = destroy_all_ccaches(context);
1988	}
1989	if (!err) {
1990		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
1991	}
1992
1993	check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing an offset that was never set (v5)");
1994#if 0
1995	check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing an offset that was never set (v4)");
1996#endif
1997
1998	err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v5, 0);
1999#if 0
2000	err = cc_ccache_set_kdc_time_offset(ccache, cc_credentials_v4, 0);
2001#endif
2002
2003	check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v5, ccNoError, "clearing v5");
2004#if 0
2005	check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4, ccNoError, "clearing v4");
2006
2007	check_once_cc_ccache_clear_kdc_time_offset(ccache, cc_credentials_v4_v5, ccErrBadCredentialsVersion, "bad in param creds vers (v4_v5)");
2008#endif
2009
2010	if (ccache) { cc_ccache_release(ccache); }
2011
2012	if (context) {
2013		err = destroy_all_ccaches(context);
2014		cc_context_release(context);
2015	}
2016
2017	#endif /* cc_ccache_clear_kdc_time_offset */
2018
2019	END_TEST_AND_RETURN
2020}
2021
2022cc_int32 check_once_cc_ccache_clear_kdc_time_offset(cc_ccache_t ccache, cc_int32 credentials_version, cc_int32 expected_err, const char *description) {
2023	cc_int32 err = ccNoError;
2024
2025	cc_int32 possible_return_values[6] = {
2026		ccNoError,
2027		ccErrCCacheNotFound,
2028		ccErrInvalidCCache,
2029		ccErrBadParam,
2030		ccErrServerUnavailable,
2031		ccErrBadCredentialsVersion,
2032	};
2033	BEGIN_CHECK_ONCE(description);
2034
2035	#ifdef cc_ccache_clear_kdc_time_offset
2036
2037	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
2038
2039	err = cc_ccache_clear_kdc_time_offset(ccache, credentials_version);
2040
2041	// check returned error
2042	check_err(err, expected_err, possible_return_values);
2043
2044#if 0
2045	if (!err) {
2046		err = cc_ccache_get_kdc_time_offset(ccache, credentials_version, &stored_offset);
2047		check_if(err != ccErrTimeOffsetNotSet, "time offset not cleared");
2048	}
2049#endif
2050
2051	#endif /* cc_ccache_clear_kdc_time_offset */
2052
2053	return err;
2054}
2055
2056
2057