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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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