12236 getmembers_DN doesn't properly handle errors from __ns_ldap_dn2uid
12240 nss_ldap does not properly look up group members by distinguished name
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 }
--- EOF ---