1 /* ccapi/lib/ccapi_v2.c */
2 /*
3 * Copyright 2006 Massachusetts Institute of Technology.
4 * All Rights Reserved.
5 *
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
10 *
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of M.I.T. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. Furthermore if you modify this software you must label
19 * your software as modified software and not distribute it in such a
20 * fashion that it might be confused with the original M.I.T. software.
21 * M.I.T. makes no representations about the suitability of
22 * this software for any purpose. It is provided "as is" without express
23 * or implied warranty.
24 */
25
26 #include "cci_common.h"
27 #include "ccapi_string.h"
28 #include "ccapi_context.h"
29 #include "ccapi_ccache.h"
30 #include "ccapi_ccache_iterator.h"
31 #include "ccapi_credentials.h"
32 #include "ccapi_credentials_iterator.h"
33 #include <CredentialsCache2.h>
34
35 infoNC infoNC_initializer = { NULL, NULL, CC_CRED_UNKNOWN };
36
37 /* ------------------------------------------------------------------------ */
38
cci_remap_version(cc_int32 in_v2_version,cc_uint32 * out_v3_version)39 static cc_int32 cci_remap_version (cc_int32 in_v2_version,
40 cc_uint32 *out_v3_version)
41 {
42 cc_result err = ccNoError;
43
44 if (!out_v3_version) { err = cci_check_error (ccErrBadParam); }
45
46 if (!err) {
47 if (in_v2_version == CC_CRED_V5) {
48 *out_v3_version = cc_credentials_v5;
49
50 } else {
51 err = ccErrBadCredentialsVersion;
52 }
53 }
54
55 return cci_check_error (err);
56 }
57
58 /* ------------------------------------------------------------------------ */
59
_cci_remap_error(cc_result in_error,const char * in_function,const char * in_file,int in_line)60 static cc_result _cci_remap_error (cc_result in_error,
61 const char *in_function,
62 const char *in_file,
63 int in_line)
64 {
65 _cci_check_error (in_error, in_function, in_file, in_line);
66
67 if (in_error >= CC_NOERROR && in_error <= CC_ERR_CRED_VERSION) {
68 return in_error;
69 }
70
71 switch (in_error) {
72 case ccNoError:
73 return CC_NOERROR;
74
75 case ccIteratorEnd:
76 return CC_END;
77
78 case ccErrBadParam:
79 case ccErrContextNotFound:
80 case ccErrInvalidContext:
81 case ccErrInvalidCredentials:
82 case ccErrInvalidCCacheIterator:
83 case ccErrInvalidCredentialsIterator:
84 case ccErrInvalidLock:
85 case ccErrBadLockType:
86 return CC_BAD_PARM;
87
88 case ccErrNoMem:
89 return CC_NOMEM;
90
91 case ccErrInvalidCCache:
92 case ccErrCCacheNotFound:
93 return CC_NO_EXIST;
94
95 case ccErrCredentialsNotFound:
96 return CC_NOTFOUND;
97
98 case ccErrBadName:
99 return CC_BADNAME;
100
101 case ccErrBadCredentialsVersion:
102 return CC_ERR_CRED_VERSION;
103
104 case ccErrBadAPIVersion:
105 return CC_BAD_API_VERSION;
106
107 case ccErrContextLocked:
108 case ccErrContextUnlocked:
109 case ccErrCCacheLocked:
110 case ccErrCCacheUnlocked:
111 return CC_LOCKED;
112
113 case ccErrServerUnavailable:
114 case ccErrServerInsecure:
115 case ccErrServerCantBecomeUID:
116 case ccErrBadInternalMessage:
117 case ccErrClientNotFound:
118 return CC_IO;
119
120 case ccErrNotImplemented:
121 return CC_NOT_SUPP;
122
123 default:
124 cci_debug_printf ("%s(): Unhandled error", __FUNCTION__);
125 return CC_BAD_PARM;
126 }
127 }
128 #define cci_remap_error(err) _cci_remap_error(err, __FUNCTION__, __FILE__, __LINE__)
129
130
131 #if TARGET_OS_MAC
132 #pragma mark -
133 #endif
134
135 /* ------------------------------------------------------------------------ */
136
cc_shutdown(apiCB ** io_context)137 cc_result cc_shutdown (apiCB **io_context)
138 {
139 cc_result err = ccNoError;
140
141 if (!io_context) { err = cci_check_error (ccErrBadParam); }
142
143 if (!err) {
144 err = ccapi_context_release (*io_context);
145 }
146
147 if (!err) {
148 *io_context = NULL;
149 }
150
151 return cci_remap_error (err);
152 }
153
154 /* ------------------------------------------------------------------------ */
155
cc_get_change_time(apiCB * in_context,cc_time_t * out_change_time)156 cc_result cc_get_change_time (apiCB *in_context,
157 cc_time_t *out_change_time)
158 {
159 cc_result err = ccNoError;
160
161 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
162 if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
163
164 if (!err) {
165 err = ccapi_context_get_change_time (in_context, out_change_time);
166 }
167
168 return cci_remap_error (err);
169 }
170
171 /* ------------------------------------------------------------------------ */
172
cc_get_NC_info(apiCB * in_context,infoNC *** out_info)173 cc_result cc_get_NC_info (apiCB *in_context,
174 infoNC ***out_info)
175 {
176 cc_result err = CC_NOERROR;
177 infoNC **info = NULL;
178 cc_uint64 count = 0; /* Preflight the size */
179 cc_uint64 i;
180
181 if (!in_context) { err = cci_check_error (ccErrBadParam); }
182 if (!out_info ) { err = cci_check_error (ccErrBadParam); }
183
184 if (!err) {
185 ccache_cit *iterator = NULL;
186
187 err = cc_seq_fetch_NCs_begin (in_context, &iterator);
188
189 while (!err) {
190 ccache_p *ccache = NULL;
191
192 err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
193
194 if (!err) { count++; }
195
196 if (ccache) { cc_close (in_context, &ccache); }
197 }
198 if (err == CC_END) { err = CC_NOERROR; }
199
200 if (!err) {
201 err = cc_seq_fetch_NCs_end (in_context, &iterator);
202 }
203 }
204
205 if (!err) {
206 info = malloc (sizeof (*info) * (count + 1));
207 if (info) {
208 for (i = 0; i < count + 1; i++) { info[i] = NULL; }
209 } else {
210 err = cci_check_error (CC_NOMEM);
211 }
212 }
213
214 if (!err) {
215 ccache_cit *iterator = NULL;
216
217 err = cc_seq_fetch_NCs_begin (in_context, &iterator);
218
219 for (i = 0; !err && i < count; i++) {
220 ccache_p *ccache = NULL;
221
222 err = cc_seq_fetch_NCs_next (in_context, &ccache, iterator);
223
224 if (!err) {
225 info[i] = malloc (sizeof (*info[i]));
226 if (info[i]) {
227 *info[i] = infoNC_initializer;
228 } else {
229 err = cci_check_error (CC_NOMEM);
230 }
231 }
232
233 if (!err) {
234 err = cc_get_name (in_context, ccache, &info[i]->name);
235 }
236
237 if (!err) {
238 err = cc_get_principal (in_context, ccache, &info[i]->principal);
239 }
240
241 if (!err) {
242 err = cc_get_cred_version (in_context, ccache, &info[i]->vers);
243 }
244
245 if (ccache) { cc_close (in_context, &ccache); }
246 }
247
248 if (!err) {
249 err = cc_seq_fetch_NCs_end (in_context, &iterator);
250 }
251 }
252
253 if (!err) {
254 *out_info = info;
255 info = NULL;
256 }
257
258 if (info) { cc_free_NC_info (in_context, &info); }
259
260 return cci_check_error (err);
261 }
262
263 #if TARGET_OS_MAC
264 #pragma mark -
265 #endif
266
267 /* ------------------------------------------------------------------------ */
268
cc_open(apiCB * in_context,const char * in_name,cc_int32 in_version,cc_uint32 in_flags,ccache_p ** out_ccache)269 cc_int32 cc_open (apiCB *in_context,
270 const char *in_name,
271 cc_int32 in_version,
272 cc_uint32 in_flags,
273 ccache_p **out_ccache)
274 {
275 cc_result err = ccNoError;
276 cc_ccache_t ccache = NULL;
277 cc_uint32 compat_version;
278 cc_uint32 real_version;
279
280 if (!in_context) { err = cci_check_error (ccErrBadParam); }
281 if (!in_name ) { err = cci_check_error (ccErrBadParam); }
282 if (!out_ccache) { err = cci_check_error (ccErrBadParam); }
283
284 if (!err) {
285 err = cci_remap_version (in_version, &compat_version);
286 }
287
288 if (!err) {
289 err = ccapi_context_open_ccache (in_context, in_name, &ccache);
290 }
291
292 /* We must not allow a CCAPI v2 caller to open a v5-only ccache
293 as a v4 ccache and vice versa. Allowing that would break
294 (valid) assumptions made by CCAPI v2 callers. */
295
296 if (!err) {
297 err = ccapi_ccache_get_credentials_version (ccache, &real_version);
298 }
299
300 if (!err) {
301 /* check the version and set up the ccache to use it */
302 if (compat_version & real_version) {
303 err = cci_ccache_set_compat_version (ccache, compat_version);
304 } else {
305 err = ccErrBadCredentialsVersion;
306 }
307 }
308
309 if (!err) {
310 *out_ccache = ccache;
311 ccache = NULL;
312 }
313
314 if (ccache) { ccapi_ccache_release (ccache); }
315
316 return cci_remap_error (err);
317 }
318
319 /* ------------------------------------------------------------------------ */
320
cc_create(apiCB * in_context,const char * in_name,const char * in_principal,cc_int32 in_version,cc_uint32 in_flags,ccache_p ** out_ccache)321 cc_result cc_create (apiCB *in_context,
322 const char *in_name,
323 const char *in_principal,
324 cc_int32 in_version,
325 cc_uint32 in_flags,
326 ccache_p **out_ccache)
327 {
328 cc_result err = ccNoError;
329 cc_ccache_t ccache = NULL;
330 cc_uint32 compat_version;
331
332 if (!in_context) { err = cci_check_error (ccErrBadParam); }
333 if (!in_name ) { err = cci_check_error (ccErrBadParam); }
334 if (!out_ccache) { err = cci_check_error (ccErrBadParam); }
335
336 if (!err) {
337 err = cci_remap_version (in_version, &compat_version);
338 }
339
340 if (!err) {
341 err = ccapi_context_create_ccache (in_context, in_name, compat_version,
342 in_principal, &ccache);
343 }
344
345 if (!err) {
346 err = cci_ccache_set_compat_version (ccache, compat_version);
347 }
348
349 if (!err) {
350 *out_ccache = ccache;
351 ccache = NULL;
352 }
353
354 if (ccache) { ccapi_ccache_release (ccache); }
355
356 return cci_remap_error (err);
357 }
358
359 /* ------------------------------------------------------------------------ */
360
cc_close(apiCB * in_context,ccache_p ** io_ccache)361 cc_result cc_close (apiCB *in_context,
362 ccache_p **io_ccache)
363 {
364 cc_result err = ccNoError;
365
366 if (!in_context) { err = cci_check_error (ccErrBadParam); }
367 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
368
369 if (!err) {
370 err = ccapi_ccache_release (*io_ccache);
371 }
372
373 if (!err) {
374 *io_ccache = NULL;
375 }
376
377 return cci_remap_error (err);
378 }
379
380 /* ------------------------------------------------------------------------ */
381
cc_destroy(apiCB * in_context,ccache_p ** io_ccache)382 cc_result cc_destroy (apiCB *in_context,
383 ccache_p **io_ccache)
384 {
385 cc_result err = ccNoError;
386
387 if (!in_context) { err = cci_check_error (ccErrBadParam); }
388 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
389
390 if (!err) {
391 err = ccapi_ccache_destroy (*io_ccache);
392 }
393
394 if (!err) {
395 *io_ccache = NULL;
396 }
397
398 return cci_remap_error (err);
399 }
400
401 /* ------------------------------------------------------------------------ */
402
cc_get_name(apiCB * in_context,ccache_p * in_ccache,char ** out_name)403 cc_result cc_get_name (apiCB *in_context,
404 ccache_p *in_ccache,
405 char **out_name)
406 {
407 cc_result err = ccNoError;
408 cc_string_t name = NULL;
409
410 if (!in_context) { err = cci_check_error (ccErrBadParam); }
411 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
412 if (!out_name ) { err = cci_check_error (ccErrBadParam); }
413
414 if (!err) {
415 err = ccapi_ccache_get_name (in_ccache, &name);
416 }
417
418 if (!err) {
419 char *string = strdup (name->data);
420 if (string) {
421 *out_name = string;
422 } else {
423 err = cci_check_error (ccErrNoMem);
424 }
425 }
426
427 if (name) { ccapi_string_release (name); }
428
429 return cci_remap_error (err);
430 }
431
432 /* ------------------------------------------------------------------------ */
433
cc_get_cred_version(apiCB * in_context,ccache_p * in_ccache,cc_int32 * out_version)434 cc_result cc_get_cred_version (apiCB *in_context,
435 ccache_p *in_ccache,
436 cc_int32 *out_version)
437 {
438 cc_result err = ccNoError;
439 cc_uint32 compat_version;
440
441 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
442 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
443 if (!out_version) { err = cci_check_error (ccErrBadParam); }
444
445 if (!err) {
446 err = cci_ccache_get_compat_version (in_ccache, &compat_version);
447 }
448
449 if (!err) {
450 if (compat_version == cc_credentials_v5) {
451 *out_version = CC_CRED_V5;
452
453 } else {
454 err = ccErrBadCredentialsVersion;
455 }
456 }
457
458 return cci_remap_error (err);
459 }
460
461 /* ------------------------------------------------------------------------ */
462
cc_set_principal(apiCB * in_context,ccache_p * io_ccache,cc_int32 in_version,char * in_principal)463 cc_result cc_set_principal (apiCB *in_context,
464 ccache_p *io_ccache,
465 cc_int32 in_version,
466 char *in_principal)
467 {
468 cc_result err = ccNoError;
469 cc_uint32 version;
470 cc_uint32 compat_version;
471
472 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
473 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
474 if (!in_principal) { err = cci_check_error (ccErrBadParam); }
475
476 if (!err) {
477 err = cci_remap_version (in_version, &version);
478 }
479
480 if (!err) {
481 err = cci_ccache_get_compat_version (io_ccache, &compat_version);
482 }
483
484 if (!err && version != compat_version) {
485 err = cci_check_error (ccErrBadCredentialsVersion);
486 }
487
488 if (!err) {
489 err = ccapi_ccache_set_principal (io_ccache, version, in_principal);
490 }
491
492 return cci_remap_error (err);
493 }
494
495 /* ------------------------------------------------------------------------ */
496
cc_get_principal(apiCB * in_context,ccache_p * in_ccache,char ** out_principal)497 cc_result cc_get_principal (apiCB *in_context,
498 ccache_p *in_ccache,
499 char **out_principal)
500 {
501 cc_result err = ccNoError;
502 cc_uint32 compat_version;
503 cc_string_t principal = NULL;
504
505 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
506 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
507 if (!out_principal) { err = cci_check_error (ccErrBadParam); }
508
509 if (!err) {
510 err = cci_ccache_get_compat_version (in_ccache, &compat_version);
511 }
512
513 if (!err) {
514 err = ccapi_ccache_get_principal (in_ccache, compat_version, &principal);
515 }
516
517 if (!err) {
518 char *string = strdup (principal->data);
519 if (string) {
520 *out_principal = string;
521 } else {
522 err = cci_check_error (ccErrNoMem);
523 }
524 }
525
526 if (principal) { ccapi_string_release (principal); }
527
528 return cci_remap_error (err);
529 }
530
531 /* ------------------------------------------------------------------------ */
532
cc_store(apiCB * in_context,ccache_p * io_ccache,cred_union in_credentials)533 cc_result cc_store (apiCB *in_context,
534 ccache_p *io_ccache,
535 cred_union in_credentials)
536 {
537 cc_result err = ccNoError;
538 cc_credentials_union *creds_union = NULL;
539
540 if (!in_context) { err = cci_check_error (ccErrBadParam); }
541 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
542
543 if (!err) {
544 err = cci_cred_union_to_credentials_union (&in_credentials,
545 &creds_union);
546 }
547
548 if (!err) {
549 err = ccapi_ccache_store_credentials (io_ccache, creds_union);
550 }
551
552 if (creds_union) { cci_credentials_union_release (creds_union); }
553 return cci_remap_error (err);
554 }
555
556 /* ------------------------------------------------------------------------ */
557
cc_remove_cred(apiCB * in_context,ccache_p * in_ccache,cred_union in_credentials)558 cc_result cc_remove_cred (apiCB *in_context,
559 ccache_p *in_ccache,
560 cred_union in_credentials)
561 {
562 cc_result err = ccNoError;
563 cc_credentials_iterator_t iterator = NULL;
564 cc_uint32 found = 0;
565
566 if (!in_context) { err = cci_check_error (ccErrBadParam); }
567 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
568
569 if (!err) {
570 err = ccapi_ccache_new_credentials_iterator (in_ccache, &iterator);
571 }
572
573 while (!err && !found) {
574 cc_credentials_t creds = NULL;
575
576 err = ccapi_credentials_iterator_next (iterator, &creds);
577
578 if (!err) {
579 err = cci_cred_union_compare_to_credentials_union (&in_credentials,
580 creds->data,
581 &found);
582 }
583
584 if (!err && found) {
585 err = ccapi_ccache_remove_credentials (in_ccache, creds);
586 }
587
588 ccapi_credentials_release (creds);
589 }
590 if (err == ccIteratorEnd) { err = cci_check_error (ccErrCredentialsNotFound); }
591
592 return cci_remap_error (err);
593 }
594
595 #if TARGET_OS_MAC
596 #pragma mark -
597 #endif
598
599 /* ------------------------------------------------------------------------ */
600
cc_seq_fetch_NCs_begin(apiCB * in_context,ccache_cit ** out_iterator)601 cc_result cc_seq_fetch_NCs_begin (apiCB *in_context,
602 ccache_cit **out_iterator)
603 {
604 cc_result err = ccNoError;
605 cc_ccache_iterator_t iterator = NULL;
606
607 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
608 if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
609
610 if (!err) {
611 err = ccapi_context_new_ccache_iterator (in_context, &iterator);
612 }
613
614 if (!err) {
615 *out_iterator = (ccache_cit *) iterator;
616 iterator = NULL; /* take ownership */
617 }
618
619 if (iterator) { ccapi_ccache_iterator_release (iterator); }
620
621 return cci_remap_error (err);
622 }
623
624 /* ------------------------------------------------------------------------ */
625
cc_seq_fetch_NCs_next(apiCB * in_context,ccache_p ** out_ccache,ccache_cit * in_iterator)626 cc_result cc_seq_fetch_NCs_next (apiCB *in_context,
627 ccache_p **out_ccache,
628 ccache_cit *in_iterator)
629 {
630 cc_result err = ccNoError;
631 cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) in_iterator;
632 cc_ccache_t ccache = NULL;
633 const char *saved_ccache_name;
634
635 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
636 if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
637 if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
638
639 if (!err) {
640 err = cci_ccache_iterator_get_saved_ccache_name (iterator,
641 &saved_ccache_name);
642 }
643
644 if (!err) {
645 if (saved_ccache_name) {
646 err = ccapi_context_open_ccache (in_context, saved_ccache_name,
647 &ccache);
648
649 if (!err) {
650 err = cci_ccache_set_compat_version (ccache, cc_credentials_v5);
651 }
652
653 if (!err) {
654 err = cci_ccache_iterator_set_saved_ccache_name (iterator, NULL);
655 }
656
657 } else {
658 cc_uint32 version = 0;
659
660 err = ccapi_ccache_iterator_next (iterator, &ccache);
661
662 if (!err) {
663 err = ccapi_ccache_get_credentials_version (ccache, &version);
664 }
665
666 if (!err) {
667 err = cci_ccache_set_compat_version (ccache, version);
668 }
669 }
670 }
671
672 if (!err) {
673 *out_ccache = ccache;
674 ccache = NULL; /* take ownership */
675 }
676
677 if (ccache) { ccapi_ccache_release (ccache); }
678
679 return cci_remap_error (err);
680 }
681
682 /* ------------------------------------------------------------------------ */
683
cc_seq_fetch_NCs_end(apiCB * in_context,ccache_cit ** io_iterator)684 cc_result cc_seq_fetch_NCs_end (apiCB *in_context,
685 ccache_cit **io_iterator)
686 {
687 cc_result err = ccNoError;
688 cc_ccache_iterator_t iterator = (cc_ccache_iterator_t) *io_iterator;
689
690 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
691 if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
692
693 if (!err) {
694 err = ccapi_ccache_iterator_release (iterator);
695 }
696
697 if (!err) {
698 *io_iterator = NULL;
699 }
700
701 return cci_remap_error (err);
702 }
703
704 #if TARGET_OS_MAC
705 #pragma mark -
706 #endif
707
708 /* ------------------------------------------------------------------------ */
709
cc_seq_fetch_creds_begin(apiCB * in_context,const ccache_p * in_ccache,ccache_cit ** out_iterator)710 cc_result cc_seq_fetch_creds_begin (apiCB *in_context,
711 const ccache_p *in_ccache,
712 ccache_cit **out_iterator)
713 {
714 cc_result err = ccNoError;
715 cc_credentials_iterator_t iterator = NULL;
716 cc_uint32 compat_version;
717
718 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
719 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
720 if (!out_iterator) { err = cci_check_error (ccErrBadParam); }
721
722 if (!err) {
723 err = cci_ccache_get_compat_version ((cc_ccache_t) in_ccache,
724 &compat_version);
725 }
726
727 if (!err) {
728 err = ccapi_ccache_new_credentials_iterator ((cc_ccache_t) in_ccache,
729 &iterator);
730 }
731
732 if (!err) {
733 err = cci_credentials_iterator_set_compat_version (iterator,
734 compat_version);
735 }
736
737 if (!err) {
738 *out_iterator = (ccache_cit *) iterator;
739 iterator = NULL; /* take ownership */
740 }
741
742 if (iterator) { ccapi_credentials_iterator_release (iterator); }
743
744 return cci_remap_error (err);
745 }
746
747 /* ------------------------------------------------------------------------ */
748
cc_seq_fetch_creds_next(apiCB * in_context,cred_union ** out_creds,ccache_cit * in_iterator)749 cc_result cc_seq_fetch_creds_next (apiCB *in_context,
750 cred_union **out_creds,
751 ccache_cit *in_iterator)
752 {
753 cc_result err = ccNoError;
754 cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) in_iterator;
755 cc_uint32 compat_version;
756
757 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
758 if (!out_creds ) { err = cci_check_error (ccErrBadParam); }
759 if (!in_iterator) { err = cci_check_error (ccErrBadParam); }
760
761 if (!err) {
762 err = cci_credentials_iterator_get_compat_version (iterator,
763 &compat_version);
764 }
765
766 while (!err) {
767 cc_credentials_t credentials = NULL;
768
769 err = ccapi_credentials_iterator_next (iterator, &credentials);
770
771 if (!err && (credentials->data->version & compat_version)) {
772 /* got the next credentials for the correct version */
773 err = cci_credentials_union_to_cred_union (credentials->data,
774 out_creds);
775 break;
776 }
777
778 if (credentials) { ccapi_credentials_release (credentials); }
779 }
780
781 return cci_remap_error (err);
782 }
783
784 /* ------------------------------------------------------------------------ */
785
cc_seq_fetch_creds_end(apiCB * in_context,ccache_cit ** io_iterator)786 cc_result cc_seq_fetch_creds_end (apiCB *in_context,
787 ccache_cit **io_iterator)
788 {
789 cc_result err = ccNoError;
790 cc_credentials_iterator_t iterator = (cc_credentials_iterator_t) *io_iterator;
791
792 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
793 if (!io_iterator) { err = cci_check_error (ccErrBadParam); }
794
795 if (!err) {
796 err = ccapi_credentials_iterator_release (iterator);
797 }
798
799 if (!err) {
800 *io_iterator = NULL;
801 }
802
803 return cci_remap_error (err);
804 }
805
806 #if TARGET_OS_MAC
807 #pragma mark -
808 #endif
809
810 /* ------------------------------------------------------------------------ */
811
cc_free_principal(apiCB * in_context,char ** io_principal)812 cc_result cc_free_principal (apiCB *in_context,
813 char **io_principal)
814 {
815 cc_result err = ccNoError;
816
817 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
818 if (!io_principal) { err = cci_check_error (ccErrBadParam); }
819
820 if (!err) {
821 free (*io_principal);
822 *io_principal = NULL;
823 }
824
825 return cci_remap_error (err);
826 }
827
828 /* ------------------------------------------------------------------------ */
829
cc_free_name(apiCB * in_context,char ** io_name)830 cc_result cc_free_name (apiCB *in_context,
831 char **io_name)
832 {
833 cc_result err = ccNoError;
834
835 if (!in_context) { err = cci_check_error (ccErrBadParam); }
836 if (!io_name ) { err = cci_check_error (ccErrBadParam); }
837
838 if (!err) {
839 free (*io_name);
840 *io_name = NULL;
841 }
842
843 return cci_remap_error (err);
844 }
845
846 /* ------------------------------------------------------------------------ */
847
cc_free_creds(apiCB * in_context,cred_union ** io_credentials)848 cc_result cc_free_creds (apiCB *in_context,
849 cred_union **io_credentials)
850 {
851 cc_result err = ccNoError;
852
853 if (!in_context ) { err = cci_check_error (ccErrBadParam); }
854 if (!io_credentials) { err = cci_check_error (ccErrBadParam); }
855
856 if (!err) {
857 err = cci_cred_union_release (*io_credentials);
858 if (!err) { *io_credentials = NULL; }
859 }
860
861 return cci_remap_error (err);
862 }
863
864 /* ------------------------------------------------------------------------ */
865
cc_free_NC_info(apiCB * in_context,infoNC *** io_info)866 cc_result cc_free_NC_info (apiCB *in_context,
867 infoNC ***io_info)
868 {
869 cc_result err = ccNoError;
870
871 if (!in_context) { err = cci_check_error (ccErrBadParam); }
872 if (!io_info ) { err = cci_check_error (ccErrBadParam); }
873
874 if (!err && *io_info) {
875 infoNC **data = *io_info;
876 int i;
877
878 for (i = 0; data[i] != NULL; i++) {
879 cc_free_principal (in_context, &data[i]->principal);
880 cc_free_name (in_context, &data[i]->name);
881 free (data[i]);
882 }
883 free (data);
884
885 *io_info = NULL;
886 }
887
888 return cci_remap_error (err);
889 }
890