Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / libsldap / common / ns_mapping.c
blobbb0846c24696dafa8021dd799b6b6e5d9af92a8e
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
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"
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
38 static unsigned long
39 ns_hash(const char *str)
41 unsigned int hval = 0;
43 while (*str) {
44 unsigned int g;
46 hval = (hval << 4) + tolower(*str++);
47 if ((g = (hval & 0xf0000000)) != 0)
48 hval ^= g >> 24;
49 hval &= ~g;
51 return ((unsigned long)hval);
55 * Scan a hash table hit for a matching hash entry.
56 * Assume service and str are non-NULL.
59 static ns_hash_t *
60 ns_scan_hash(ns_hashtype_t type, const char *service,
61 const char *str, ns_hash_t *idx)
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);
69 idx = idx->h_next;
71 return ((ns_hash_t *)NULL);
75 * Find an entry in the hash table
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)
82 ns_hash_t *idx, *hashp;
83 unsigned long hash;
85 if (config == NULL || service == NULL || str == NULL)
86 return (NULL);
88 hash = ns_hash(str) % NS_HASH_MAX;
89 idx = config->hashTbl[hash];
90 hashp = ns_scan_hash(type, service, str, idx);
92 return (hashp);
96 * free a map entry
99 static void
100 ns_free_map(ns_mapping_t *mapp)
102 char **ptr;
104 if (mapp == NULL)
105 return;
106 if (mapp->service) {
107 free(mapp->service);
108 mapp->service = NULL;
110 if (mapp->orig) {
111 free(mapp->orig);
112 mapp->orig = NULL;
114 if (mapp->map) {
115 for (ptr = mapp->map; *ptr; ptr++)
116 free(*ptr);
117 free(mapp->map);
118 mapp->map = NULL;
120 free(mapp);
124 * Remove a hash table entry.
125 * This function is not MT safe.
128 static ns_hash_t *
129 ns_free_hash(ns_hash_t *p)
131 ns_mapping_t *map;
132 ns_hash_t *next;
134 map = p->h_map;
135 next = p->h_next;
136 ns_free_map(map);
137 free(p);
138 return (next);
142 * destroy the hash table.
143 * This function is not MT safe.
146 void
147 __s_api_destroy_hash(ns_config_t *config)
149 ns_hash_t *next;
150 int i;
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);
159 config->hashTbl[i] = NULL;
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.
170 __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type,
171 ns_mapping_t *map)
173 ns_hash_t *idx, *newp;
174 unsigned long hash;
176 if (config == NULL)
177 return (NS_HASH_RC_CONFIG_ERROR);
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);
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);
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
211 * objectclassMap syntax:
212 * objectclassMap = serviceId ":" origObjectclass "="
213 * objectclass
214 * origObjectclass = objectclass
215 * objectclass = keystring
219 __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA)
221 char *sptr, *dptr, **mapp;
222 int i, max;
224 *sid = NULL;
225 *origA = NULL;
226 *mapA = NULL;
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;
239 dptr = strchr(sptr, TOKENSEPARATOR);
240 if (dptr == NULL) {
241 free(*sid);
242 *sid = NULL;
243 return (NS_HASH_RC_SYNTAX_ERROR);
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);
252 (void) strlcpy(*origA, sptr, i);
253 sptr = dptr+1;
255 max = 1;
256 for (dptr = sptr; *dptr; dptr++) {
257 if (*dptr == SPACETOK) {
258 max++;
259 while (*(dptr+1) == SPACETOK)
260 dptr++;
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);
271 mapp = *mapA;
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);
290 (void) strlcpy(*mapp, sptr, i);
291 mapp++;
292 sptr = dptr;
294 return (NS_HASH_RC_SUCCESS);
298 static void
299 __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr)
301 if (ptr == NULL)
302 return;
303 free(ptr->basedn);
304 free(ptr->filter);
305 free(ptr);
309 * Parse a service descriptor
310 * and create a service descriptor struct
311 * SD Format:
312 * serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]]
313 * desc format:
314 * [base][?[scope][?[filter]]]
317 typedef enum _ns_parse_state {
318 P_ERROR, P_INIT, P_BASEDN, P_SCOPE,
319 P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR
320 } _ns_parse_state_t;
322 static
324 __s_api_parseASearchDesc(const char *service,
325 char **cur, ns_ldap_search_desc_t **ret)
327 ns_ldap_search_desc_t *ptr;
328 char *sptr, *dptr;
329 int i, rc;
330 ns_ldap_error_t **errorp = NULL;
331 ns_ldap_error_t *error = NULL;
332 void **paramVal = NULL;
333 char **dns = NULL;
334 _ns_parse_state_t state = P_INIT;
335 int quoted = 0;
336 int wasquoted = 0;
337 int empty = 1;
339 if (ret == NULL)
340 return (NS_LDAP_INVALID_PARAM);
341 *ret = NULL;
342 if (cur == NULL)
343 return (NS_LDAP_INVALID_PARAM);
345 ptr = (ns_ldap_search_desc_t *)
346 calloc(1, sizeof (ns_ldap_search_desc_t));
347 if (ptr == NULL)
348 return (NS_LDAP_MEMORY);
350 sptr = *cur;
352 /* Get the default scope */
353 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
354 &paramVal, errorp)) != NS_LDAP_SUCCESS) {
355 (void) __ns_ldap_freeError(errorp);
356 __ns_ldap_freeASearchDesc(ptr);
357 ptr = NULL;
358 return (NS_LDAP_MEMORY);
360 if (paramVal && *paramVal)
361 ptr->scope = * (ScopeType_t *)(*paramVal);
362 else
363 ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
364 (void) __ns_ldap_freeParam(&paramVal);
365 paramVal = NULL;
367 for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) {
368 empty = 0;
369 switch (state) {
370 case P_INIT:
371 if (*sptr == QUESTTOK) {
372 /* No basedn */
373 ptr->basedn = strdup("");
374 if (!ptr->basedn) {
375 state = P_MEMERR;
376 break;
378 state = P_SCOPE;
379 break;
381 if (*sptr == SEMITOK) {
382 /* No SSD */
383 ptr->basedn = strdup("");
384 if (!ptr->basedn) {
385 state = P_MEMERR;
386 break;
388 state = P_EXIT;
389 break;
391 /* prepare to copy DN */
392 i = strlen(sptr) + 1;
393 ptr->basedn = dptr = (char *)calloc(i, sizeof (char));
394 if (!ptr->basedn) {
395 state = P_MEMERR;
396 break;
398 if (*sptr == BSLTOK) {
399 if (*(sptr+1) == '\0') {
400 /* error */
401 state = P_ERROR;
402 break;
404 if (*(sptr+1) == QUOTETOK ||
405 *(sptr+1) == BSLTOK) {
406 /* escaped CHARS */
407 sptr++;
408 } else {
409 *dptr++ = *sptr++;
411 *dptr++ = *sptr;
412 } else if (*sptr == QUOTETOK) {
413 quoted = 1;
414 wasquoted = 1;
415 } else {
416 *dptr++ = *sptr;
418 state = P_BASEDN;
419 break;
420 case P_INIFILTER:
421 if (*sptr == SEMITOK) {
422 /* No filter and no more SSD */
423 state = P_EXIT;
424 break;
426 /* prepare to copy DN */
427 i = strlen(sptr) + 1;
428 ptr->filter = dptr = (char *)calloc(i, sizeof (char));
429 if (!ptr->filter) {
430 state = P_MEMERR;
431 break;
433 if (*sptr == BSLTOK) {
434 if (*(sptr+1) == '\0') {
435 /* error */
436 state = P_ERROR;
437 break;
439 if (*(sptr+1) == QUOTETOK ||
440 *(sptr+1) == BSLTOK) {
441 /* escaped CHARS */
442 sptr++;
443 } else {
444 *dptr++ = *sptr++;
446 *dptr++ = *sptr;
447 } else if (*sptr == QUOTETOK) {
448 quoted = 1;
449 wasquoted = 1;
450 } else {
451 *dptr++ = *sptr;
453 state = P_FILTER;
454 break;
455 case P_SCOPE:
456 if (*sptr == SEMITOK) {
457 /* no more SSD */
458 state = P_EXIT;
459 break;
461 if (strncasecmp(sptr, "base", 4) == 0) {
462 sptr += 4;
463 ptr->scope = NS_LDAP_SCOPE_BASE;
464 } else if (strncasecmp(sptr, "one", 3) == 0) {
465 ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
466 sptr += 3;
467 } else if (strncasecmp(sptr, "sub", 3) == 0) {
468 ptr->scope = NS_LDAP_SCOPE_SUBTREE;
469 sptr += 3;
471 if (*sptr == '\0' || (*sptr == SEMITOK)) {
472 /* no more SSD */
473 state = P_EXIT;
474 sptr--;
475 break;
477 if (*sptr != QUESTTOK) {
478 state = P_ERROR;
479 break;
481 state = P_INIFILTER;
482 quoted = 0;
483 wasquoted = 0;
484 break;
485 case P_BASEDN:
486 case P_FILTER:
487 if (quoted) {
488 /* Quoted */
489 if (*sptr == BSLTOK) {
490 if (*(sptr+1) == '\0') {
491 state = P_ERROR;
492 break;
494 if (*(sptr+1) == QUOTETOK ||
495 *(sptr+1) == BSLTOK) {
496 /* escaped CHARS */
497 sptr++;
498 } else {
499 *dptr++ = *sptr++;
501 /* fall through to char copy */
502 } else if (*sptr == QUOTETOK) {
503 /* end of string */
504 *dptr = '\0';
505 quoted = 0;
506 break;
508 /* else fall through to char copy */
509 } else {
510 /* Unquoted */
511 if (wasquoted && *sptr != QUESTTOK) {
512 /* error past end of quoted string */
513 state = P_ERROR;
514 break;
516 if (*sptr == BSLTOK) {
517 if (*(sptr+1) == '\0') {
518 state = P_ERROR;
519 break;
521 if (*(sptr+1) == SEMITOK ||
522 *(sptr+1) == QUESTTOK ||
523 *(sptr+1) == QUOTETOK ||
524 *(sptr+1) == BSLTOK) {
525 /* escaped chars */
526 sptr++;
528 /* fall through to char copy */
529 } else if (*sptr == QUOTETOK) {
530 /* error */
531 state = P_ERROR;
532 break;
533 } else if (*sptr == QUESTTOK) {
534 /* if filter error */
535 if (state == P_FILTER) {
536 state = P_ERROR;
537 break;
539 /* end of basedn goto scope */
540 *dptr = '\0';
541 state = P_SCOPE;
542 break;
543 } else if (*sptr == SEMITOK) {
544 /* end of current SSD */
545 *dptr = '\0';
546 state = P_EXIT;
547 break;
550 /* normal character to copy */
551 *dptr++ = *sptr;
552 break;
553 case P_END:
554 if (*sptr == SEMITOK) {
555 state = P_EXIT;
556 break;
558 __ns_ldap_freeASearchDesc(ptr);
559 ptr = NULL;
560 *cur = NULL;
561 return (NS_LDAP_CONFIG);
562 default: /* error should never arrive here */
563 case P_ERROR:
564 __ns_ldap_freeASearchDesc(ptr);
565 ptr = NULL;
566 *cur = NULL;
567 return (NS_LDAP_CONFIG);
568 case P_MEMERR:
569 __ns_ldap_freeASearchDesc(ptr);
570 ptr = NULL;
571 *cur = NULL;
572 return (NS_LDAP_MEMORY);
576 if (quoted) {
577 __ns_ldap_freeASearchDesc(ptr);
578 ptr = NULL;
579 *cur = NULL;
580 return (NS_LDAP_INVALID_PARAM);
583 if (empty || strlen(ptr->basedn) == 0) {
584 free(ptr->basedn);
585 /* get default base */
586 rc = __s_api_getDNs(&dns, service, &error);
587 if (rc != NS_LDAP_SUCCESS) {
588 if (dns) {
589 __s_api_free2dArray(dns);
590 dns = NULL;
592 (void) __ns_ldap_freeError(&error);
593 __ns_ldap_freeASearchDesc(ptr);
594 ptr = NULL;
595 return (NS_LDAP_MEMORY);
597 ptr->basedn = strdup(dns[0]);
598 __s_api_free2dArray(dns);
599 dns = NULL;
602 *cur = sptr;
603 *ret = ptr;
604 return (NS_LDAP_SUCCESS);
609 * Build up the service descriptor array
611 #define NS_SDESC_MAX 4
613 static int
614 __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
615 int *cnt, int *max, ns_ldap_search_desc_t *ret)
617 ns_ldap_search_desc_t **tmplist;
619 if (*sdlist == NULL) {
620 *cnt = 0;
621 *max = NS_SDESC_MAX;
622 *sdlist = (ns_ldap_search_desc_t **)
623 calloc(*max, sizeof (ns_ldap_search_desc_t *));
624 if (*sdlist == NULL)
625 return (-1);
626 } else if (*cnt+1 >= *max) {
627 *max += NS_SDESC_MAX;
628 tmplist = (ns_ldap_search_desc_t **)
629 reallocarray(*sdlist, *max,
630 sizeof (ns_ldap_search_desc_t *));
631 if (tmplist == NULL)
632 return (-1);
633 else
634 *sdlist = tmplist;
636 (*sdlist)[*cnt] = ret;
637 (*cnt)++;
638 (*sdlist)[*cnt] = NULL;
639 return (0);
644 * Exported Search Descriptor Routines
647 int __ns_ldap_getSearchDescriptors(
648 const char *service,
649 ns_ldap_search_desc_t ***desc,
650 ns_ldap_error_t **errorp)
652 int rc;
653 int slen;
654 void **param = NULL;
655 void **paramVal = NULL;
656 char **sdl, *srv, **sdl_save;
657 char errstr[2 * MAXERROR];
658 ns_ldap_search_desc_t **sdlist;
659 int cnt, max;
660 int vers;
661 ns_config_t *cfg;
662 ns_ldap_search_desc_t *ret;
664 if ((desc == NULL) || (errorp == NULL))
665 return (NS_LDAP_INVALID_PARAM);
667 *desc = NULL;
668 *errorp = NULL;
670 rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
671 (void ***)&param, errorp);
672 if (rc != NS_LDAP_SUCCESS) {
673 return (rc);
675 sdl = (char **)param;
676 cnt = 0;
677 max = 0;
678 sdlist = NULL;
680 cfg = __s_api_get_default_config();
682 if (cfg == NULL) {
683 (void) snprintf(errstr, sizeof (errstr),
684 gettext("No configuration information available."));
685 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
687 return (NS_LDAP_CONFIG);
690 vers = cfg->version;
691 __s_api_release_config(cfg);
693 /* If using version1 or no sd's process SEARCH_DN if available */
694 if (vers == NS_LDAP_V1 && param == NULL) {
695 rc = __s_api_get_search_DNs_v1(&sdl, service, errorp);
696 if (rc != NS_LDAP_SUCCESS || sdl == NULL) {
697 return (rc);
699 sdl_save = sdl;
700 /* Convert a SEARCH_DN to a search descriptor */
701 for (; *sdl; sdl++) {
702 ret = (ns_ldap_search_desc_t *)
703 calloc(1, sizeof (ns_ldap_search_desc_t));
704 if (ret == NULL) {
705 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
706 __s_api_free2dArray(sdl_save);
707 return (NS_LDAP_MEMORY);
709 ret->basedn = strdup(*sdl);
710 if (ret->basedn == NULL) {
711 free(ret);
712 (void) __ns_ldap_freeASearchDesc(ret);
713 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
714 __s_api_free2dArray(sdl_save);
715 return (NS_LDAP_MEMORY);
718 /* default scope */
719 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
720 &paramVal, errorp)) != NS_LDAP_SUCCESS) {
721 (void) __ns_ldap_freeASearchDesc(ret);
722 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
723 __s_api_free2dArray(sdl_save);
724 return (rc);
726 if (paramVal && *paramVal)
727 ret->scope = * (ScopeType_t *)(*paramVal);
728 else
729 ret->scope = NS_LDAP_SCOPE_ONELEVEL;
730 (void) __ns_ldap_freeParam(&paramVal);
731 paramVal = NULL;
733 rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret);
734 if (rc < 0) {
735 (void) __ns_ldap_freeASearchDesc(ret);
736 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
737 __s_api_free2dArray(sdl_save);
738 return (NS_LDAP_MEMORY);
741 __s_api_free2dArray(sdl_save);
742 *desc = sdlist;
743 return (NS_LDAP_SUCCESS);
746 if (sdl == NULL || service == NULL) {
747 (void) __ns_ldap_freeParam(&param);
748 param = NULL;
749 *desc = NULL;
750 return (NS_LDAP_SUCCESS);
752 slen = strlen(service);
754 /* Process the version2 sd's */
755 for (; *sdl; sdl++) {
756 srv = *sdl;
757 if (strncasecmp(service, srv, slen) != 0)
758 continue;
759 srv += slen;
760 if (*srv != COLONTOK)
761 continue;
762 srv++;
763 while (srv != NULL && *srv != '\0') {
764 /* Process 1 */
765 rc = __s_api_parseASearchDesc(service, &srv, &ret);
766 if (rc != NS_LDAP_SUCCESS) {
767 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
768 (void) snprintf(errstr, (2 * MAXERROR), gettext(
769 "Invalid serviceSearchDescriptor (%s). "
770 "Illegal configuration"), *sdl);
771 (void) __ns_ldap_freeParam(&param);
772 param = NULL;
773 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
774 strdup(errstr), 0);
775 return (rc);
777 if (ret != NULL) {
778 rc = __ns_ldap_saveSearchDesc(
779 &sdlist, &cnt, &max, ret);
781 if (rc < 0) {
782 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
783 (void) __ns_ldap_freeParam(&param);
784 param = NULL;
785 return (NS_LDAP_MEMORY);
790 (void) __ns_ldap_freeParam(&param);
791 param = NULL;
792 *desc = sdlist;
793 return (NS_LDAP_SUCCESS);
797 __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc)
799 ns_ldap_search_desc_t **dptr;
800 ns_ldap_search_desc_t *ptr;
802 if (*desc == NULL)
803 return (NS_LDAP_SUCCESS);
804 for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) {
805 __ns_ldap_freeASearchDesc(ptr);
807 free(*desc);
808 *desc = NULL;
810 return (NS_LDAP_SUCCESS);
817 * Exported Attribute/Objectclass mapping functions.
821 * This function is not supported.
823 /* ARGSUSED */
824 int __ns_ldap_getAttributeMaps(
825 const char *service,
826 ns_ldap_attribute_map_t ***maps,
827 ns_ldap_error_t **errorp)
829 *maps = NULL;
830 return (NS_LDAP_OP_FAILED);
834 __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps)
836 ns_ldap_attribute_map_t **dptr;
837 ns_ldap_attribute_map_t *ptr;
838 char **cpp, *cp;
840 if (*maps == NULL)
841 return (NS_LDAP_SUCCESS);
842 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
843 if (ptr->origAttr) {
844 free(ptr->origAttr);
845 ptr->origAttr = NULL;
847 if (ptr->mappedAttr) {
848 for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++)
849 free(cp);
850 free(ptr->mappedAttr);
851 ptr->mappedAttr = NULL;
853 free(ptr);
855 free(*maps);
856 *maps = NULL;
858 return (NS_LDAP_SUCCESS);
861 char **__ns_ldap_getMappedAttributes(
862 const char *service,
863 const char *origAttribute)
865 ns_config_t *ptr = __s_api_loadrefresh_config();
866 ns_hash_t *hp;
867 char **ret;
869 if (ptr == NULL)
870 return (NULL);
872 hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute);
874 if (hp == NULL || hp->h_map == NULL)
875 ret = NULL;
876 else
877 ret = __s_api_cp2dArray(hp->h_map->map);
878 __s_api_release_config(ptr);
879 return (ret);
882 char **__ns_ldap_getOrigAttribute(
883 const char *service,
884 const char *mappedAttribute)
886 ns_config_t *ptr = __s_api_loadrefresh_config();
887 ns_hash_t *hp;
888 char **ret;
890 if (ptr == NULL)
891 return (NULL);
893 hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute);
895 if (hp == NULL || hp->h_map == NULL)
896 ret = NULL;
897 else
898 ret = __s_api_cp2dArray(hp->h_map->map);
899 __s_api_release_config(ptr);
900 return (ret);
904 * This function is not supported.
906 /* ARGSUSED */
907 int __ns_ldap_getObjectClassMaps(
908 const char *service,
909 ns_ldap_objectclass_map_t ***maps,
910 ns_ldap_error_t **errorp)
912 *maps = NULL;
913 return (NS_LDAP_OP_FAILED);
917 __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps)
919 ns_ldap_objectclass_map_t **dptr;
920 ns_ldap_objectclass_map_t *ptr;
922 if (*maps == NULL)
923 return (NS_LDAP_SUCCESS);
924 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
925 if (ptr->origOC) {
926 free(ptr->origOC);
927 ptr->origOC = NULL;
929 if (ptr->mappedOC) {
930 free(ptr->mappedOC);
931 ptr->mappedOC = NULL;
933 free(ptr);
935 free(*maps);
936 *maps = NULL;
938 return (NS_LDAP_SUCCESS);
941 char **__ns_ldap_getMappedObjectClass(
942 const char *service,
943 const char *origObjectClass)
945 ns_config_t *ptr = __s_api_loadrefresh_config();
946 ns_hash_t *hp;
947 char **ret;
949 if (ptr == NULL)
950 return (NULL);
952 hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass);
954 if (hp == NULL || hp->h_map == NULL)
955 ret = NULL;
956 else
957 ret = __s_api_cp2dArray(hp->h_map->map);
958 __s_api_release_config(ptr);
959 return (ret);
962 char **__ns_ldap_getOrigObjectClass(
963 const char *service,
964 const char *mappedObjectClass)
966 ns_config_t *ptr = __s_api_loadrefresh_config();
967 ns_hash_t *hp;
968 char **ret;
970 if (ptr == NULL)
971 return (NULL);
973 hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass);
975 if (hp == NULL || hp->h_map == NULL)
976 ret = NULL;
977 else
978 ret = __s_api_cp2dArray(hp->h_map->map);
979 __s_api_release_config(ptr);
980 return (ret);
983 char **__ns_ldap_mapAttributeList(
984 const char *service,
985 const char * const *origAttrList)
987 const char * const *opp;
988 char **cpp, **npp;
989 int i;
991 if (origAttrList == NULL)
992 return (NULL);
994 opp = origAttrList;
995 for (i = 0; *opp; i++, opp++)
997 cpp = (char **)calloc(i+1, sizeof (char *));
998 if (cpp == NULL)
999 return (NULL);
1001 opp = origAttrList;
1002 for (i = 0; *opp; i++, opp++) {
1003 npp = __ns_ldap_getMappedAttributes(service, *opp);
1004 if (npp && npp[0]) {
1005 cpp[i] = strdup(npp[0]);
1006 __s_api_free2dArray(npp);
1007 npp = NULL;
1008 if (cpp[i] == NULL) {
1009 __s_api_free2dArray(cpp);
1010 return (NULL);
1012 } else {
1013 cpp[i] = strdup(*opp);
1014 if (cpp[i] == NULL) {
1015 __s_api_free2dArray(cpp);
1016 return (NULL);
1020 return (cpp);
1023 char *
1024 __ns_ldap_mapAttribute(
1025 const char *service,
1026 const char *origAttr)
1028 char **npp;
1029 char *mappedAttr;
1031 if (origAttr == NULL)
1032 return (NULL);
1034 npp = __ns_ldap_getMappedAttributes(service, origAttr);
1035 if (npp && npp[0]) {
1036 mappedAttr = strdup(npp[0]);
1037 __s_api_free2dArray(npp);
1038 } else {
1039 mappedAttr = strdup(origAttr);
1041 return (mappedAttr);