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 
check_cc_initialize(void)7 int 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 
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)29 cc_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 
check_cc_context_release(void)66 int 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 
check_once_cc_context_release(cc_context_t * out_context,cc_int32 expected_err,const char * description)92 cc_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 
check_cc_context_get_change_time(void)133 int 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 
check_once_cc_context_get_change_time(cc_context_t context,cc_time_t * time,cc_int32 expected_err,const char * description)237 cc_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 
check_cc_context_get_default_ccache_name(void)275 int 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 
check_once_cc_context_get_default_ccache_name(cc_context_t context,cc_string_t * name,cc_int32 expected_err,const char * description)315 cc_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 
check_cc_context_open_ccache(void)351 int 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 
check_once_cc_context_open_ccache(cc_context_t context,const char * name,cc_ccache_t * ccache,cc_int32 expected_err,const char * description)406 cc_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 
check_cc_context_open_default_ccache(void)459 int 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 
check_once_cc_context_open_default_ccache(cc_context_t context,cc_ccache_t * ccache,cc_int32 expected_err,const char * description)498 cc_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 
check_cc_context_create_ccache(void)551 int 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_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
587 		err = check_once_cc_context_create_ccache(context, "name", cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
588 	}
589 
590 	if (name) { cc_string_release(name); }
591 	if (ccache) { cc_ccache_destroy(ccache); }
592 	if (context) { cc_context_release(context); }
593 
594 	#endif /* cc_context_create_ccache */
595 
596 	END_TEST_AND_RETURN
597 }
598 
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)599 cc_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) {
600 	cc_int32 err = 0;
601 	cc_string_t stored_name = NULL;
602 	cc_string_t stored_principal = NULL;
603 	cc_uint32 stored_creds_vers = 0;
604 
605 	cc_int32 possible_return_values[6] = {
606 		ccNoError,
607 		ccErrBadName,
608 		ccErrBadParam,
609 		ccErrInvalidContext,
610 		ccErrNoMem,
611 		ccErrBadCredentialsVersion,
612 	};
613 	BEGIN_CHECK_ONCE(description);
614 
615 	#ifdef cc_context_create_ccache
616 
617 	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
618 
619 	err = cc_context_create_ccache(context, name, cred_vers, principal, ccache);
620 
621 	// check returned error
622 	check_err(err, expected_err, possible_return_values);
623 
624 	if (!err) {
625 		check_if(*ccache == NULL, NULL);
626 
627 		// make sure all of the ccache's info matches what we gave it
628 		// name
629 		err = cc_ccache_get_name(*ccache, &stored_name);
630 		if (!err) { check_if(strcmp(stored_name->data, name), NULL); }
631 		if (stored_name) { cc_string_release(stored_name); }
632 		// cred_vers
633 		// FIXME Documented function name of cc_ccache_get_credentials_version is a typo.
634 		// 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
635 		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
636 		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
637 		// principal
638 		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
639 		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
640 		if (stored_principal) { cc_string_release(stored_principal); }
641 
642 		if (ccache && *ccache) {
643 			cc_ccache_destroy(*ccache);
644 			*ccache = NULL;
645 		}
646 	}
647 
648 	#endif /* cc_context_create_ccache */
649 
650 	END_CHECK_ONCE;
651 
652 	return err;
653 }
654 
check_cc_context_create_default_ccache(void)655 int check_cc_context_create_default_ccache(void) {
656 	cc_int32 err = 0;
657 	cc_context_t context = NULL;
658 	cc_ccache_t ccache = NULL;
659 	cc_string_t name = NULL;
660 
661 	BEGIN_TEST("cc_context_create_default_ccache");
662 
663 	#ifndef cc_context_create_default_ccache
664 	log_error("cc_context_create_default_ccache is not implemented yet");
665 	failure_count++;
666 	#else
667 
668 	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
669 	if (!err) {
670 		// try making the default when there are no existing ccaches
671 		err = destroy_all_ccaches(context);
672 		if (!err) {
673 			err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL);
674 		}
675 		if (ccache) { cc_ccache_release(ccache); }
676 
677 		// try making a new default when one already exists
678 		if (!err) {
679 			err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL);
680 		}
681 
682 		// try bad parameters
683 		err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
684 		err = check_once_cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
685 	}
686 
687 	if (name) { cc_string_release(name); }
688 	if (ccache) { cc_ccache_destroy(ccache); }
689 	if (context) { cc_context_release(context); }
690 
691 	#endif /* cc_context_create_default_ccache */
692 
693 	END_TEST_AND_RETURN
694 }
695 
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)696 cc_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) {
697 	cc_int32 err = 0;
698 	cc_string_t stored_principal = NULL;
699 	cc_uint32 stored_creds_vers = 0;
700 
701 	cc_int32 possible_return_values[6] = {
702 		ccNoError,
703 		ccErrBadName, // how can this be possible when the name isn't a parameter?
704 		ccErrBadParam,
705 		ccErrInvalidContext,
706 		ccErrNoMem,
707 		ccErrBadCredentialsVersion,
708 	};
709 
710     BEGIN_CHECK_ONCE(description);
711 
712 	#ifdef cc_context_create_default_ccache
713 
714 	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
715 
716 	err = cc_context_create_default_ccache(context, cred_vers, principal, ccache);
717 
718 	// check returned error
719 	check_err(err, expected_err, possible_return_values);
720 
721 	if (!err) {
722 		if (ccache) { check_if(*ccache == NULL, NULL); }
723 		// make sure all of the ccache's info matches what we gave it
724 		// cred_vers
725 		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
726 		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
727 		// principal
728 		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
729 		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
730 		if (stored_principal) { cc_string_release(stored_principal); }
731 
732 		if (ccache && *ccache) {
733 			cc_ccache_release(*ccache);
734 			*ccache = NULL;
735 		}
736 	}
737 
738 	#endif /* cc_context_create_default_ccache */
739 
740 	END_CHECK_ONCE;
741 
742 	return err;
743 }
744 
check_cc_context_create_new_ccache(void)745 int check_cc_context_create_new_ccache(void) {
746 	cc_int32 err = 0;
747 	cc_context_t context = NULL;
748 	cc_ccache_t ccache = NULL;
749 	cc_string_t name = NULL;
750 
751 	BEGIN_TEST("cc_context_create_new_ccache");
752 
753 	#ifndef cc_context_create_new_ccache
754 	log_error("cc_context_create_new_ccache is not implemented yet");
755 	failure_count++;
756 	#else
757 
758 	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
759 	if (!err) {
760 		// try making when there are no existing ccaches (should have name of default)
761 		err = destroy_all_ccaches(context);
762 		if (!err) {
763 			err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", &ccache, ccNoError, NULL);
764 		}
765 		if (ccache) { cc_ccache_release(ccache); }
766 
767 		// try making a new ccache when one already exists (should not have name of default)
768 		if (!err) {
769 			err = check_once_cc_context_create_new_ccache(context, 0, cc_credentials_v5, "foo/baz@BAR.ORG", &ccache, ccNoError, NULL);
770 		}
771 		if (ccache) { cc_ccache_release(ccache); }
772 
773 		// try bad parameters
774 		err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, NULL, &ccache, ccErrBadParam, "NULL principal");                          // NULL principal
775 		err = check_once_cc_context_create_new_ccache(context, 1, cc_credentials_v5, "foo@BAR.ORG", NULL, ccErrBadParam, "NULL ccache");                    // NULL ccache
776 	}
777 
778 	if (name) { cc_string_release(name); }
779 	if (ccache) { cc_ccache_destroy(ccache); }
780 	if (context) { cc_context_release(context); }
781 
782 	#endif /* cc_context_create_new_ccache */
783 
784 	END_TEST_AND_RETURN
785 }
786 
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)787 cc_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) {
788 	cc_int32 err = 0;
789 	cc_string_t name = NULL;
790 	cc_string_t stored_name = NULL;
791 	cc_string_t stored_principal = NULL;
792 	cc_uint32 stored_creds_vers = 0;
793 
794 	cc_int32 possible_return_values[6] = {
795 		ccNoError,
796 		ccErrBadName, // how can this be possible when the name isn't a parameter?
797 		ccErrBadParam,
798 		ccErrInvalidContext,
799 		ccErrNoMem,
800 		ccErrBadCredentialsVersion,
801 	};
802 
803     BEGIN_CHECK_ONCE(description);
804 
805 	#ifdef cc_context_create_new_ccache
806 
807 	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
808 
809 	err = cc_context_create_new_ccache(context, cred_vers, principal, ccache);
810 
811 	// check returned error
812 	check_err(err, expected_err, possible_return_values);
813 
814 	if (!err) {
815 		if (ccache) { check_if(*ccache == NULL, NULL); }
816 		// make sure all of the ccache's info matches what we gave it
817 		if (!err) {
818 			err = cc_context_get_default_ccache_name(context, &name);
819 		}
820 		if (!err) {
821 			err = cc_ccache_get_name(*ccache, &stored_name);
822 		}
823 		if (!err) {
824 			if (should_be_default) {
825 				check_if(strcmp(stored_name->data, name->data), "new ccache does not have name of default");
826 			}
827 			else {
828 				check_if((strcmp(stored_name->data, name->data) == 0), "new cache has name of default");
829 			}
830 		}
831 		if (name) { cc_string_release(name); }
832 		if (stored_name) { cc_string_release(stored_name); }
833 
834 		// cred_vers
835 		err = cc_ccache_get_credentials_version(*ccache, &stored_creds_vers);
836 		if (!err) { check_if(stored_creds_vers != cred_vers, NULL); }
837 		// principal
838 		err = cc_ccache_get_principal(*ccache, cc_credentials_v5, &stored_principal);
839 		if (!err) { check_if(strcmp(stored_principal->data, principal), NULL); }
840 		if (stored_principal) { cc_string_release(stored_principal); }
841 
842 		if (ccache && *ccache) {
843 			cc_ccache_release(*ccache);
844 			*ccache = NULL;
845 		}
846 	}
847 
848 	#endif /* cc_context_create_new_ccache */
849 
850 	END_CHECK_ONCE;
851 
852 	return err;
853 }
854 
check_cc_context_new_ccache_iterator(void)855 int check_cc_context_new_ccache_iterator(void) {
856 	cc_int32 err = 0;
857 	cc_context_t context = NULL;
858 	cc_ccache_t ccache = NULL;
859 	cc_string_t name = NULL;
860 	cc_ccache_iterator_t iterator = NULL;
861 
862 	BEGIN_TEST("cc_context_new_ccache_iterator");
863 
864 	#ifndef cc_context_new_ccache_iterator
865 	log_error("cc_context_new_ccache_iterator is not implemented yet");
866 	failure_count++;
867 	#else
868 
869 	err = cc_initialize(&context, ccapi_version_3, NULL, NULL);
870 	if (!err) {
871 		err = destroy_all_ccaches(context);
872 	}
873 	if (!err) {
874 		// try making when there are no existing ccaches (shouldn't make a difference, but just in case)
875 		check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when there are no existing ccaches");
876 
877 		err = cc_context_create_default_ccache(context, cc_credentials_v5, "foo@BAR.ORG", &ccache);
878 	}
879 	if (!err) {
880 		// try making when at least one ccache already exists (just to cover all our bases)
881 		check_once_cc_context_new_ccache_iterator(context, &iterator, ccNoError, "when at least one ccache already exists");
882 
883 		// try bad parameters
884 		check_once_cc_context_new_ccache_iterator(context, NULL, ccErrBadParam, "NULL param"); // NULL iterator
885 	}
886 		// we'll do a comprehensive test of cc_ccache_iterator related functions later in the test suite
887 
888 	if (name) { cc_string_release(name); }
889 	if (ccache) { cc_ccache_destroy(ccache); }
890 	if (context) { cc_context_release(context); }
891 
892 	#endif /* cc_context_new_ccache_iterator */
893 
894 	END_TEST_AND_RETURN
895 }
896 
check_once_cc_context_new_ccache_iterator(cc_context_t context,cc_ccache_iterator_t * iterator,cc_int32 expected_err,const char * description)897 cc_int32 check_once_cc_context_new_ccache_iterator(cc_context_t context, cc_ccache_iterator_t *iterator, cc_int32 expected_err, const char *description) {
898 	cc_int32 err = ccNoError;
899 
900 	cc_int32 possible_return_values[4] = {
901 		ccNoError,
902 		ccErrBadParam,
903 		ccErrNoMem,
904 		ccErrInvalidContext,
905 	};
906 
907     BEGIN_CHECK_ONCE(description);
908 
909 	#ifdef cc_context_create_new_ccache
910 
911 	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
912 
913 	err = cc_context_new_ccache_iterator(context, iterator);
914 
915 	// check returned error
916 	check_err(err, expected_err, possible_return_values);
917 
918 	// we'll do a comprehensive test of cc_ccache_iterator related functions later
919 
920 	#endif /* cc_context_create_new_ccache */
921 
922 	return err;
923 }
924 
925 
926 // ---------------------------------------------------------------------------
927 
check_cc_context_compare(void)928 int check_cc_context_compare(void) {
929 	cc_int32 err = 0;
930 	cc_context_t context_a = NULL;
931 	cc_context_t context_b = NULL;
932 	cc_uint32 equal = 0;
933 
934 	BEGIN_TEST("cc_context_compare");
935 
936 	#ifndef cc_context_compare
937 	log_error("cc_context_compare is not implemented yet");
938 	failure_count++;
939 	#else
940 
941 	err = cc_initialize(&context_a, ccapi_version_3, NULL, NULL);
942 	if (!err) {
943 		err = cc_initialize(&context_b, ccapi_version_3, NULL, NULL);
944 	}
945 
946 	check_once_cc_context_compare(context_a, context_a, &equal, ccNoError, "valid params, same contexts");
947 	check_once_cc_context_compare(context_a, context_b, &equal, ccNoError, "valid params, different contexts");
948 	check_once_cc_context_compare(context_a, NULL, &equal, ccErrBadParam, "NULL compare_to context");
949 	check_once_cc_context_compare(context_a, context_b, NULL, ccErrBadParam, "NULL out param");
950 
951 	if (context_a) { cc_context_release(context_a); }
952 	if (context_b) { cc_context_release(context_b); }
953 
954 	#endif /* cc_context_compare */
955 
956 	END_TEST_AND_RETURN
957 }
958 
check_once_cc_context_compare(cc_context_t context,cc_context_t compare_to,cc_uint32 * equal,cc_int32 expected_err,const char * description)959 cc_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) {
960 	cc_int32 err = ccNoError;
961 
962 	cc_int32 possible_return_values[4] = {
963 		ccNoError,
964 		ccErrInvalidContext,
965 		ccErrBadParam,
966 		ccErrServerUnavailable,
967 	};
968 
969     BEGIN_CHECK_ONCE(description);
970 
971 	#ifdef cc_context_compare
972 
973 	#define possible_ret_val_count sizeof(possible_return_values)/sizeof(possible_return_values[0])
974 
975 	err = cc_context_compare(context, compare_to, equal);
976 
977 	if (!err) {
978 		*equal = 0;
979 	}
980 
981 	// check returned error
982 	check_err(err, expected_err, possible_return_values);
983 
984 	#endif /* cc_context_compare */
985 
986 	return err;
987 }
988