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 int i, rc; 332 ns_ldap_error_t **errorp = NULL; 333 ns_ldap_error_t *error = NULL; 334 void **paramVal = NULL; 335 char **dns = NULL; 336 _ns_parse_state_t state = P_INIT; 337 int quoted = 0; 338 int wasquoted = 0; 339 int empty = 1; 340 341 if (ret == NULL) 342 return (NS_LDAP_INVALID_PARAM); 343 *ret = NULL; 344 if (cur == NULL) 345 return (NS_LDAP_INVALID_PARAM); 346 347 ptr = (ns_ldap_search_desc_t *) 348 calloc(1, sizeof (ns_ldap_search_desc_t)); 349 if (ptr == NULL) 350 return (NS_LDAP_MEMORY); 351 352 sptr = *cur; 353 354 /* Get the default scope */ 355 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, 356 ¶mVal, errorp)) != NS_LDAP_SUCCESS) { 357 (void) __ns_ldap_freeError(errorp); 358 __ns_ldap_freeASearchDesc(ptr); 359 ptr = NULL; 360 return (NS_LDAP_MEMORY); 361 } 362 if (paramVal && *paramVal) 363 ptr->scope = * (ScopeType_t *)(*paramVal); 364 else 365 ptr->scope = NS_LDAP_SCOPE_ONELEVEL; 366 (void) __ns_ldap_freeParam(¶mVal); 367 paramVal = NULL; 368 369 for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) { 370 empty = 0; 371 switch (state) { 372 case P_INIT: 373 if (*sptr == QUESTTOK) { 374 /* No basedn */ 375 ptr->basedn = strdup(""); 376 if (!ptr->basedn) { 377 state = P_MEMERR; 378 break; 379 } 380 state = P_SCOPE; 381 break; 382 } 383 if (*sptr == SEMITOK) { 384 /* No SSD */ 385 ptr->basedn = strdup(""); 386 if (!ptr->basedn) { 387 state = P_MEMERR; 388 break; 389 } 390 state = P_EXIT; 391 break; 392 } 393 /* prepare to copy DN */ 394 i = strlen(sptr) + 1; 395 ptr->basedn = dptr = (char *)calloc(i, sizeof (char)); 396 if (!ptr->basedn) { 397 state = P_MEMERR; 398 break; 399 } 400 if (*sptr == BSLTOK) { 401 if (*(sptr+1) == '\0') { 402 /* error */ 403 state = P_ERROR; 404 break; 405 } 406 if (*(sptr+1) == QUOTETOK || 407 *(sptr+1) == BSLTOK) { 408 /* escaped CHARS */ 409 sptr++; 410 } else { 411 *dptr++ = *sptr++; 412 } 413 *dptr++ = *sptr; 414 } else if (*sptr == QUOTETOK) { 415 quoted = 1; 416 wasquoted = 1; 417 } else { 418 *dptr++ = *sptr; 419 } 420 state = P_BASEDN; 421 break; 422 case P_INIFILTER: 423 if (*sptr == SEMITOK) { 424 /* No filter and no more SSD */ 425 state = P_EXIT; 426 break; 427 } 428 /* prepare to copy DN */ 429 i = strlen(sptr) + 1; 430 ptr->filter = dptr = (char *)calloc(i, sizeof (char)); 431 if (!ptr->filter) { 432 state = P_MEMERR; 433 break; 434 } 435 if (*sptr == BSLTOK) { 436 if (*(sptr+1) == '\0') { 437 /* error */ 438 state = P_ERROR; 439 break; 440 } 441 if (*(sptr+1) == QUOTETOK || 442 *(sptr+1) == BSLTOK) { 443 /* escaped CHARS */ 444 sptr++; 445 } else { 446 *dptr++ = *sptr++; 447 } 448 *dptr++ = *sptr; 449 } else if (*sptr == QUOTETOK) { 450 quoted = 1; 451 wasquoted = 1; 452 } else { 453 *dptr++ = *sptr; 454 } 455 state = P_FILTER; 456 break; 457 case P_SCOPE: 458 if (*sptr == SEMITOK) { 459 /* no more SSD */ 460 state = P_EXIT; 461 break; 462 } 463 if (strncasecmp(sptr, "base", 4) == 0) { 464 sptr += 4; 465 ptr->scope = NS_LDAP_SCOPE_BASE; 466 } else if (strncasecmp(sptr, "one", 3) == 0) { 467 ptr->scope = NS_LDAP_SCOPE_ONELEVEL; 468 sptr += 3; 469 } else if (strncasecmp(sptr, "sub", 3) == 0) { 470 ptr->scope = NS_LDAP_SCOPE_SUBTREE; 471 sptr += 3; 472 } 473 if (*sptr == '\0' || (*sptr == SEMITOK)) { 474 /* no more SSD */ 475 state = P_EXIT; 476 sptr--; 477 break; 478 } 479 if (*sptr != QUESTTOK) { 480 state = P_ERROR; 481 break; 482 } 483 state = P_INIFILTER; 484 quoted = 0; 485 wasquoted = 0; 486 break; 487 case P_BASEDN: 488 case P_FILTER: 489 if (quoted) { 490 /* Quoted */ 491 if (*sptr == BSLTOK) { 492 if (*(sptr+1) == '\0') { 493 state = P_ERROR; 494 break; 495 } 496 if (*(sptr+1) == QUOTETOK || 497 *(sptr+1) == BSLTOK) { 498 /* escaped CHARS */ 499 sptr++; 500 } else { 501 *dptr++ = *sptr++; 502 } 503 /* fall through to char copy */ 504 } else if (*sptr == QUOTETOK) { 505 /* end of string */ 506 *dptr = '\0'; 507 quoted = 0; 508 break; 509 } 510 /* else fall through to char copy */ 511 } else { 512 /* Unquoted */ 513 if (wasquoted && *sptr != QUESTTOK) { 514 /* error past end of quoted string */ 515 state = P_ERROR; 516 break; 517 } 518 if (*sptr == BSLTOK) { 519 if (*(sptr+1) == '\0') { 520 state = P_ERROR; 521 break; 522 } 523 if (*(sptr+1) == SEMITOK || 524 *(sptr+1) == QUESTTOK || 525 *(sptr+1) == QUOTETOK || 526 *(sptr+1) == BSLTOK) { 527 /* escaped chars */ 528 sptr++; 529 } 530 /* fall through to char copy */ 531 } else if (*sptr == QUOTETOK) { 532 /* error */ 533 state = P_ERROR; 534 break; 535 } else if (*sptr == QUESTTOK) { 536 /* if filter error */ 537 if (state == P_FILTER) { 538 state = P_ERROR; 539 break; 540 } 541 /* end of basedn goto scope */ 542 *dptr = '\0'; 543 state = P_SCOPE; 544 break; 545 } else if (*sptr == SEMITOK) { 546 /* end of current SSD */ 547 *dptr = '\0'; 548 state = P_EXIT; 549 break; 550 } 551 } 552 /* normal character to copy */ 553 *dptr++ = *sptr; 554 break; 555 case P_END: 556 if (*sptr == SEMITOK) { 557 state = P_EXIT; 558 break; 559 } 560 __ns_ldap_freeASearchDesc(ptr); 561 ptr = NULL; 562 *cur = NULL; 563 return (NS_LDAP_CONFIG); 564 default: /* error should never arrive here */ 565 case P_ERROR: 566 __ns_ldap_freeASearchDesc(ptr); 567 ptr = NULL; 568 *cur = NULL; 569 return (NS_LDAP_CONFIG); 570 case P_MEMERR: 571 __ns_ldap_freeASearchDesc(ptr); 572 ptr = NULL; 573 *cur = NULL; 574 return (NS_LDAP_MEMORY); 575 } 576 } 577 578 if (quoted) { 579 __ns_ldap_freeASearchDesc(ptr); 580 ptr = NULL; 581 *cur = NULL; 582 return (NS_LDAP_INVALID_PARAM); 583 } 584 585 if (empty || strlen(ptr->basedn) == 0) { 586 if (ptr->basedn) 587 free(ptr->basedn); 588 /* get default base */ 589 rc = __s_api_getDNs(&dns, service, &error); 590 if (rc != NS_LDAP_SUCCESS) { 591 if (dns) { 592 __s_api_free2dArray(dns); 593 dns = NULL; 594 } 595 (void) __ns_ldap_freeError(&error); 596 __ns_ldap_freeASearchDesc(ptr); 597 ptr = NULL; 598 return (NS_LDAP_MEMORY); 599 } 600 ptr->basedn = strdup(dns[0]); 601 __s_api_free2dArray(dns); 602 dns = NULL; 603 } 604 605 *cur = sptr; 606 *ret = ptr; 607 return (NS_LDAP_SUCCESS); 608 } 609 610 611 /* 612 * Build up the service descriptor array 613 */ 614 #define NS_SDESC_MAX 4 615 616 static int 617 __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist, 618 int *cnt, int *max, ns_ldap_search_desc_t *ret) 619 { 620 ns_ldap_search_desc_t **tmplist; 621 622 if (*sdlist == NULL) { 623 *cnt = 0; 624 *max = NS_SDESC_MAX; 625 *sdlist = (ns_ldap_search_desc_t **) 626 calloc(*max, sizeof (ns_ldap_search_desc_t *)); 627 if (*sdlist == NULL) 628 return (-1); 629 } else if (*cnt+1 >= *max) { 630 *max += NS_SDESC_MAX; 631 tmplist = (ns_ldap_search_desc_t **) 632 realloc((void *)(*sdlist), 633 *max * sizeof (ns_ldap_search_desc_t *)); 634 if (tmplist == NULL) 635 return (-1); 636 else 637 *sdlist = tmplist; 638 } 639 (*sdlist)[*cnt] = ret; 640 (*cnt)++; 641 (*sdlist)[*cnt] = NULL; 642 return (0); 643 } 644 645 646 /* 647 * Exported Search Descriptor Routines 648 */ 649 650 int __ns_ldap_getSearchDescriptors( 651 const char *service, 652 ns_ldap_search_desc_t ***desc, 653 ns_ldap_error_t **errorp) 654 { 655 int rc; 656 int slen; 657 void **param = NULL; 658 void **paramVal = NULL; 659 char **sdl, *srv, **sdl_save; 660 char errstr[2 * MAXERROR]; 661 ns_ldap_search_desc_t **sdlist; 662 int cnt, max; 663 int vers; 664 ns_config_t *cfg; 665 ns_ldap_search_desc_t *ret; 666 667 if ((desc == NULL) || (errorp == NULL)) 668 return (NS_LDAP_INVALID_PARAM); 669 670 *desc = NULL; 671 *errorp = NULL; 672 673 rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P, 674 (void ***)¶m, errorp); 675 if (rc != NS_LDAP_SUCCESS) { 676 return (rc); 677 } 678 sdl = (char **)param; 679 cnt = 0; 680 max = 0; 681 sdlist = NULL; 682 683 cfg = __s_api_get_default_config(); 684 685 if (cfg == NULL) { 686 (void) snprintf(errstr, sizeof (errstr), 687 gettext("No configuration information available.")); 688 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 689 NS_LDAP_MEMORY); 690 return (NS_LDAP_CONFIG); 691 } 692 693 vers = cfg->version; 694 __s_api_release_config(cfg); 695 696 /* If using version1 or no sd's process SEARCH_DN if available */ 697 if (vers == NS_LDAP_V1 && param == NULL) { 698 rc = __s_api_get_search_DNs_v1(&sdl, service, errorp); 699 if (rc != NS_LDAP_SUCCESS || sdl == NULL) { 700 return (rc); 701 } 702 sdl_save = sdl; 703 /* Convert a SEARCH_DN to a search descriptor */ 704 for (; *sdl; sdl++) { 705 ret = (ns_ldap_search_desc_t *) 706 calloc(1, sizeof (ns_ldap_search_desc_t)); 707 if (ret == NULL) { 708 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 709 __s_api_free2dArray(sdl_save); 710 return (NS_LDAP_MEMORY); 711 } 712 ret->basedn = strdup(*sdl); 713 if (ret->basedn == NULL) { 714 free(ret); 715 (void) __ns_ldap_freeASearchDesc(ret); 716 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 717 __s_api_free2dArray(sdl_save); 718 return (NS_LDAP_MEMORY); 719 } 720 721 /* default scope */ 722 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P, 723 ¶mVal, errorp)) != NS_LDAP_SUCCESS) { 724 (void) __ns_ldap_freeASearchDesc(ret); 725 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 726 __s_api_free2dArray(sdl_save); 727 return (rc); 728 } 729 if (paramVal && *paramVal) 730 ret->scope = * (ScopeType_t *)(*paramVal); 731 else 732 ret->scope = NS_LDAP_SCOPE_ONELEVEL; 733 (void) __ns_ldap_freeParam(¶mVal); 734 paramVal = NULL; 735 736 rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret); 737 if (rc < 0) { 738 (void) __ns_ldap_freeASearchDesc(ret); 739 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 740 __s_api_free2dArray(sdl_save); 741 return (NS_LDAP_MEMORY); 742 } 743 } 744 __s_api_free2dArray(sdl_save); 745 *desc = sdlist; 746 return (NS_LDAP_SUCCESS); 747 } 748 749 if (sdl == NULL || service == NULL) { 750 (void) __ns_ldap_freeParam(¶m); 751 param = NULL; 752 *desc = NULL; 753 return (NS_LDAP_SUCCESS); 754 } 755 slen = strlen(service); 756 757 /* Process the version2 sd's */ 758 for (; *sdl; sdl++) { 759 srv = *sdl; 760 if (strncasecmp(service, srv, slen) != 0) 761 continue; 762 srv += slen; 763 if (*srv != COLONTOK) 764 continue; 765 srv++; 766 while (srv != NULL && *srv != '\0') { 767 /* Process 1 */ 768 rc = __s_api_parseASearchDesc(service, &srv, &ret); 769 if (rc != NS_LDAP_SUCCESS) { 770 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 771 (void) snprintf(errstr, (2 * MAXERROR), gettext( 772 "Invalid serviceSearchDescriptor (%s). " 773 "Illegal configuration"), *sdl); 774 (void) __ns_ldap_freeParam(¶m); 775 param = NULL; 776 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX, 777 strdup(errstr), NS_LDAP_MEMORY); 778 return (rc); 779 } 780 if (ret != NULL) { 781 rc = __ns_ldap_saveSearchDesc( 782 &sdlist, &cnt, &max, ret); 783 } 784 if (rc < 0) { 785 (void) __ns_ldap_freeSearchDescriptors(&sdlist); 786 (void) __ns_ldap_freeParam(¶m); 787 param = NULL; 788 return (NS_LDAP_MEMORY); 789 } 790 } 791 } 792 793 (void) __ns_ldap_freeParam(¶m); 794 param = NULL; 795 *desc = sdlist; 796 return (NS_LDAP_SUCCESS); 797 } 798 799 int 800 __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc) 801 { 802 ns_ldap_search_desc_t **dptr; 803 ns_ldap_search_desc_t *ptr; 804 805 if (*desc == NULL) 806 return (NS_LDAP_SUCCESS); 807 for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) { 808 __ns_ldap_freeASearchDesc(ptr); 809 } 810 free(*desc); 811 *desc = NULL; 812 813 return (NS_LDAP_SUCCESS); 814 } 815 816 817 818 819 /* 820 * Exported Attribute/Objectclass mapping functions. 821 */ 822 823 /* 824 * This function is not supported. 825 */ 826 /* ARGSUSED */ 827 int __ns_ldap_getAttributeMaps( 828 const char *service, 829 ns_ldap_attribute_map_t ***maps, 830 ns_ldap_error_t **errorp) 831 { 832 *maps = NULL; 833 return (NS_LDAP_OP_FAILED); 834 } 835 836 int 837 __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps) 838 { 839 ns_ldap_attribute_map_t **dptr; 840 ns_ldap_attribute_map_t *ptr; 841 char **cpp, *cp; 842 843 if (*maps == NULL) 844 return (NS_LDAP_SUCCESS); 845 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) { 846 if (ptr->origAttr) { 847 free(ptr->origAttr); 848 ptr->origAttr = NULL; 849 } 850 if (ptr->mappedAttr) { 851 for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++) 852 free(cp); 853 free(ptr->mappedAttr); 854 ptr->mappedAttr = NULL; 855 } 856 free(ptr); 857 } 858 free(*maps); 859 *maps = NULL; 860 861 return (NS_LDAP_SUCCESS); 862 } 863 864 char **__ns_ldap_getMappedAttributes( 865 const char *service, 866 const char *origAttribute) 867 { 868 ns_config_t *ptr = __s_api_loadrefresh_config(); 869 ns_hash_t *hp; 870 char **ret; 871 872 if (ptr == NULL) 873 return (NULL); 874 875 hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute); 876 877 if (hp == NULL || hp->h_map == NULL) 878 ret = NULL; 879 else 880 ret = __s_api_cp2dArray(hp->h_map->map); 881 __s_api_release_config(ptr); 882 return (ret); 883 } 884 885 char **__ns_ldap_getOrigAttribute( 886 const char *service, 887 const char *mappedAttribute) 888 { 889 ns_config_t *ptr = __s_api_loadrefresh_config(); 890 ns_hash_t *hp; 891 char **ret; 892 893 if (ptr == NULL) 894 return (NULL); 895 896 hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute); 897 898 if (hp == NULL || hp->h_map == NULL) 899 ret = NULL; 900 else 901 ret = __s_api_cp2dArray(hp->h_map->map); 902 __s_api_release_config(ptr); 903 return (ret); 904 } 905 906 /* 907 * This function is not supported. 908 */ 909 /* ARGSUSED */ 910 int __ns_ldap_getObjectClassMaps( 911 const char *service, 912 ns_ldap_objectclass_map_t ***maps, 913 ns_ldap_error_t **errorp) 914 { 915 *maps = NULL; 916 return (NS_LDAP_OP_FAILED); 917 } 918 919 int 920 __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps) 921 { 922 ns_ldap_objectclass_map_t **dptr; 923 ns_ldap_objectclass_map_t *ptr; 924 925 if (*maps == NULL) 926 return (NS_LDAP_SUCCESS); 927 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) { 928 if (ptr->origOC) { 929 free(ptr->origOC); 930 ptr->origOC = NULL; 931 } 932 if (ptr->mappedOC) { 933 free(ptr->mappedOC); 934 ptr->mappedOC = NULL; 935 } 936 free(ptr); 937 } 938 free(*maps); 939 *maps = NULL; 940 941 return (NS_LDAP_SUCCESS); 942 } 943 944 char **__ns_ldap_getMappedObjectClass( 945 const char *service, 946 const char *origObjectClass) 947 { 948 ns_config_t *ptr = __s_api_loadrefresh_config(); 949 ns_hash_t *hp; 950 char **ret; 951 952 if (ptr == NULL) 953 return (NULL); 954 955 hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass); 956 957 if (hp == NULL || hp->h_map == NULL) 958 ret = NULL; 959 else 960 ret = __s_api_cp2dArray(hp->h_map->map); 961 __s_api_release_config(ptr); 962 return (ret); 963 } 964 965 char **__ns_ldap_getOrigObjectClass( 966 const char *service, 967 const char *mappedObjectClass) 968 { 969 ns_config_t *ptr = __s_api_loadrefresh_config(); 970 ns_hash_t *hp; 971 char **ret; 972 973 if (ptr == NULL) 974 return (NULL); 975 976 hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass); 977 978 if (hp == NULL || hp->h_map == NULL) 979 ret = NULL; 980 else 981 ret = __s_api_cp2dArray(hp->h_map->map); 982 __s_api_release_config(ptr); 983 return (ret); 984 } 985 986 char **__ns_ldap_mapAttributeList( 987 const char *service, 988 const char * const *origAttrList) 989 { 990 const char * const *opp; 991 char **cpp, **npp; 992 int i; 993 994 if (origAttrList == NULL) 995 return (NULL); 996 997 opp = origAttrList; 998 for (i = 0; *opp; i++, opp++) 999 ; 1000 cpp = (char **)calloc(i+1, sizeof (char *)); 1001 if (cpp == NULL) 1002 return (NULL); 1003 1004 opp = origAttrList; 1005 for (i = 0; *opp; i++, opp++) { 1006 npp = __ns_ldap_getMappedAttributes(service, *opp); 1007 if (npp && npp[0]) { 1008 cpp[i] = strdup(npp[0]); 1009 __s_api_free2dArray(npp); 1010 npp = NULL; 1011 if (cpp[i] == NULL) { 1012 __s_api_free2dArray(cpp); 1013 return (NULL); 1014 } 1015 } else { 1016 cpp[i] = strdup(*opp); 1017 if (cpp[i] == NULL) { 1018 __s_api_free2dArray(cpp); 1019 return (NULL); 1020 } 1021 } 1022 } 1023 return (cpp); 1024 } 1025 1026 char * 1027 __ns_ldap_mapAttribute( 1028 const char *service, 1029 const char *origAttr) 1030 { 1031 char **npp; 1032 char *mappedAttr; 1033 1034 if (origAttr == NULL) 1035 return (NULL); 1036 1037 npp = __ns_ldap_getMappedAttributes(service, origAttr); 1038 if (npp && npp[0]) { 1039 mappedAttr = strdup(npp[0]); 1040 __s_api_free2dArray(npp); 1041 } else { 1042 mappedAttr = strdup(origAttr); 1043 } 1044 return (mappedAttr); 1045 } 1046