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