1#include <string.h>
2#include "test_ccapi_context.h"
3#include <limits.h>
4#include "test_ccapi_check.h"
5#include "test_ccapi_util.h"
6
7int check_cc_initialize(void) {
8	cc_int32 err = 0;
9	cc_context_t context = NULL;
10
11	BEGIN_TEST("cc_initialize");
12
13	// try every api_version
14	err = check_once_cc_initialize(&context, ccapi_version_2, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_2");   	   // err == CC_BAD_API_VERSION (9) would be imported by CredentialsCache2.h
15	err = check_once_cc_initialize(&context, ccapi_version_3, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_3");   	   // !err
16	err = check_once_cc_initialize(&context, ccapi_version_4, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_4");   	   //        "
17	err = check_once_cc_initialize(&context, ccapi_version_5, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_5");   	   //        "
18	err = check_once_cc_initialize(&context, ccapi_version_6, NULL, NULL, ccNoError, "cc_initialize with ccapi_version_6");   	   //        "
19
20	// try bad api_version
21	err = check_once_cc_initialize(&context, INT_MAX,         NULL, NULL, ccErrBadAPIVersion, NULL); // err == ccErrBadAPIVersion
22
23	// try bad param
24	err = check_once_cc_initialize(NULL,     ccapi_version_3, NULL, NULL, ccErrBadParam, NULL);  	   // err == ccErrBadParam
25
26	END_TEST_AND_RETURN
27}
28
29cc_int32 check_once_cc_initialize(cc_context_t *out_context, cc_int32 in_version, cc_int32 *out_supported_version, char const **out_vendor, cc_int32 expected_err, const char *description) {
30	cc_int32 err = 0;
31	cc_context_t context;
32
33	cc_int32 possible_return_values[4] = {
34		ccNoError,
35		ccErrNoMem,
36		ccErrBadAPIVersion,
37		ccErrBadParam,
38	};
39
40    BEGIN_CHECK_ONCE(description);
41
42	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
43
44	err = cc_initialize(out_context, in_version, out_supported_version, out_vendor);
45
46	// check returned error
47	check_err(err, expected_err, possible_return_values);
48
49	if (out_context) { context = *out_context; }
50	else { context = NULL; }
51
52	// check output parameters
53	if (!err) {
54		check_if(context == NULL, NULL);
55		if (context) {
56			cc_context_release(context);
57			*out_context = NULL;
58		}
59	} else {
60		check_if(context != NULL, NULL);
61	}
62
63	return err;
64}
65
66int check_cc_context_release(void) {
67	cc_int32 err = 0;
68	cc_context_t context = NULL;
69
70	BEGIN_TEST("cc_context_release");
71
72	#ifndef cc_context_release
73	log_error("cc_context_release is not implemented yet");
74	failure_count++;
75	#else
76
77	// try with valid context
78	err = check_once_cc_context_release(&context, ccNoError, NULL);
79
80	// try with NULL
81	//err = check_once_cc_context_release(NULL, ccErrInvalidContext);
82	/* calling with NULL context crashes, because this macro expands to
83	   ((NULL) -> functions -> release (NULL)) which is dereferencing NULL which is bad. */
84
85	if (context) { cc_context_release(context); }
86
87	#endif /* cc_context_release */
88
89	END_TEST_AND_RETURN
90}
91
92cc_int32 check_once_cc_context_release(cc_context_t *out_context, cc_int32 expected_err, const char *description) {
93	cc_int32 err = 0;
94	cc_context_t context = NULL;
95
96	cc_int32 possible_return_values[2] = {
97		ccNoError,
98		ccErrInvalidContext,
99	};
100
101    BEGIN_CHECK_ONCE(description);
102
103	#ifdef cc_context_release
104
105	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
106
107	if (out_context) {
108		err = cc_initialize(out_context, ccapi_version_3, NULL, NULL);
109		if (!err) {
110			context = *out_context;
111		}
112	}
113
114	if (err != ccNoError) {
115		log_error("failure in cc_initialize, unable to perform check");
116		return err;
117	}
118	else {
119		err = cc_context_release(context);
120		// check returned error
121		check_err(err, expected_err, possible_return_values);
122	}
123
124	*out_context = NULL;
125
126	#endif /* cc_context_release */
127
128	END_CHECK_ONCE;
129
130	return err;
131}
132
133int check_cc_context_get_change_time(void) {
134	cc_int32 err = 0;
135	cc_context_t context = NULL;
136	cc_time_t last_change_time = 0;
137	cc_ccache_t ccache = NULL;
138	cc_credentials_union creds_union;
139	cc_credentials_iterator_t creds_iterator = NULL;
140	cc_credentials_t credentials = NULL;
141
142	BEGIN_TEST("cc_context_get_change_time");
143
144	#ifndef cc_context_get_change_time
145	log_error("cc_context_get_change_time is not implemented yet");
146	failure_count++;
147	#else
148
149	/*
150	 * Make a context
151	 * make sure the change time changes after:
152	 * 	a ccache is created
153	 * 	a ccache is destroyed
154	 * 	a credential is stored
155	 * 	a credential is removed
156	 * 	a ccache principal is changed
157	 * 	the default ccache is changed
158	 * clean up memory
159	 */
160
161	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
162	if (!err) {
163
164		// try bad parameters first
165		err = check_once_cc_context_get_change_time(context, NULL, ccErrBadParam, "NULL param, should fail");
166
167		// make sure we have a default ccache
168		err = cc_context_open_default_ccache(context, &ccache);
169		if (err == ccErrCCacheNotFound) {
170			err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache);
171		}
172		if (!err) {
173			err = cc_ccache_release(ccache);
174		}
175		// either the default ccache already existed or we just created it
176		// either way, the get_change_time should now give something > 0
177		check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "first-run, should be > 0");
178
179		// create a ccache
180		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
181		check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after creating a new ccache");
182
183		// store a credential
184		if (!err) {
185			new_v5_creds_union(&creds_union, "BAR.ORG");
186			err = cc_ccache_store_credentials(ccache, &creds_union);
187			release_v5_creds_union(&creds_union);
188		}
189		check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after storing a credential");
190
191		if (!err) {
192			// change principal (fails with ccErrBadInternalMessage)
193			err = cc_ccache_set_principal(ccache, cc_credentials_v5, "foo@BAR.ORG");
194			if (err) {
195				log_error("failed to change ccache's principal - %s (%d)", translate_ccapi_error(err), err);
196				failure_count++;
197				err = ccNoError;
198			}
199		}
200		check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing a principle");
201
202		// remove a credential
203		if (!err) {
204			err = cc_ccache_new_credentials_iterator(ccache, &creds_iterator);
205		}
206		if (!err) {
207			err = cc_credentials_iterator_next(creds_iterator, &credentials);
208		}
209		if (err == ccIteratorEnd) {
210			err = ccNoError;
211		}
212		if (!err) {
213			err = cc_ccache_remove_credentials(ccache, credentials);
214		}
215		check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after removing a credential");
216
217		if (!err) {
218			// change default ccache
219			err = cc_ccache_set_default(ccache);
220			check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after changing default ccache");
221		}
222
223		if (ccache) {
224			// destroy a ccache
225			err = cc_ccache_destroy(ccache);
226			check_once_cc_context_get_change_time(context, &last_change_time, ccNoError, "after destroying a ccache");
227		}
228	}
229
230	if (context) { cc_context_release(context); }
231
232	#endif /* cc_get_change_time */
233
234	END_TEST_AND_RETURN
235}
236
237cc_int32 check_once_cc_context_get_change_time(cc_context_t context, cc_time_t *time, cc_int32 expected_err, const char *description) {
238	cc_int32 err = 0;
239	cc_time_t last_change_time;
240	cc_time_t current_change_time = 0;
241
242	cc_int32 possible_return_values[3] = {
243		ccNoError,
244		ccErrInvalidContext,
245		ccErrBadParam,
246	};
247
248    BEGIN_CHECK_ONCE(description);
249
250	#ifdef cc_context_get_change_time
251
252	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
253
254	if (time != NULL) { // if we were passed NULL, then we're looking to pass a bad param
255		err = cc_context_get_change_time(context, &current_change_time);
256	} else {
257		err = cc_context_get_change_time(context, NULL);
258	}
259
260	check_err(err, expected_err, possible_return_values);
261
262	if (!err) {
263		last_change_time = *time;
264		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);
265		*time = current_change_time;
266	}
267
268	#endif /* cc_context_get_change_time */
269
270	END_CHECK_ONCE;
271
272	return err;
273}
274
275int check_cc_context_get_default_ccache_name(void) {
276	cc_int32 err = 0;
277	cc_context_t context = NULL;
278	cc_ccache_t ccache = NULL;
279	cc_string_t name = NULL;
280
281	BEGIN_TEST("cc_context_get_default_ccache_name");
282
283	#ifndef cc_context_get_default_ccache_name
284	log_error("cc_context_get_default_ccache_name is not implemented yet");
285	failure_count++;
286	#else
287
288	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
289	if (!err) {
290		// try bad parameters first
291		err = check_once_cc_context_get_default_ccache_name(context, NULL, ccErrBadParam, NULL);
292
293		// try with no default
294		err = destroy_all_ccaches(context);
295		err = cc_context_open_default_ccache(context, &ccache);
296		if (err != ccErrCCacheNotFound) {
297			log_error("didn't remove all ccaches");
298		}
299		err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL);
300
301		// try normally
302		err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
303		if (ccache) { cc_ccache_release(ccache); }
304		err = check_once_cc_context_get_default_ccache_name(context, &name, ccNoError, NULL);
305
306	}
307
308	if (context) { cc_context_release(context); }
309
310	#endif /* cc_context_get_default_ccache_name */
311
312	END_TEST_AND_RETURN
313}
314
315cc_int32 check_once_cc_context_get_default_ccache_name(cc_context_t context, cc_string_t *name, cc_int32 expected_err, const char *description) {
316	cc_int32 err = 0;
317
318	cc_int32 possible_return_values[4] = {
319		ccNoError,
320		ccErrInvalidContext,
321		ccErrBadParam,
322		ccErrNoMem,
323	};
324
325    BEGIN_CHECK_ONCE(description);
326
327	#ifdef cc_context_get_default_ccache_name
328
329	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
330
331	if (name != NULL) { // if we were passed NULL, then we're looking to pass a bad param
332		err = cc_context_get_default_ccache_name(context, name);
333	} else {
334		err = cc_context_get_default_ccache_name(context, NULL);
335	}
336
337	// check returned error
338	check_err(err, expected_err, possible_return_values);
339
340	// not really anything else to check
341
342	if (name && *name) { cc_string_release(*name); }
343
344	#endif /* cc_context_get_default_ccache_name */
345
346	END_CHECK_ONCE;
347
348	return err;
349}
350
351int check_cc_context_open_ccache(void) {
352	cc_int32 err = 0;
353	cc_context_t context = NULL;
354	cc_ccache_t ccache = NULL;
355	cc_string_t name = NULL;
356
357	BEGIN_TEST("cc_context_open_ccache");
358
359	#ifndef cc_context_open_ccache
360	log_error("cc_context_open_ccache is not implemented yet");
361	failure_count++;
362	#else
363
364	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
365	if (!err) {
366		// make sure we have a default ccache
367		err = cc_context_open_default_ccache(context, &ccache);
368		if (err == ccErrCCacheNotFound) {
369			err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache);
370		}
371		if (!err) {
372			err = cc_ccache_release(ccache);
373			ccache = NULL;
374		}
375
376		// try default ccache
377		err = cc_context_get_default_ccache_name(context, &name);
378		if (!err) {
379			err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccNoError, NULL);
380		}
381
382		// try bad parameters
383		err = check_once_cc_context_open_ccache(context, NULL, &ccache, ccErrBadParam, NULL);
384		err = check_once_cc_context_open_ccache(context, name->data, NULL, ccErrBadParam, NULL);
385
386		// try a ccache that doesn't exist (create one and then destroy it)
387		err = cc_context_create_new_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
388		if (!err) {
389			err = cc_ccache_get_name(ccache, &name);
390		}
391		if (!err) {
392			err = cc_ccache_destroy(ccache);
393			ccache = NULL;
394		}
395
396		err = check_once_cc_context_open_ccache(context, name->data, &ccache, ccErrCCacheNotFound, NULL);
397	}
398
399	if (context) { cc_context_release(context); }
400
401	#endif /* cc_context_open_ccache */
402
403	END_TEST_AND_RETURN
404}
405
406cc_int32 check_once_cc_context_open_ccache(cc_context_t context, const char *name, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) {
407	cc_int32 err = 0;
408	cc_string_t stored_name = NULL;
409
410	cc_int32 possible_return_values[6] = {
411		ccNoError,
412		ccErrBadName,
413		ccErrInvalidContext,
414		ccErrNoMem,
415		ccErrCCacheNotFound,
416		ccErrBadParam,
417	};
418
419    BEGIN_CHECK_ONCE(description);
420
421	#ifdef cc_context_open_ccache
422
423	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
424
425	if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param
426		err = cc_context_open_ccache(context, name, ccache);
427	} else {
428		err = cc_context_open_ccache(context, name, NULL);
429	}
430
431	// check returned error
432	check_err(err, expected_err, possible_return_values);
433
434	if (!err) {
435		check_if(*ccache == NULL, NULL);
436
437		if (!err) {
438			err = cc_ccache_get_name(*ccache, &stored_name);
439		}
440		if (!err) {
441			check_if(strcmp(stored_name->data, name), NULL);
442		}
443		if (stored_name) { cc_string_release(stored_name); }
444
445
446		if (ccache && *ccache) {
447			cc_ccache_release(*ccache);
448			*ccache = NULL;
449		}
450	}
451
452	#endif /* cc_context_open_ccache */
453
454	END_CHECK_ONCE;
455
456	return err;
457}
458
459int check_cc_context_open_default_ccache(void) {
460	cc_int32 err = 0;
461	cc_context_t context = NULL;
462	cc_ccache_t ccache = NULL;
463
464	BEGIN_TEST("cc_context_open_default_ccache");
465
466	#ifndef cc_context_open_default_ccache
467	log_error("cc_context_open_default_ccache is not implemented yet");
468	failure_count++;
469	#else
470
471	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
472	if (!err) {
473		// make sure we have a default ccache
474		err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache);
475		if (ccache) { cc_ccache_release(ccache); }
476
477		// try default ccache
478		if (!err) {
479			err = check_once_cc_context_open_default_ccache(context, &ccache, ccNoError, NULL);
480		}
481
482		// try bad parameters
483		err = check_once_cc_context_open_default_ccache(context, NULL, ccErrBadParam, NULL);
484
485		// try with no default ccache (destroy all ccaches first)
486		err = destroy_all_ccaches(context);
487
488		err = check_once_cc_context_open_default_ccache(context, &ccache, ccErrCCacheNotFound, NULL);
489	}
490
491	if (context) { cc_context_release(context); }
492
493	#endif /* cc_context_open_default_ccache */
494
495	END_TEST_AND_RETURN
496}
497
498cc_int32 check_once_cc_context_open_default_ccache(cc_context_t context, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) {
499	cc_int32 err = 0;
500	cc_string_t given_name = NULL;
501	cc_string_t default_name = NULL;
502
503	cc_int32 possible_return_values[5] = {
504		ccNoError,
505		ccErrInvalidContext,
506		ccErrNoMem,
507		ccErrCCacheNotFound,
508		ccErrBadParam,
509	};
510
511    BEGIN_CHECK_ONCE(description);
512
513	#ifdef cc_context_open_default_ccache
514
515	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
516
517	if (ccache != NULL) { // if we were passed NULL, then we're looking to pass a bad param
518		err = cc_context_open_default_ccache(context, ccache);
519	} else {
520		err = cc_context_open_default_ccache(context, NULL);
521	}
522
523	// check returned error
524	check_err(err, expected_err, possible_return_values);
525
526	if (!err) {
527		check_if(*ccache == NULL, NULL);
528
529		// make sure this ccache is the one we were looking to get back (compare name with cc_context_get_default_ccache_name)
530		err = cc_ccache_get_name(*ccache, &given_name);
531		err = cc_context_get_default_ccache_name(context, &default_name);
532		if (given_name && default_name) {
533			check_if(strcmp(given_name->data, default_name->data), "name of ccache returned by cc_context_open_default_ccache doesn't match name returned by cc_context_get_default_ccache_name");
534		}
535		if (given_name) { cc_string_release(given_name); }
536		if (default_name) { cc_string_release(default_name); }
537
538		if (ccache && *ccache) {
539			cc_ccache_release(*ccache);
540			*ccache = NULL;
541		}
542	}
543
544	#endif /* cc_context_open_default_ccache */
545
546	END_CHECK_ONCE;
547
548	return err;
549}
550
551int check_cc_context_create_ccache(void) {
552	cc_int32 err = 0;
553	cc_context_t context = NULL;
554	cc_ccache_t ccache = NULL;
555	cc_string_t name = NULL;
556
557	BEGIN_TEST("cc_context_create_ccache");
558
559	#ifndef cc_context_create_ccache
560	log_error("cc_context_create_ccache is not implemented yet");
561	failure_count++;
562	#else
563
564	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
565	if (!err) {
566		// try making a ccache with a non-unique name (the existing default's name)
567		if (!err) {
568			err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo/bar@BAZ.ORG", &ccache);
569		}
570		if (!err) {
571			err = cc_ccache_get_name(ccache, &name);
572		}
573		if (ccache) { cc_ccache_release(ccache); }
574		if (!err) {
575			err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL);
576		}
577
578		// try making a ccache with a unique name (the now destroyed default's name)
579		if (ccache) { cc_ccache_destroy(ccache); }
580		if (!err) {
581			err = check_once_cc_context_create_ccache(context, name->data, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL);
582		}
583
584		// try bad parameters
585		err = check_once_cc_context_create_ccache(context, NULL, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccErrBadParam, "NULL name");                    // NULL name
586		err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers
587		err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
588		err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
589	}
590
591	if (name) { cc_string_release(name); }
592	if (ccache) { cc_ccache_destroy(ccache); }
593	if (context) { cc_context_release(context); }
594
595	#endif /* cc_context_create_ccache */
596
597	END_TEST_AND_RETURN
598}
599
600cc_int32 check_once_cc_context_create_ccache(cc_context_t context, const char *name, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) {
601	cc_int32 err = 0;
602	cc_string_t stored_name = NULL;
603	cc_string_t stored_principal = NULL;
604	cc_uint32 stored_creds_vers = 0;
605
606	cc_int32 possible_return_values[6] = {
607		ccNoError,
608		ccErrBadName,
609		ccErrBadParam,
610		ccErrInvalidContext,
611		ccErrNoMem,
612		ccErrBadCredentialsVersion,
613	};
614	BEGIN_CHECK_ONCE(description);
615
616	#ifdef cc_context_create_ccache
617
618	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
619
620	err = cc_context_create_ccache(context, name, cred_vers, principal, ccache);
621
622	// check returned error
623	check_err(err, expected_err, possible_return_values);
624
625	if (!err) {
626		check_if(*ccache == NULL, NULL);
627
628		// make sure all of the ccache's info matches what we gave it
629		// name
630		err = cc_ccache_get_name(*ccache, &stored_name);
631		if (!err) { check_if(strcmp(stored_name->data, name), NULL); }
632		if (stored_name) { cc_string_release(stored_name); }
633		// cred_vers
634		// FIXME Documented function name of cc_ccache_get_credentials_version is a typo.
635		// FIXME Documented type of creds param the wrong signedness (should be unsigned) for cc_ccache_get_credentials_version, cc_context_create_ccache, cc_context_create_default_ccache, cc_context_create_new_ccache
636		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
637		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
638		// principal
639		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
640		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
641		if (stored_principal) { cc_string_release(stored_principal); }
642
643		if (ccache && *ccache) {
644			cc_ccache_destroy(*ccache);
645			*ccache = NULL;
646		}
647	}
648
649	#endif /* cc_context_create_ccache */
650
651	END_CHECK_ONCE;
652
653	return err;
654}
655
656int check_cc_context_create_default_ccache(void) {
657	cc_int32 err = 0;
658	cc_context_t context = NULL;
659	cc_ccache_t ccache = NULL;
660	cc_string_t name = NULL;
661
662	BEGIN_TEST("cc_context_create_default_ccache");
663
664	#ifndef cc_context_create_default_ccache
665	log_error("cc_context_create_default_ccache is not implemented yet");
666	failure_count++;
667	#else
668
669	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
670	if (!err) {
671		// try making the default when there are no existing ccaches
672		err = destroy_all_ccaches(context);
673		if (!err) {
674			err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL);
675		}
676		if (ccache) { cc_ccache_release(ccache); }
677
678		// try making a new default when one already exists
679		if (!err) {
680			err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL);
681		}
682
683		// try bad parameters
684		err = check_once_cc_context_create_default_ccache(context, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers
685		err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
686		err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
687	}
688
689	if (name) { cc_string_release(name); }
690	if (ccache) { cc_ccache_destroy(ccache); }
691	if (context) { cc_context_release(context); }
692
693	#endif /* cc_context_create_default_ccache */
694
695	END_TEST_AND_RETURN
696}
697
698cc_int32 check_once_cc_context_create_default_ccache(cc_context_t context, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) {
699	cc_int32 err = 0;
700	cc_string_t stored_principal = NULL;
701	cc_uint32 stored_creds_vers = 0;
702
703	cc_int32 possible_return_values[6] = {
704		ccNoError,
705		ccErrBadName, // how can this be possible when the name isn't a parameter?
706		ccErrBadParam,
707		ccErrInvalidContext,
708		ccErrNoMem,
709		ccErrBadCredentialsVersion,
710	};
711
712    BEGIN_CHECK_ONCE(description);
713
714	#ifdef cc_context_create_default_ccache
715
716	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
717
718	err = cc_context_create_default_ccache(context, cred_vers, principal, ccache);
719
720	// check returned error
721	check_err(err, expected_err, possible_return_values);
722
723	if (!err) {
724		if (ccache) { check_if(*ccache == NULL, NULL); }
725		// make sure all of the ccache's info matches what we gave it
726		// cred_vers
727		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
728		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
729		// principal
730		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
731		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
732		if (stored_principal) { cc_string_release(stored_principal); }
733
734		if (ccache && *ccache) {
735			cc_ccache_release(*ccache);
736			*ccache = NULL;
737		}
738	}
739
740	#endif /* cc_context_create_default_ccache */
741
742	END_CHECK_ONCE;
743
744	return err;
745}
746
747int check_cc_context_create_new_ccache(void) {
748	cc_int32 err = 0;
749	cc_context_t context = NULL;
750	cc_ccache_t ccache = NULL;
751	cc_string_t name = NULL;
752
753	BEGIN_TEST("cc_context_create_new_ccache");
754
755	#ifndef cc_context_create_new_ccache
756	log_error("cc_context_create_new_ccache is not implemented yet");
757	failure_count++;
758	#else
759
760	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
761	if (!err) {
762		// try making when there are no existing ccaches (should have name of default)
763		err = destroy_all_ccaches(context);
764		if (!err) {
765			err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL);
766		}
767		if (ccache) { cc_ccache_release(ccache); }
768
769		// try making a new ccache when one already exists (should not have name of default)
770		if (!err) {
771			err = check_once_cc_context_create_new_ccache(context, 0, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL);
772		}
773		if (ccache) { cc_ccache_release(ccache); }
774
775		// try bad parameters
776		err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v4_v5, "foo@BAR.ORG", &ccache, ccErrBadCredentialsVersion, "invalid creds_vers"); // invalid creds_vers
777		err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
778		err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
779	}
780
781	if (name) { cc_string_release(name); }
782	if (ccache) { cc_ccache_destroy(ccache); }
783	if (context) { cc_context_release(context); }
784
785	#endif /* cc_context_create_new_ccache */
786
787	END_TEST_AND_RETURN
788}
789
790cc_int32 check_once_cc_context_create_new_ccache(cc_context_t context, cc_int32 should_be_default, cc_uint32 cred_vers, const char *principal, cc_ccache_t *ccache, cc_int32 expected_err, const char *description) {
791	cc_int32 err = 0;
792	cc_string_t name = NULL;
793	cc_string_t stored_name = NULL;
794	cc_string_t stored_principal = NULL;
795	cc_uint32 stored_creds_vers = 0;
796
797	cc_int32 possible_return_values[6] = {
798		ccNoError,
799		ccErrBadName, // how can this be possible when the name isn't a parameter?
800		ccErrBadParam,
801		ccErrInvalidContext,
802		ccErrNoMem,
803		ccErrBadCredentialsVersion,
804	};
805
806    BEGIN_CHECK_ONCE(description);
807
808	#ifdef cc_context_create_new_ccache
809
810	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
811
812	err = cc_context_create_new_ccache(context, cred_vers, principal, ccache);
813
814	// check returned error
815	check_err(err, expected_err, possible_return_values);
816
817	if (!err) {
818		if (ccache) { check_if(*ccache == NULL, NULL); }
819		// make sure all of the ccache's info matches what we gave it
820		if (!err) {
821			err = cc_context_get_default_ccache_name(context, &name);
822		}
823		if (!err) {
824			err = cc_ccache_get_name(*ccache, &stored_name);
825		}
826		if (!err) {
827			if (should_be_default) {
828				check_if(strcmp(stored_name->data, name->data), "new ccache does not have name of default");
829			}
830			else {
831				check_if((strcmp(stored_name->data, name->data) == 0), "new cache has name of default");
832			}
833		}
834		if (name) { cc_string_release(name); }
835		if (stored_name) { cc_string_release(stored_name); }
836
837		// cred_vers
838		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
839		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
840		// principal
841		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
842		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
843		if (stored_principal) { cc_string_release(stored_principal); }
844
845		if (ccache && *ccache) {
846			cc_ccache_release(*ccache);
847			*ccache = NULL;
848		}
849	}
850
851	#endif /* cc_context_create_new_ccache */
852
853	END_CHECK_ONCE;
854
855	return err;
856}
857
858int check_cc_context_new_ccache_iterator(void) {
859	cc_int32 err = 0;
860	cc_context_t context = NULL;
861	cc_ccache_t ccache = NULL;
862	cc_string_t name = NULL;
863	cc_ccache_iterator_t iterator = NULL;
864
865	BEGIN_TEST("cc_context_new_ccache_iterator");
866
867	#ifndef cc_context_new_ccache_iterator
868	log_error("cc_context_new_ccache_iterator is not implemented yet");
869	failure_count++;
870	#else
871
872	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
873	if (!err) {
874		err = destroy_all_ccaches(context);
875	}
876	if (!err) {
877		// try making when there are no existing ccaches (shouldn't make a difference, but just in case)
878		check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when there are no existing ccaches");
879
880		err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
881	}
882	if (!err) {
883		// try making when at least one ccache already exists (just to cover all our bases)
884		check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when at least one ccache already exists");
885
886		// try bad parameters
887		check_once_cc_context_new_ccache_iterator(context, NULL, ccErrBadParam, "NULL param"); // NULL iterator
888	}
889		// we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite
890
891	if (name) { cc_string_release(name); }
892	if (ccache) { cc_ccache_destroy(ccache); }
893	if (context) { cc_context_release(context); }
894
895	#endif /* cc_context_new_ccache_iterator */
896
897	END_TEST_AND_RETURN
898}
899
900cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description) {
901	cc_int32 err = ccNoError;
902
903	cc_int32 possible_return_values[4] = {
904		ccNoError,
905		ccErrBadParam,
906		ccErrNoMem,
907		ccErrInvalidContext,
908	};
909
910    BEGIN_CHECK_ONCE(description);
911
912	#ifdef cc_context_create_new_ccache
913
914	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
915
916	err = cc_context_new_ccache_iterator(context, iterator);
917
918	// check returned error
919	check_err(err, expected_err, possible_return_values);
920
921	// we'll do a comprehensive test of cc_ccache_iterator related functions later
922
923	#endif /* cc_context_create_new_ccache */
924
925	return err;
926}
927
928
929// ---------------------------------------------------------------------------
930
931int check_cc_context_compare(void) {
932	cc_int32 err = 0;
933	cc_context_t context_a = NULL;
934	cc_context_t context_b = NULL;
935	cc_uint32 equal = 0;
936
937	BEGIN_TEST("cc_context_compare");
938
939	#ifndef cc_context_compare
940	log_error("cc_context_compare is not implemented yet");
941	failure_count++;
942	#else
943
944	err = cc_initialize(&context_a, ccapi_version_3, NULL, NULL);
945	if (!err) {
946		err = cc_initialize(&context_b, ccapi_version_3, NULL, NULL);
947	}
948
949	check_once_cc_context_compare(context_a, context_a, &equal, ccNoError, "valid params, same contexts");
950	check_once_cc_context_compare(context_a, context_b, &equal, ccNoError, "valid params, different contexts");
951	check_once_cc_context_compare(context_a, NULL, &equal, ccErrBadParam, "NULL compare_to context");
952	check_once_cc_context_compare(context_a, context_b, NULL, ccErrBadParam, "NULL out param");
953
954	if (context_a) { cc_context_release(context_a); }
955	if (context_b) { cc_context_release(context_b); }
956
957	#endif /* cc_context_compare */
958
959	END_TEST_AND_RETURN
960}
961
962cc_int32 check_once_cc_context_compare(cc_context_t context, cc_context_t compare_to, cc_uint32 *equal, cc_int32 expected_err, const char *description) {
963	cc_int32 err = ccNoError;
964
965	cc_int32 possible_return_values[4] = {
966		ccNoError,
967		ccErrInvalidContext,
968		ccErrBadParam,
969		ccErrServerUnavailable,
970	};
971
972    BEGIN_CHECK_ONCE(description);
973
974	#ifdef cc_context_compare
975
976	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
977
978	err = cc_context_compare(context, compare_to, equal);
979
980	if (!err) {
981		*equal = 0;
982	}
983
984	// check returned error
985	check_err(err, expected_err, possible_return_values);
986
987	#endif /* cc_context_compare */
988
989	return err;
990}
991