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