1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <stdlib.h> 26 #include <strings.h> 27 #include <ctype.h> 28 #include <locale.h> 29 #include <syslog.h> 30 #include "ns_internal.h" 31 32 /* 33 * Calculate a hash for a string 34 * Based on elf_hash algorithm, hash is case insensitive 35 * Uses tolower instead of _tolower because of I18N 36 */ 37 38 static unsigned long 39 ns_hash(const char *str) 40 { 41 unsigned int hval = 0; 42 43 while (*str) { 44 unsigned int g; 45 46 hval = (hval << 4) + tolower(*str++); 47 if ((g = (hval & 0xf0000000)) != 0) 48 hval ^= g >> 24; 49 hval &= ~g; 50 } 51 return ((unsigned long)hval); 52 } 53 54 /* 55 * Scan a hash table hit for a matching hash entry. 56 * Assume service and str are non-NULL. 57 */ 58 59 static ns_hash_t * 60 ns_scan_hash(ns_hashtype_t type, const char *service, 61 const char *str, ns_hash_t *idx) 62 { 63 while (idx) { 64 if (idx->h_type == type && 65 strcasecmp(service, idx->h_map->service) == 0 && 66 strcasecmp(str, idx->h_map->orig) == 0) { 67 return (idx); 68 } 69 idx = idx->h_next; 70 } 71 return ((ns_hash_t *)NULL); 72 } 73 74 /* 75 * Find an entry in the hash table 76 */ 77 78 static ns_hash_t * 79 ns_get_hash(const ns_config_t *config, 80 ns_hashtype_t type, const char *service, const char *str) 81 { 82 ns_hash_t *idx, *hashp; 83 unsigned long hash; 84 85 if (config == NULL || service == NULL || str == NULL) 86 return (NULL); 87 88 hash = ns_hash(str) % NS_HASH_MAX; 89 idx = config->hashTbl[hash]; 90 hashp = ns_scan_hash(type, service, str, idx); 91 92 return (hashp); 93 } 94 95 /* 96 * free a map entry 97 */ 98 99 static void 100 ns_free_map(ns_mapping_t *mapp) 101 { 102 char **ptr; 103 104 if (mapp == NULL) 105 return; 106 if (mapp->service) { 107 free(mapp->service); 108 mapp->service = NULL; 109 } 110 if (mapp->orig) { 111 free(mapp->orig); 112 mapp->orig = NULL; 113 } 114 if (mapp->map) { 115 for (ptr = mapp->map; *ptr; ptr++) 116 free(*ptr); 117 free(mapp->map); 118 mapp->map = NULL; 119 } 120 free(mapp); 121 } 122 123 /* 124 * Remove a hash table entry. 125 * This function is not MT safe. 126 */ 127 128 static ns_hash_t * 129 ns_free_hash(ns_hash_t *p) 130 { 131 ns_mapping_t *map; 132 ns_hash_t *next; 133 134 map = p->h_map; 135 next = p->h_next; 136 ns_free_map(map); 137 free(p); 138 return (next); 139 } 140 141 /* 142 * destroy the hash table. 143 * This function is not MT safe. 144 */ 145 146 void 147 __s_api_destroy_hash(ns_config_t *config) 148 { 149 ns_hash_t *next; 150 int i; 151 152 if (config == NULL) 153 return; 154 for (i = 0; i < NS_HASH_MAX; i++) { 155 next = config->hashTbl[i]; 156 while (next != NULL) { 157 next = ns_free_hash(next); 158 } 159 config->hashTbl[i] = NULL; 160 } 161 } 162 163 /* 164 * Add a hash entry to the hash table. 165 * This function is not MT safe. 166 * Assume map, map->orig, map->service are non-NULL. 167 */ 168 169 int 170 __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type, 171 ns_mapping_t *map) 172 { 173 ns_hash_t *idx, *newp; 174 unsigned long hash; 175 176 if (config == NULL) 177 return (NS_HASH_RC_CONFIG_ERROR); 178 179 hash = ns_hash(map->orig) % NS_HASH_MAX; 180 idx = config->hashTbl[hash]; 181 if (idx != NULL && 182 ns_scan_hash(type, map->service, map->orig, idx) != NULL) { 183 return (NS_HASH_RC_EXISTED); 184 } 185 186 newp = (ns_hash_t *)malloc(sizeof (ns_hash_t)); 187 if (newp == NULL) 188 return (NS_HASH_RC_NO_MEMORY); 189 newp->h_type = type; 190 newp->h_map = map; 191 newp->h_next = idx; 192 config->hashTbl[hash] = newp; 193 newp->h_llnext = config->llHead; 194 config->llHead = newp; 195 return (NS_HASH_RC_SUCCESS); 196 } 197 198 199 /* 200 * Parse an attribute map string. 201 * Assume space is the only legal whitespace. 202 * attributeMap syntax: 203 * attributeMap = serviceId ":" origAttribute "=" 204 * attributes 205 * origAttribute = attribute 206 * attributes = wattribute *( space wattribute ) 207 * wattribute = whsp newAttribute whsp 208 * newAttribute = descr | "*NULL*" 209 * attribute = descr 210 * 211 * objectclassMap syntax: 212 * objectclassMap = serviceId ":" origObjectclass "=" 213 * objectclass 214 * origObjectclass = objectclass 215 * objectclass = keystring 216 */ 217 218 int 219 __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA) 220 { 221 char *sptr, *dptr, **mapp; 222 int i, max; 223 224 *sid = NULL; 225 *origA = NULL; 226 *mapA = NULL; 227 228 sptr = cp; 229 dptr = strchr(sptr, COLONTOK); 230 if (dptr == NULL) 231 return (NS_HASH_RC_SYNTAX_ERROR); 232 i = dptr - sptr + 1; 233 *sid = (char *)malloc(i); 234 if (*sid == NULL) 235 return (NS_HASH_RC_NO_MEMORY); 236 (void) strlcpy(*sid, sptr, i); 237 sptr = dptr+1; 238 239 dptr = strchr(sptr, TOKENSEPARATOR); 240 if (dptr == NULL) { 241 free(*sid); 242 *sid = NULL; 243 return (NS_HASH_RC_SYNTAX_ERROR); 244 } 245 i = dptr - sptr + 1; 246 *origA = (char *)malloc(i); 247 if (*origA == NULL) { 248 free(*sid); 249 *sid = NULL; 250 return (NS_HASH_RC_NO_MEMORY); 251 } 252 (void) strlcpy(*origA, sptr, i); 253 sptr = dptr+1; 254 255 max = 1; 256 for (dptr = sptr; *dptr; dptr++) { 257 if (*dptr == SPACETOK) { 258 max++; 259 while (*(dptr+1) == SPACETOK) 260 dptr++; 261 } 262 } 263 *mapA = (char **)calloc(max+1, sizeof (char *)); 264 if (*mapA == NULL) { 265 free(*sid); 266 *sid = NULL; 267 free(*origA); 268 *origA = NULL; 269 return (NS_HASH_RC_NO_MEMORY); 270 } 271 mapp = *mapA; 272 273 while (*sptr) { 274 while (*sptr == SPACETOK) 275 sptr++; 276 dptr = sptr; 277 while (*dptr && *dptr != SPACETOK) 278 dptr++; 279 i = dptr - sptr + 1; 280 *mapp = (char *)malloc(i); 281 if (*mapp == NULL) { 282 free(*sid); 283 *sid = NULL; 284 free(*origA); 285 *origA = NULL; 286 __s_api_free2dArray(*mapA); 287 *mapA = NULL; 288 return (NS_HASH_RC_NO_MEMORY); 289 } 290 (void) strlcpy(*mapp, sptr, i); 291 mapp++; 292 sptr = dptr; 293 } 294 return (NS_HASH_RC_SUCCESS); 295 } 296 297 298 static void 299 __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr) 300 { 301 if (ptr == NULL) 302 return; 303 if (ptr->basedn) 304 free(ptr->basedn); 305 if (ptr->filter) 306 free(ptr->filter); 307 free(ptr); 308 } 309 310 /* 311 * Parse a service descriptor 312 * and create a service descriptor struct 313 * SD Format: 314 * serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]] 315 * desc format: 316 * [base][?[scope][?[filter]]] 317 */ 318 319 typedef enum _ns_parse_state { 320 P_ERROR, P_INIT, P_BASEDN, P_SCOPE, 321 P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR 322 } _ns_parse_state_t; 323 324 static 325 int 326 __s_api_parseASearchDesc(const char *service, 327 char **cur, ns_ldap_search_desc_t **ret) 328 { 329 ns_ldap_search_desc_t *ptr; 330 char *sptr, *dptr; 331 char buf[BUFSIZ]; 332 int i, rc; 333 ns_ldap_error_t **errorp = NULL; 334 ns_ldap_error_t *error = NULL; 335 void **paramVal = NULL; 336 char **dns = NULL; 337 _ns_parse_state_t state = P_INIT; 338 int quoted = 0; 339 int wasquoted = 0; 340 int empty = 1; 341 342 if (ret == NULL) 343 return (NS_LDAP_INVALID_PARAM); 344 *ret = NULL; 345 if (cur == NULL) 346 return (NS_LDAP_INVALID_PARAM); 347 348 ptr = (ns_ldap_search_desc_t *) 349 calloc(1, sizeof (ns_ldap_search_desc_t)); 350 if (ptr == NULL) 351 return (NS_LDAP_MEMORY); 352 353 sptr = *cur; 354 355 /* Get the default scope */ 356 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, 357 ¶mVal, errorp)) != NS_LDAP_SUCCESS) { 358 (void) __ns_ldap_freeError(errorp); 359 __ns_ldap_freeASearchDesc(ptr); 360 ptr = NULL; 361 return (NS_LDAP_MEMORY); 362 } 363 if (paramVal && *paramVal) 364 ptr->scope = * (ScopeType_t *)(*paramVal); 365 else 366 ptr->scope = NS_LDAP_SCOPE_ONELEVEL; 367 (void) __ns_ldap_freeParam(¶mVal); 368 paramVal = NULL; 369 370 for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) { 371 empty = 0; 372 switch (state) { 373 case P_INIT: 374 if (*sptr == QUESTTOK) { 375 /* No basedn */ 376 ptr->basedn = strdup(""); 377 if (!ptr->basedn) { 378 state = P_MEMERR; 379 break; 380 } 381 state = P_SCOPE; 382 break; 383 } 384 if (*sptr == SEMITOK) { 385 /* No SSD */ 386 ptr->basedn = strdup(""); 387 if (!ptr->basedn) { 388 state = P_MEMERR; 389 break; 390 } 391 state = P_EXIT; 392 break; 393 } 394 /* prepare to copy DN */ 395 i = strlen(sptr) + 1; 396 ptr->basedn = dptr = (char *)calloc(i, sizeof (char)); 397 if (!ptr->basedn) { 398 state = P_MEMERR; 399 break; 400 } 401 if (*sptr == BSLTOK) { 402 if (*(sptr+1) == '\0') { 403 /* error */ 404 state = P_ERROR; 405 break; 406 } 407 if (*(sptr+1) == QUOTETOK || 408 *(sptr+1) == BSLTOK) { 409 /* escaped CHARS */ 410 sptr++; 411 } else { 412 *dptr++ = *sptr++; 413 } 414 *dptr++ = *sptr; 415 } else if (*sptr == QUOTETOK) { 416 quoted = 1; 417 wasquoted = 1; 418 } else { 419 *dptr++ = *sptr; 420 } 421 state = P_BASEDN; 422 break; 423 case P_INIFILTER: 424 if (*sptr == SEMITOK) { 425 /* No filter and no more SSD */ 426 state = P_EXIT; 427 break; 428 } 429 /* prepare to copy DN */ 430 i = strlen(sptr) + 1; 431 ptr->filter = dptr = (char *)calloc(i, sizeof (char)); 432 if (!ptr->filter) { 433 state = P_MEMERR; 434 break; 435 } 436 if (*sptr == BSLTOK) { 437 if (*(sptr+1) == '\0') { 438 /* error */ 439 state = P_ERROR; 440 break; 441 } 442 if (*(sptr+1) == QUOTETOK || 443 *(sptr+1) == BSLTOK) { 444 /* escaped CHARS */ 445 sptr++; 446 } else { 447 *dptr++ = *sptr++; 448 } 449 *dptr++ = *sptr; 450 } else if (*sptr == QUOTETOK) { 451 quoted = 1; 452 wasquoted = 1; 453 } else { 454 *dptr++ = *sptr; 455 } 456 state = P_FILTER; 457 break; 458 case P_SCOPE: 459 buf[0] = '\0'; 460 if (*sptr == SEMITOK) { 461 /* no more SSD */ 462 state = P_EXIT; 463 break; 464 } 465 if (strncasecmp(sptr, "base", 4) == 0) { 466 sptr += 4; 467 ptr->scope = NS_LDAP_SCOPE_BASE; 468 } else if (strncasecmp(sptr, "one", 3) == 0) { 469 ptr->scope = NS_LDAP_SCOPE_ONELEVEL; 470 sptr += 3; 471 } else if (strncasecmp(sptr, "sub", 3) == 0) { 472 ptr->scope = NS_LDAP_SCOPE_SUBTREE; 473 sptr += 3; 474 } 475 if (*sptr == '\0' || (*sptr == SEMITOK)) { 476 /* no more SSD */ 477 state = P_EXIT; 478 sptr--; 479 break; 480 } 481 if (*sptr != QUESTTOK) { 482 state = P_ERROR; 483 break; 484 } 485 state = P_INIFILTER; 486 quoted = 0; 487 wasquoted = 0; 488 break; 489 case P_BASEDN: 490 case P_FILTER: 491 if (quoted) { 492 /* Quoted */ 493 if (*sptr == BSLTOK) { 494 if (*(sptr+1) == '\0') { 495 state = P_ERROR; 496 break; 497 } 498 if (*(sptr+1) == QUOTETOK || 499 *(sptr+1) == BSLTOK) { 500 /* escaped CHARS */ 501 sptr++; 502 } else { 503 *dptr++ = *sptr++; 504 } 505 /* fall through to char copy */ 506 } else if (*sptr == QUOTETOK) { 507 /* end of string */ 508 *dptr = '\0'; 509 quoted = 0; 510 break; 511 } 512 /* else fall through to char copy */ 513 } else { 514 /* Unquoted */ 515 if (wasquoted && *sptr != QUESTTOK) { 516 /* error past end of quoted string */ 517 state = P_ERROR; 518 break; 519 } 520 if (*sptr == BSLTOK) { 521 if (*(sptr+1) == '\0') { 522 state = P_ERROR; 523 break; 524 } 525 if (*(sptr+1) == SEMITOK || 526 *(sptr+1) == QUESTTOK || 527 *(sptr+1) == QUOTETOK || 528 *(sptr+1) == BSLTOK) { 529 /* escaped chars */ 530 sptr++; 531 } 532 /* fall through to char copy */ 533 } else if (*sptr == QUOTETOK) { 534 /* error */ 535 state = P_ERROR; 536 break; 537 } else if (*sptr == QUESTTOK) { 538 /* if filter error */ 539 if (state == P_FILTER) { 540 state = P_ERROR; 541 break; 542 } 543 /* end of basedn goto scope */ 544 *dptr = '\0'; 545 state = P_SCOPE; 546 break; 547 } else if (*sptr == SEMITOK) { 548 /* end of current SSD */ 549 *dptr = '\0'; 550 state = P_EXIT; 551 break; 552 } 553 } 554 /* normal character to copy */ 555 *dptr++ = *sptr; 556 break; 557 case P_END: 558 if (*sptr == SEMITOK) { 559 state = P_EXIT; 560 break; 561 } 562 __ns_ldap_freeASearchDesc(ptr); 563 ptr = NULL; 564 *cur = NULL; 565 return (NS_LDAP_CONFIG); 566 default: /* error should never arrive here */ 567 case P_ERROR: 568 __ns_ldap_freeASearchDesc(ptr); 569 ptr = NULL; 570 *cur = NULL; 571 return (NS_LDAP_CONFIG); 572 case P_MEMERR: 573 __ns_ldap_freeASearchDesc(ptr); 574 ptr = NULL; 575 *cur = NULL; 576 return (NS_LDAP_MEMORY); 577 } 578 } 579 580 if (quoted) { 581 __ns_ldap_freeASearchDesc(ptr); 582 ptr = NULL; 583 *cur = NULL; 584 return (NS_LDAP_INVALID_PARAM); 585 } 586 587 if (empty || strlen(ptr->basedn) == 0) { 588 if (ptr->basedn) 589 free(ptr->basedn); 590 /* get default base */ 591 rc = __s_api_getDNs(&dns, service, &error); 592 if (rc != NS_LDAP_SUCCESS) { 593 if (dns) { 594 __s_api_free2dArray(dns); 595 dns = NULL; 596 } 597 (void) __ns_ldap_freeError(&error); 598 __ns_ldap_freeASearchDesc(ptr); 599 ptr = NULL; 600 return (NS_LDAP_MEMORY); 601 } 602 ptr->basedn = strdup(dns[0]); 603 __s_api_free2dArray(dns); 604 dns = NULL; 605 } 606 607 *cur = sptr; 608 *ret = ptr; 609 return (NS_LDAP_SUCCESS); 610 } 611 612 613 /* 614 * Build up the service descriptor array 615 */ 616 #define NS_SDESC_MAX 4 617 618 static int 619 __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist, 620 int *cnt, int *max, ns_ldap_search_desc_t *ret) 621 { 622 ns_ldap_search_desc_t **tmplist; 623 624 if (*sdlist == NULL) { 625 *cnt = 0; 626 *max = NS_SDESC_MAX; 627 *sdlist = (ns_ldap_search_desc_t **) 628 calloc(*max, sizeof (ns_ldap_search_desc_t *)); 629 if (*sdlist == NULL) 630 return (-1); 631 } else if (*cnt+1 >= *max) { 632 *max += NS_SDESC_MAX; 633 tmplist = (ns_ldap_search_desc_t **) 634 realloc((void *)(*sdlist), 635 *max * sizeof (ns_ldap_search_desc_t *)); 636 if (tmplist == NULL) 637 return (-1); 638 else 639 *sdlist = tmplist; 640 } 641 (*sdlist)[*cnt] = ret; 642 (*cnt)++; 643 (*sdlist)[*cnt] = NULL; 644 return (0); 645 } 646 647 648 /* 649 * Exported Search Descriptor Routines 650 */ 651 652 int __ns_ldap_getSearchDescriptors( 653 const char *service, 654 ns_ldap_search_desc_t ***desc, 655 ns_ldap_error_t **errorp) 656 { 657 int rc; 658 int slen; 659 void **param = NULL; 660 void **paramVal = NULL; 661 char **sdl, *srv, **sdl_save; 662 char errstr[2 * MAXERROR]; 663 ns_ldap_search_desc_t **sdlist; 664 int cnt, max; 665 int vers; 666 ns_config_t *cfg; 667 ns_ldap_search_desc_t *ret; 668 669 if ((desc == NULL) || (errorp == NULL)) 670 return (NS_LDAP_INVALID_PARAM); 671 672 *desc = NULL; 673 *errorp = NULL; 674 675 rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P, 676 (void ***)¶m, errorp); 677 if (rc != NS_LDAP_SUCCESS) { 678 return (rc); 679 } 680 sdl = (char **)param; 681 cnt = 0; 682 max = 0; 683 sdlist = NULL; 684 685 cfg = __s_api_get_default_config(); 686 687 if (cfg == NULL) { 688 (void) snprintf(errstr, sizeof (errstr), 689 gettext("No configuration information available.")); 690 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 691 NULL); 692 return (NS_LDAP_CONFIG); 693 } 694 695 vers = cfg->version; 696 __s_api_release_config(cfg); 697 698 /* If using version1 or no sd's process SEARCH_DN if available */ 699 if (vers == NS_LDAP_V1 && param == NULL) { 700 rc = __s_api_get_search_DNs_v1(&sdl, service, errorp); 701 if (rc != NS_LDAP_SUCCESS || sdl == NULL) { 702 return (rc); 703 } 704 sdl_save = sdl; 705 /* Convert a SEARCH_DN to a search descriptor */ 706 for (; *sdl; sdl++) { 707 ret = (ns_ldap_search_desc_t *) 708 calloc(1, sizeof (ns_ldap_search_desc_t)); 709 if (ret == NULL) { 710 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 711 __s_api_free2dArray(sdl_save); 712 return (NS_LDAP_MEMORY); 713 } 714 ret->basedn = strdup(*sdl); 715 if (ret->basedn == NULL) { 716 free(ret); 717 (void) __ns_ldap_freeASearchDesc(ret); 718 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 719 __s_api_free2dArray(sdl_save); 720 return (NS_LDAP_MEMORY); 721 } 722 723 /* default scope */ 724 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, 725 ¶mVal, errorp)) != NS_LDAP_SUCCESS) { 726 (void) __ns_ldap_freeASearchDesc(ret); 727 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 728 __s_api_free2dArray(sdl_save); 729 return (rc); 730 } 731 if (paramVal && *paramVal) 732 ret->scope = * (ScopeType_t *)(*paramVal); 733 else 734 ret->scope = NS_LDAP_SCOPE_ONELEVEL; 735 (void) __ns_ldap_freeParam(¶mVal); 736 paramVal = NULL; 737 738 rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret); 739 if (rc < 0) { 740 (void) __ns_ldap_freeASearchDesc(ret); 741 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 742 __s_api_free2dArray(sdl_save); 743 return (NS_LDAP_MEMORY); 744 } 745 } 746 __s_api_free2dArray(sdl_save); 747 *desc = sdlist; 748 return (NS_LDAP_SUCCESS); 749 } 750 751 if (sdl == NULL || service == NULL) { 752 (void) __ns_ldap_freeParam(¶m); 753 param = NULL; 754 *desc = NULL; 755 return (NS_LDAP_SUCCESS); 756 } 757 slen = strlen(service); 758 759 /* Process the version2 sd's */ 760 for (; *sdl; sdl++) { 761 srv = *sdl; 762 if (strncasecmp(service, srv, slen) != 0) 763 continue; 764 srv += slen; 765 if (*srv != COLONTOK) 766 continue; 767 srv++; 768 while (srv != NULL && *srv != NULL) { 769 /* Process 1 */ 770 rc = __s_api_parseASearchDesc(service, &srv, &ret); 771 if (rc != NS_LDAP_SUCCESS) { 772 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 773 (void) snprintf(errstr, (2 * MAXERROR), gettext( 774 "Invalid serviceSearchDescriptor (%s). " 775 "Illegal configuration"), *sdl); 776 (void) __ns_ldap_freeParam(¶m); 777 param = NULL; 778 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX, 779 strdup(errstr), NULL); 780 return (rc); 781 } 782 if (ret != NULL) { 783 rc = __ns_ldap_saveSearchDesc( 784 &sdlist, &cnt, &max, ret); 785 } 786 if (rc < 0) { 787 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 788 (void) __ns_ldap_freeParam(¶m); 789 param = NULL; 790 return (NS_LDAP_MEMORY); 791 } 792 } 793 } 794 795 (void) __ns_ldap_freeParam(¶m); 796 param = NULL; 797 *desc = sdlist; 798 return (NS_LDAP_SUCCESS); 799 } 800 801 int 802 __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc) 803 { 804 ns_ldap_search_desc_t **dptr; 805 ns_ldap_search_desc_t *ptr; 806 807 if (*desc == NULL) 808 return (NS_LDAP_SUCCESS); 809 for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) { 810 __ns_ldap_freeASearchDesc(ptr); 811 } 812 free(*desc); 813 *desc = NULL; 814 815 return (NS_LDAP_SUCCESS); 816 } 817 818 819 820 821 /* 822 * Exported Attribute/Objectclass mapping functions. 823 */ 824 825 /* 826 * This function is not supported. 827 */ 828 /* ARGSUSED */ 829 int __ns_ldap_getAttributeMaps( 830 const char *service, 831 ns_ldap_attribute_map_t ***maps, 832 ns_ldap_error_t **errorp) 833 { 834 *maps = NULL; 835 return (NS_LDAP_OP_FAILED); 836 } 837 838 int 839 __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps) 840 { 841 ns_ldap_attribute_map_t **dptr; 842 ns_ldap_attribute_map_t *ptr; 843 char **cpp, *cp; 844 845 if (*maps == NULL) 846 return (NS_LDAP_SUCCESS); 847 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) { 848 if (ptr->origAttr) { 849 free(ptr->origAttr); 850 ptr->origAttr = NULL; 851 } 852 if (ptr->mappedAttr) { 853 for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++) 854 free(cp); 855 free(ptr->mappedAttr); 856 ptr->mappedAttr = NULL; 857 } 858 free(ptr); 859 } 860 free(*maps); 861 *maps = NULL; 862 863 return (NS_LDAP_SUCCESS); 864 } 865 866 char **__ns_ldap_getMappedAttributes( 867 const char *service, 868 const char *origAttribute) 869 { 870 ns_config_t *ptr = __s_api_loadrefresh_config(); 871 ns_hash_t *hp; 872 char **ret; 873 874 if (ptr == NULL) 875 return (NULL); 876 877 hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute); 878 879 if (hp == NULL || hp->h_map == NULL) 880 ret = NULL; 881 else 882 ret = __s_api_cp2dArray(hp->h_map->map); 883 __s_api_release_config(ptr); 884 return (ret); 885 } 886 887 char **__ns_ldap_getOrigAttribute( 888 const char *service, 889 const char *mappedAttribute) 890 { 891 ns_config_t *ptr = __s_api_loadrefresh_config(); 892 ns_hash_t *hp; 893 char **ret; 894 895 if (ptr == NULL) 896 return (NULL); 897 898 hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute); 899 900 if (hp == NULL || hp->h_map == NULL) 901 ret = NULL; 902 else 903 ret = __s_api_cp2dArray(hp->h_map->map); 904 __s_api_release_config(ptr); 905 return (ret); 906 } 907 908 /* 909 * This function is not supported. 910 */ 911 /* ARGSUSED */ 912 int __ns_ldap_getObjectClassMaps( 913 const char *service, 914 ns_ldap_objectclass_map_t ***maps, 915 ns_ldap_error_t **errorp) 916 { 917 *maps = NULL; 918 return (NS_LDAP_OP_FAILED); 919 } 920 921 int 922 __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps) 923 { 924 ns_ldap_objectclass_map_t **dptr; 925 ns_ldap_objectclass_map_t *ptr; 926 927 if (*maps == NULL) 928 return (NS_LDAP_SUCCESS); 929 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) { 930 if (ptr->origOC) { 931 free(ptr->origOC); 932 ptr->origOC = NULL; 933 } 934 if (ptr->mappedOC) { 935 free(ptr->mappedOC); 936 ptr->mappedOC = NULL; 937 } 938 free(ptr); 939 } 940 free(*maps); 941 *maps = NULL; 942 943 return (NS_LDAP_SUCCESS); 944 } 945 946 char **__ns_ldap_getMappedObjectClass( 947 const char *service, 948 const char *origObjectClass) 949 { 950 ns_config_t *ptr = __s_api_loadrefresh_config(); 951 ns_hash_t *hp; 952 char **ret; 953 954 if (ptr == NULL) 955 return (NULL); 956 957 hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass); 958 959 if (hp == NULL || hp->h_map == NULL) 960 ret = NULL; 961 else 962 ret = __s_api_cp2dArray(hp->h_map->map); 963 __s_api_release_config(ptr); 964 return (ret); 965 } 966 967 char **__ns_ldap_getOrigObjectClass( 968 const char *service, 969 const char *mappedObjectClass) 970 { 971 ns_config_t *ptr = __s_api_loadrefresh_config(); 972 ns_hash_t *hp; 973 char **ret; 974 975 if (ptr == NULL) 976 return (NULL); 977 978 hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass); 979 980 if (hp == NULL || hp->h_map == NULL) 981 ret = NULL; 982 else 983 ret = __s_api_cp2dArray(hp->h_map->map); 984 __s_api_release_config(ptr); 985 return (ret); 986 } 987 988 char **__ns_ldap_mapAttributeList( 989 const char *service, 990 const char * const *origAttrList) 991 { 992 const char * const *opp; 993 char **cpp, **npp; 994 int i; 995 996 if (origAttrList == NULL) 997 return (NULL); 998 999 opp = origAttrList; 1000 for (i = 0; *opp; i++, opp++) 1001 ; 1002 cpp = (char **)calloc(i+1, sizeof (char *)); 1003 if (cpp == NULL) 1004 return (NULL); 1005 1006 opp = origAttrList; 1007 for (i = 0; *opp; i++, opp++) { 1008 npp = __ns_ldap_getMappedAttributes(service, *opp); 1009 if (npp && npp[0]) { 1010 cpp[i] = strdup(npp[0]); 1011 __s_api_free2dArray(npp); 1012 npp = NULL; 1013 if (cpp[i] == NULL) { 1014 __s_api_free2dArray(cpp); 1015 return (NULL); 1016 } 1017 } else { 1018 cpp[i] = strdup(*opp); 1019 if (cpp[i] == NULL) { 1020 __s_api_free2dArray(cpp); 1021 return (NULL); 1022 } 1023 } 1024 } 1025 return (cpp); 1026 } 1027 1028 char * 1029 __ns_ldap_mapAttribute( 1030 const char *service, 1031 const char *origAttr) 1032 { 1033 char **npp; 1034 char *mappedAttr; 1035 1036 if (origAttr == NULL) 1037 return (NULL); 1038 1039 npp = __ns_ldap_getMappedAttributes(service, origAttr); 1040 if (npp && npp[0]) { 1041 mappedAttr = strdup(npp[0]); 1042 __s_api_free2dArray(npp); 1043 } else { 1044 mappedAttr = strdup(origAttr); 1045 } 1046 return (mappedAttr); 1047 } 1048