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