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
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.
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]
23 * Copyright 2015 Gary Mills
24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
39 #include <dlfcn.h> /* for dynamic loading only */
41 #include "ldap_parse.h"
42 #include "nis_parse_ldap_conf.h"
43 #include "nis_parse_ldap_err.h"
44 #include "ldap_util.h"
45 #include "ldap_util.h"
47 void append_dot(char **str
);
48 void append_comma(char **str
);
49 bool_t
make_full_dn(char **dn
, const char *base
);
50 bool_t
make_fqdn(__nis_object_dn_t
*dn
, const char *base
);
51 char *get_default_ldap_base(const char *domain
);
52 bool_t
add_domain(char **objName
, const char *domain
);
53 bool_t
add_column(__nis_table_mapping_t
*t
, const char *col_name
);
54 __nis_mapping_rule_t
**dup_mapping_rules(
55 __nis_mapping_rule_t
**rules
, int n_rules
);
56 __nis_mapping_rule_t
*dup_mapping_rule(
57 __nis_mapping_rule_t
*in
);
58 void *s_malloc(size_t size
);
59 __nis_mapping_format_t
*dup_format_mapping(
60 __nis_mapping_format_t
*in
);
61 bool_t
dup_mapping_element(__nis_mapping_element_t
*in
,
62 __nis_mapping_element_t
*out
);
63 bool_t
is_string_ok(char *, int);
68 * FUNCTION: free_parse_structs
70 * Release the resources in parse results
77 __nis_table_mapping_t
*t
;
78 __nis_table_mapping_t
*t1
;
80 free_proxy_info(&proxyInfo
);
81 for (t
= ldapTableMapping
; t
!= NULL
; t
= t1
) {
83 free_table_mapping(t
);
85 ldapTableMapping
= NULL
;
89 * FUNCTION: initialize_parse_structs
91 * Initialize fields to unset values
93 * INPUT: __nis_ldap_proxy_info, __nis_config_t
94 * and __nisdb_table_mapping_t structures
98 initialize_parse_structs(
99 __nis_ldap_proxy_info
*proxy_info
,
100 __nis_config_t
*config_info
,
101 __nisdb_table_mapping_t
*table_info
)
103 proxy_info
->default_servers
= NULL
;
104 proxy_info
->auth_method
= (auth_method_t
)NO_VALUE_SET
;
105 proxy_info
->tls_method
= (tls_method_t
)NO_VALUE_SET
;
106 proxy_info
->tls_cert_db
= NULL
;
107 proxy_info
->default_search_base
= NULL
;
108 proxy_info
->proxy_dn
= NULL
;
109 proxy_info
->proxy_passwd
= NULL
;
110 proxy_info
->default_nis_domain
= NULL
;
111 proxy_info
->bind_timeout
.tv_sec
= (time_t)NO_VALUE_SET
;
112 proxy_info
->bind_timeout
.tv_usec
= 0;
113 proxy_info
->search_timeout
.tv_sec
= (time_t)NO_VALUE_SET
;
114 proxy_info
->search_timeout
.tv_usec
= 0;
115 proxy_info
->modify_timeout
.tv_sec
= (time_t)NO_VALUE_SET
;
116 proxy_info
->modify_timeout
.tv_usec
= 0;
117 proxy_info
->add_timeout
.tv_sec
= (time_t)NO_VALUE_SET
;
118 proxy_info
->add_timeout
.tv_usec
= 0;
119 proxy_info
->delete_timeout
.tv_sec
= (time_t)NO_VALUE_SET
;
120 proxy_info
->delete_timeout
.tv_usec
= 0;
121 proxy_info
->search_time_limit
= (int)NO_VALUE_SET
;
122 proxy_info
->search_size_limit
= (int)NO_VALUE_SET
;
123 proxy_info
->follow_referral
= (follow_referral_t
)NO_VALUE_SET
;
126 config_info
->initialUpdate
= (__nis_initial_update_t
)NO_VALUE_SET
;
127 config_info
->threadCreationError
=
128 (__nis_thread_creation_error_t
)NO_VALUE_SET
;
129 config_info
->threadCreationErrorTimeout
.attempts
= NO_VALUE_SET
;
130 config_info
->threadCreationErrorTimeout
.timeout
= (time_t)NO_VALUE_SET
;
131 config_info
->dumpError
= (__nis_dump_error_t
)NO_VALUE_SET
;
132 config_info
->dumpErrorTimeout
.attempts
= NO_VALUE_SET
;
133 config_info
->dumpErrorTimeout
.timeout
= (time_t)NO_VALUE_SET
;
134 config_info
->resyncService
= (__nis_resync_service_t
)NO_VALUE_SET
;
135 config_info
->updateBatching
= (__nis_update_batching_t
)NO_VALUE_SET
;
136 config_info
->updateBatchingTimeout
.timeout
= (time_t)NO_VALUE_SET
;
137 config_info
->numberOfServiceThreads
= (int)NO_VALUE_SET
;
138 config_info
->emulate_yp
= (int)NO_VALUE_SET
;
139 config_info
->maxRPCRecordSize
= (int)NO_VALUE_SET
;
141 table_info
->retrieveError
= (__nis_retrieve_error_t
)NO_VALUE_SET
;
142 table_info
->retrieveErrorRetry
.attempts
= NO_VALUE_SET
;
143 table_info
->retrieveErrorRetry
.timeout
= (time_t)NO_VALUE_SET
;
144 table_info
->storeError
= (__nis_store_error_t
)NO_VALUE_SET
;
145 table_info
->storeErrorRetry
.attempts
= NO_VALUE_SET
;
146 table_info
->storeErrorRetry
.timeout
= (time_t)NO_VALUE_SET
;
147 table_info
->refreshError
= (__nis_refresh_error_t
)NO_VALUE_SET
;
148 table_info
->refreshErrorRetry
.attempts
= NO_VALUE_SET
;
149 table_info
->refreshErrorRetry
.timeout
= (time_t)NO_VALUE_SET
;
150 table_info
->matchFetch
= (__nis_match_fetch_t
)NO_VALUE_SET
;
154 * FUNCTION: free_mapping_rule
156 * Frees __nis_mapping_rule_t
158 * INPUT: __nis_mapping_rule_t
162 free_mapping_rule(__nis_mapping_rule_t
*rule
)
165 __nis_mapping_rlhs_t
*r
;
169 for (i
= 0; i
< r
->numElements
; i
++)
170 free_mapping_element(&r
->element
[i
]);
174 for (i
= 0; i
< r
->numElements
; i
++)
175 free_mapping_element(&r
->element
[i
]);
183 * FUNCTION: free_mapping_element
185 * Frees __nis_mapping_element_t
187 * INPUT: __nis_mapping_element_t
191 free_mapping_element(__nis_mapping_element_t
*e
)
200 free_mapping_item(&e
->element
.item
);
203 if (e
->element
.print
.fmt
!= NULL
)
204 free_mapping_format(e
->element
.print
.fmt
);
205 e
->element
.print
.fmt
= NULL
;
206 for (i
= 0; i
< e
->element
.print
.numSubElements
; i
++)
207 free_mapping_sub_element(
208 &e
->element
.print
.subElement
[i
]);
209 e
->element
.print
.numSubElements
= 0;
210 free(e
->element
.print
.subElement
);
211 e
->element
.print
.subElement
= NULL
;
214 free_mapping_item(&e
->element
.split
.item
);
217 if (e
->element
.match
.fmt
!= NULL
)
218 free_mapping_format(e
->element
.match
.fmt
);
219 e
->element
.match
.fmt
= NULL
;
220 for (i
= 0; i
< e
->element
.match
.numItems
; i
++)
221 free_mapping_item(&e
->element
.match
.item
[i
]);
222 e
->element
.match
.numItems
= 0;
223 free(e
->element
.match
.item
);
224 e
->element
.match
.item
= NULL
;
227 if (e
->element
.extract
.fmt
!= NULL
)
228 free_mapping_format(e
->element
.extract
.fmt
);
229 e
->element
.extract
.fmt
= NULL
;
230 free_mapping_item(&e
->element
.extract
.item
);
237 * FUNCTION: free_table_mapping
239 * Frees __nis_table_mapping_t
241 * INPUT: __nis_table_mapping_t
245 * free_table_mapping does not remove the table mapping from
250 free_table_mapping(__nis_table_mapping_t
*mapping
)
258 mapping
->dbId
= NULL
;
260 free(mapping
->objName
);
261 mapping
->objName
= NULL
;
263 for (i
= 0; i
< mapping
->index
.numIndexes
; i
++) {
264 free(mapping
->index
.name
[i
]);
265 free_mapping_format(mapping
->index
.value
[i
]);
268 free(mapping
->index
.name
);
269 mapping
->index
.name
= NULL
;
271 free(mapping
->index
.value
);
272 mapping
->index
.value
= NULL
;
274 mapping
->index
.numIndexes
= 0;
276 if (mapping
->column
!= NULL
) {
277 for (i
= 0; i
< mapping
->numColumns
; i
++) {
278 free(mapping
->column
[i
]);
280 mapping
->numColumns
= 0;
281 free(mapping
->column
);
282 mapping
->column
= NULL
;
285 if (mapping
->commentChar
!= '\0')
286 mapping
->commentChar
= '\0';
288 if (mapping
->objectDN
!= NULL
)
289 free_object_dn(mapping
->objectDN
);
290 mapping
->objectDN
= NULL
;
292 if (mapping
->separatorStr
!= NULL
)
293 mapping
->separatorStr
= NULL
;
295 for (i
= 0; i
< mapping
->numRulesFromLDAP
; i
++) {
296 if (mapping
->ruleFromLDAP
[i
]) /* See Comment below */
297 free_mapping_rule(mapping
->ruleFromLDAP
[i
]);
299 mapping
->numRulesFromLDAP
= 0;
301 free(mapping
->ruleFromLDAP
);
302 mapping
->ruleFromLDAP
= NULL
;
304 for (i
= 0; i
< mapping
->numRulesToLDAP
; i
++) {
305 if (mapping
->ruleToLDAP
[i
])
307 * Normally mapping->ruleToLDAP[i] should
308 * always be non-null if
309 * mapping->numRulesToLDAP is > 0.
310 * However it is possible to have data
311 * corruption where numRulesToLDAP gets
312 * some integer value even though no real
313 * data is present in mapping->ruleToLDAP.
315 free_mapping_rule(mapping
->ruleToLDAP
[i
]);
317 mapping
->numRulesToLDAP
= 0;
319 free(mapping
->ruleToLDAP
);
320 mapping
->ruleToLDAP
= NULL
;
322 if (mapping
->e
!= NULL
) {
323 /* Similar logic as in above comment applies. */
324 for (i
= 0; i
<= mapping
->numSplits
; i
++) {
325 free_mapping_element(&mapping
->e
[i
]);
331 mapping
->numSplits
= 0;
337 * FUNCTION: free_config_info
339 * Frees __nis_config_info_t
341 * INPUT: __nis_config_info_t
345 free_config_info(__nis_config_info_t
*config_info
)
347 free(config_info
->config_dn
);
348 config_info
->config_dn
= NULL
;
350 free(config_info
->default_servers
);
351 config_info
->default_servers
= NULL
;
353 free(config_info
->proxy_dn
);
354 config_info
->proxy_dn
= NULL
;
356 free(config_info
->proxy_passwd
);
357 config_info
->proxy_passwd
= NULL
;
359 free(config_info
->tls_cert_db
);
360 config_info
->tls_cert_db
= NULL
;
364 * FUNCTION: free_proxy_info
366 * Frees __nis_ldap_proxy_info
368 * INPUT: __nis_ldap_proxy_info
372 free_proxy_info(__nis_ldap_proxy_info
*proxy_info
)
374 free(proxy_info
->tls_cert_db
);
375 proxy_info
->tls_cert_db
= NULL
;
377 free(proxy_info
->default_servers
);
378 proxy_info
->default_servers
= NULL
;
380 free(proxy_info
->default_search_base
);
381 proxy_info
->default_search_base
= NULL
;
383 free(proxy_info
->proxy_dn
);
384 proxy_info
->proxy_dn
= NULL
;
386 free(proxy_info
->proxy_passwd
);
387 proxy_info
->proxy_passwd
= NULL
;
389 free(proxy_info
->default_nis_domain
);
390 proxy_info
->default_nis_domain
= NULL
;
394 * FUNCTION: free_object_dn
396 * Frees __nis_object_dn_t
398 * INPUT: __nis_object_dn_t
402 free_object_dn(__nis_object_dn_t
*obj_dn
)
404 __nis_object_dn_t
*t
;
407 while (obj_dn
!= NULL
) {
408 free(obj_dn
->read
.base
);
409 obj_dn
->read
.base
= NULL
;
410 free(obj_dn
->read
.attrs
);
411 obj_dn
->read
.attrs
= NULL
;
412 free(obj_dn
->write
.base
);
413 obj_dn
->write
.base
= NULL
;
414 free(obj_dn
->write
.attrs
);
415 obj_dn
->write
.attrs
= NULL
;
416 free(obj_dn
->dbIdName
);
417 obj_dn
->dbIdName
= NULL
;
418 for (i
= 0; i
< obj_dn
->numDbIds
; i
++)
419 free_mapping_rule(obj_dn
->dbId
[i
]);
420 obj_dn
->numDbIds
= 0;
426 obj_dn
= obj_dn
->next
;
432 * FUNCTION: free_index
434 * Frees __nis_index_t
436 * INPUT: __nis_index_t
440 free_index(__nis_index_t
*index
)
443 for (i
= 0; i
< index
->numIndexes
; i
++) {
444 free(index
->name
[i
]);
445 free_mapping_format(index
->value
[i
]);
447 index
->numIndexes
= 0;
455 * FUNCTION: free_mapping_item
457 * Frees __nis_mapping_item_t
459 * INPUT: __nis_mapping_item_t
463 free_mapping_item(__nis_mapping_item_t
*item
)
470 if (item
->type
== mit_nisplus
) {
471 free_index(&item
->searchSpec
.obj
.index
);
472 free(item
->searchSpec
.obj
.name
);
473 item
->searchSpec
.obj
.name
= NULL
;
474 } else if (item
->type
== mit_ldap
) {
475 free(item
->searchSpec
.triple
.base
);
476 item
->searchSpec
.triple
.base
= NULL
;
477 free(item
->searchSpec
.triple
.attrs
);
478 item
->searchSpec
.triple
.attrs
= NULL
;
479 if (item
->searchSpec
.triple
.element
!= NULL
) {
480 free_mapping_element(
481 item
->searchSpec
.triple
.element
);
482 free(item
->searchSpec
.triple
.element
);
484 item
->searchSpec
.triple
.element
= NULL
;
486 if (item
->exItem
!= NULL
) {
487 free_mapping_item(item
->exItem
);
494 * FUNCTION: free_mapping_format
496 * Frees __nis_mapping_format_t
498 * INPUT: __nis_mapping_format_t
502 free_mapping_format(__nis_mapping_format_t
*fmt
)
504 __nis_mapping_format_t
*f
= fmt
;
506 while (fmt
->type
!= mmt_end
) {
511 free(fmt
->match
.string
);
512 fmt
->match
.string
= NULL
;
515 free(fmt
->match
.single
.lo
);
516 fmt
->match
.single
.lo
= NULL
;
517 free(fmt
->match
.single
.hi
);
518 fmt
->match
.single
.hi
= NULL
;
525 case mmt_berstring_null
:
526 free(fmt
->match
.berString
);
527 fmt
->match
.berString
= NULL
;
540 * FUNCTION: free_mapping_sub_element
542 * Frees __nis_mapping_sub_element_t
544 * INPUT: __nis_mapping_sub_element_t
548 free_mapping_sub_element(__nis_mapping_sub_element_t
*sub
)
554 free_mapping_item(&sub
->element
.item
);
557 if (sub
->element
.print
.fmt
!= NULL
)
558 free_mapping_format(sub
->element
.print
.fmt
);
559 sub
->element
.print
.fmt
= NULL
;
560 for (i
= 0; i
< sub
->element
.print
.numItems
; i
++)
561 free_mapping_item(&sub
->element
.print
.item
[i
]);
562 sub
->element
.print
.numItems
= 0;
563 free(sub
->element
.print
.item
);
564 sub
->element
.print
.item
= NULL
;
567 free_mapping_item(&sub
->element
.split
.item
);
570 if (sub
->element
.extract
.fmt
!= NULL
)
571 free_mapping_format(sub
->element
.extract
.fmt
);
572 sub
->element
.extract
.fmt
= NULL
;
573 free_mapping_item(&sub
->element
.extract
.item
);
579 * FUNCTION: read_line
581 * Gets next line in buffer - using '\' at end of line
582 * to indicate continuation. Lines beginning with # are
583 * ignored. start_line_num and start_line_num are
584 * maintained to track the line number currently being
587 * RETURN VALUE: The number of characters read. 0 for
590 * INPUT: file descriptor, buffer, and buffer size
594 read_line(int fd
, char *buffer
, int buflen
)
599 bool_t skip_line
= FALSE
;
600 bool_t begin_line
= TRUE
;
601 static bool_t prev_cr
= FALSE
;
603 start_line_num
= cur_line_num
;
604 (void) memset(buffer
, 0, buflen
);
605 for (; p_error
== no_parse_error
; ) {
607 while (linelen
< buflen
) {
608 rc
= read(fd
, &c
, 1);
610 if (c
== '\n' || c
== '\r') {
649 } else if (linelen
> 0 &&
653 } else if (linelen
> 0) {
654 buffer
[linelen
] = '\0';
660 skip_line
= c
== POUND_SIGN
;
663 buffer
[linelen
++] = c
;
667 buffer
[linelen
- 1] == ESCAPE_CHAR
) {
668 /* continuation on last line */
669 p_error
= parse_bad_continuation_error
;
672 buffer
[linelen
] = '\0';
677 p_error
= parse_line_too_long
;
683 * FUNCTION: finish_parse
685 * Adds any elements not configured, fully qualifies
688 * RETURN VALUE: 0 on success, -1 on failure
693 __nis_ldap_proxy_info
*proxy_info
,
694 __nis_table_mapping_t
**table_mapping
)
696 __nis_table_mapping_t
*t
;
697 __nis_table_mapping_t
*t1
;
698 __nis_table_mapping_t
*t2
;
699 __nis_table_mapping_t
*t_del
= NULL
;
703 __nis_object_dn_t
*objectDN
;
704 __nis_mapping_rlhs_t
*lhs
;
705 __nis_mapping_element_t
*e
;
709 /* set to default those values yet set */
710 if (proxy_info
->auth_method
==
711 (auth_method_t
)NO_VALUE_SET
) {
712 p_error
= parse_no_proxy_auth_error
;
713 report_error(NULL
, NULL
);
717 if (proxy_info
->default_servers
== NULL
) {
718 p_error
= parse_no_ldap_server_error
;
719 report_error(NULL
, NULL
);
723 if (proxy_info
->tls_method
== (tls_method_t
)NO_VALUE_SET
)
724 proxy_info
->tls_method
= no_tls
;
725 else if (proxy_info
->tls_method
== ssl_tls
&&
726 (proxy_info
->tls_cert_db
== NULL
||
727 *proxy_info
->tls_cert_db
== '\0')) {
728 p_error
= parse_no_cert_db
;
729 report_error(NULL
, NULL
);
733 if (proxy_info
->default_nis_domain
== NULL
)
734 proxy_info
->default_nis_domain
=
735 s_strdup(__nis_rpc_domain());
736 else if (*proxy_info
->default_nis_domain
== '\0') {
737 free(proxy_info
->default_nis_domain
);
738 proxy_info
->default_nis_domain
=
739 s_strdup(__nis_rpc_domain());
741 if (proxy_info
->default_nis_domain
!= NULL
)
742 append_dot(&proxy_info
->default_nis_domain
);
744 if (proxy_info
->tls_method
== ssl_tls
) {
745 if ((errnum
= ldapssl_client_init(
746 proxy_info
->tls_cert_db
, NULL
)) < 0) {
747 p_error
= parse_ldapssl_client_init_error
;
748 report_error(ldapssl_err2string(errnum
), NULL
);
753 if (proxy_info
->default_search_base
== NULL
)
754 proxy_info
->default_search_base
=
755 get_default_ldap_base(proxy_info
->default_nis_domain
);
757 /* convert a relative dn to a fullly qualified dn */
758 (void) make_full_dn(&proxy_info
->proxy_dn
,
759 proxy_info
->default_search_base
);
761 if (p_error
!= no_parse_error
) {
762 report_error(NULL
, NULL
);
767 * Create a list of potential delete mappings
768 * those have NULL objectDNs, but badly also rules
769 * that are missing object dn's will be included.
770 * We will use the ttl field to determine if the
771 * delete rule is actually used
774 for (t
= *table_mapping
; t
!= NULL
; t
= t1
) {
776 if (t
->objectDN
== NULL
) {
788 for (t
= *table_mapping
; t
!= NULL
; t
= t
->next
) {
789 objectDN
= t
->objectDN
;
790 while (objectDN
!= NULL
) {
791 if (objectDN
->dbIdName
!= NULL
) {
792 s
= objectDN
->dbIdName
;
793 t1
= find_table_mapping(s
, strlen(s
), t_del
);
795 p_error
= parse_no_db_del_mapping_rule
;
796 report_error2(objectDN
->dbIdName
, t
->dbId
);
798 } else if (t1
->objName
!= NULL
||
799 t1
->numRulesToLDAP
== 0 ||
800 t1
->numRulesFromLDAP
!= 0) {
801 p_error
= parse_invalid_db_del_mapping_rule
;
802 report_error(t1
->dbId
, NULL
);
806 dup_mapping_rules(t1
->ruleToLDAP
,
808 if (objectDN
->dbId
== NULL
) {
811 objectDN
->numDbIds
= t1
->numRulesToLDAP
;
814 objectDN
= objectDN
->next
;
818 for (t
= t_del
; t
!= NULL
; t
= t1
) {
821 p_error
= parse_no_object_dn
;
822 report_error(t
->dbId
, NULL
);
824 free_table_mapping(t
);
827 if (p_error
!= no_parse_error
)
830 /* set to default those table mapping values yet set */
831 for (t
= *table_mapping
; t
!= NULL
; t
= t
->next
) {
832 if (t
->objName
== 0) {
833 p_error
= parse_no_object_dn
;
834 report_error(t
->dbId
, NULL
);
838 if (!add_domain(&t
->objName
,
839 proxy_info
->default_nis_domain
)) {
840 report_error(NULL
, NULL
);
844 if (t
->initTtlHi
== (time_t)NO_VALUE_SET
)
845 t
->initTtlHi
= DEFAULT_TTL_HIGH
;
846 if (t
->initTtlLo
== (time_t)NO_VALUE_SET
)
847 t
->initTtlLo
= DEFAULT_TTL_LOW
;
848 if (t
->ttl
== (time_t)NO_VALUE_SET
)
849 t
->ttl
= DEFAULT_TTL
;
850 objectDN
= t
->objectDN
;
852 /* fixup relative dn's */
853 while (objectDN
!= NULL
) {
855 if (!make_full_dn(&objectDN
->read
.base
,
856 proxy_info
->default_search_base
))
859 if (objectDN
->write
.scope
!= LDAP_SCOPE_UNKNOWN
) {
860 if (objectDN
->write
.base
!= NULL
&&
861 !make_full_dn(&objectDN
->write
.base
,
862 proxy_info
->default_search_base
))
864 if (objectDN
->write
.base
== NULL
) {
865 objectDN
->write
.base
=
866 s_strdup(objectDN
->read
.base
);
867 if (objectDN
->write
.base
== NULL
)
871 objectDN
= objectDN
->next
;
874 if (p_error
!= no_parse_error
) {
875 report_error(NULL
, NULL
);
879 /* Check for ruleToLDAP with no rhs */
880 for (i
= 0; i
< t
->numRulesToLDAP
; i
++) {
881 if (t
->ruleToLDAP
[i
]->rhs
.numElements
== 0) {
882 p_error
= parse_unexpected_data_end_rule
;
883 report_error(t
->dbId
, NULL
);
888 /* populate cols field */
890 for (i
= 0; i
< t
->numRulesFromLDAP
; i
++) {
891 lhs
= &t
->ruleFromLDAP
[i
]->lhs
;
892 for (j
= 0; j
< lhs
->numElements
; j
++) {
893 e
= &lhs
->element
[j
];
897 e
->element
.item
.name
)) {
905 k
< e
->element
.match
.numItems
;
908 e
->element
.match
.item
[k
].name
)) {
923 * FUNCTION: set_default_values
925 * Sets unconfigured values to their default value
929 set_default_values(__nis_ldap_proxy_info
*proxy_info
,
930 __nis_config_t
*config_info
, __nisdb_table_mapping_t
*table_info
)
932 if (proxy_info
->bind_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
933 proxy_info
->bind_timeout
.tv_sec
= DEFAULT_BIND_TIMEOUT
;
934 if (proxy_info
->search_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
935 proxy_info
->search_timeout
.tv_sec
=
936 (yp2ldap
)?DEFAULT_YP_SEARCH_TIMEOUT
:
937 DEFAULT_SEARCH_TIMEOUT
;
938 if (proxy_info
->modify_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
939 proxy_info
->modify_timeout
.tv_sec
= DEFAULT_MODIFY_TIMEOUT
;
940 if (proxy_info
->add_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
941 proxy_info
->add_timeout
.tv_sec
= DEFAULT_ADD_TIMEOUT
;
942 if (proxy_info
->delete_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
943 proxy_info
->delete_timeout
.tv_sec
= DEFAULT_DELETE_TIMEOUT
;
945 if (proxy_info
->search_time_limit
== (int)NO_VALUE_SET
)
946 proxy_info
->search_time_limit
= DEFAULT_SEARCH_TIME_LIMIT
;
947 if (proxy_info
->search_size_limit
== (int)NO_VALUE_SET
)
948 proxy_info
->search_size_limit
= DEFAULT_SEARCH_SIZE_LIMIT
;
950 if (proxy_info
->follow_referral
== (follow_referral_t
)NO_VALUE_SET
)
951 proxy_info
->follow_referral
= no_follow
;
953 switch (config_info
->initialUpdate
) {
954 case (__nis_initial_update_t
)NO_VALUE_SET
:
955 case (__nis_initial_update_t
)INITIAL_UPDATE_NO_ACTION
:
956 case (__nis_initial_update_t
)NO_INITIAL_UPDATE_NO_ACTION
:
957 config_info
->initialUpdate
= ini_none
;
959 case (__nis_initial_update_t
)FROM_NO_INITIAL_UPDATE
:
960 config_info
->initialUpdate
= from_ldap
;
962 case (__nis_initial_update_t
)TO_NO_INITIAL_UPDATE
:
963 config_info
->initialUpdate
= to_ldap
;
966 if (config_info
->threadCreationError
==
967 (__nis_thread_creation_error_t
)NO_VALUE_SET
)
968 config_info
->threadCreationError
= pass_error
;
969 if (config_info
->threadCreationErrorTimeout
.attempts
== NO_VALUE_SET
)
970 config_info
->threadCreationErrorTimeout
.attempts
=
971 DEFAULT_THREAD_ERROR_ATTEMPTS
;
972 if (config_info
->threadCreationErrorTimeout
.timeout
==
973 (time_t)NO_VALUE_SET
)
974 config_info
->threadCreationErrorTimeout
.timeout
=
975 DEFAULT_THREAD_ERROR_TIME_OUT
;
976 if (config_info
->dumpError
==
977 (__nis_dump_error_t
)NO_VALUE_SET
)
978 config_info
->dumpError
= de_retry
;
979 if (config_info
->dumpErrorTimeout
.attempts
== NO_VALUE_SET
)
980 config_info
->dumpErrorTimeout
.attempts
=
981 DEFAULT_DUMP_ERROR_ATTEMPTS
;
982 if (config_info
->dumpErrorTimeout
.timeout
== (time_t)NO_VALUE_SET
)
983 config_info
->dumpErrorTimeout
.timeout
=
984 DEFAULT_DUMP_ERROR_TIME_OUT
;
985 if (config_info
->resyncService
==
986 (__nis_resync_service_t
)NO_VALUE_SET
)
987 config_info
->resyncService
= from_copy
;
988 if (config_info
->updateBatching
==
989 (__nis_update_batching_t
)NO_VALUE_SET
)
990 config_info
->updateBatching
= accumulate
;
991 if (config_info
->updateBatchingTimeout
.timeout
== (time_t)NO_VALUE_SET
)
992 config_info
->updateBatchingTimeout
.timeout
=
993 DEFAULT_BATCHING_TIME_OUT
;
994 if (config_info
->numberOfServiceThreads
== (int)NO_VALUE_SET
)
995 config_info
->numberOfServiceThreads
=
996 DEFAULT_NUMBER_OF_THREADS
;
997 if (config_info
->emulate_yp
== (int)NO_VALUE_SET
)
998 config_info
->emulate_yp
=
999 DEFAULT_YP_EMULATION
;
1000 if (config_info
->maxRPCRecordSize
== (int)NO_VALUE_SET
)
1001 config_info
->maxRPCRecordSize
= RPC_MAXDATASIZE
;
1003 if (table_info
->retrieveError
==
1004 (__nis_retrieve_error_t
)NO_VALUE_SET
)
1005 table_info
->retrieveError
= use_cached
;
1006 if (table_info
->retrieveErrorRetry
.attempts
== NO_VALUE_SET
)
1007 table_info
->retrieveErrorRetry
.attempts
=
1008 DEFAULT_RETRIEVE_ERROR_ATTEMPTS
;
1009 if (table_info
->retrieveErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1010 table_info
->retrieveErrorRetry
.timeout
=
1011 DEFAULT_RETRIEVE_ERROR_TIME_OUT
;
1012 if (table_info
->storeError
==
1013 (__nis_store_error_t
)NO_VALUE_SET
)
1014 table_info
->storeError
= sto_retry
;
1015 if (table_info
->storeErrorRetry
.attempts
== NO_VALUE_SET
)
1016 table_info
->storeErrorRetry
.attempts
=
1017 DEFAULT_STORE_ERROR_ATTEMPTS
;
1018 if (table_info
->storeErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1019 table_info
->storeErrorRetry
.timeout
=
1020 DEFAULT_STORE_ERROR_TIME_OUT
;
1021 if (table_info
->refreshError
==
1022 (__nis_refresh_error_t
)NO_VALUE_SET
)
1023 table_info
->refreshError
= continue_using
;
1024 if (table_info
->refreshErrorRetry
.attempts
== NO_VALUE_SET
)
1025 table_info
->refreshErrorRetry
.attempts
=
1026 DEFAULT_REFRESH_ERROR_ATTEMPTS
;
1027 if (table_info
->refreshErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1028 table_info
->refreshErrorRetry
.timeout
=
1029 DEFAULT_REFRESH_ERROR_TIME_OUT
;
1030 if (table_info
->matchFetch
==
1031 (__nis_match_fetch_t
)NO_VALUE_SET
)
1032 table_info
->matchFetch
= no_match_only
;
1035 __nis_table_mapping_t
*
1036 find_table_mapping(const char *s
, int len
, __nis_table_mapping_t
*table_mapping
)
1038 __nis_table_mapping_t
*t
;
1040 for (t
= table_mapping
; t
!= NULL
; t
= t
->next
)
1041 if (strlen(t
->dbId
) == len
&&
1042 strncasecmp(t
->dbId
, s
, len
) == 0)
1048 append_dot(char **str
)
1051 int len
= strlen(s
);
1053 if (len
== 0 || s
[len
- 1] != PERIOD_CHAR
) {
1054 s
= s_realloc(s
, len
+ 2);
1056 s
[len
] = PERIOD_CHAR
;
1064 append_comma(char **str
)
1068 int len
= strlen(s
);
1070 if (len
== 0 || s
[len
- 1] != COMMA_CHAR
) {
1071 s
= s_realloc(s
, len
+ 2);
1073 s
[len
] = COMMA_CHAR
;
1081 * FUNCTION: make_full_dn
1083 * Appends the base dn if a relative ldap dn
1084 * (invoked only for LDAP write cycle)
1086 * RETURN VALUE: FALSE if error
1087 * TRUE if __nis_index_t returned
1089 * INPUT: the relative dn and ldap base
1093 make_full_dn(char **dn
, const char *base
)
1099 *dn
= s_strdup(base
);
1102 if (len
> 0 && (*dn
)[len
-1] == COMMA_CHAR
) {
1103 len1
= strlen(base
) + 1;
1104 *dn
= s_realloc(*dn
, len
+ len1
);
1106 (void) strcpy(*dn
+ len
, base
);
1109 return (*dn
!= NULL
);
1113 * FUNCTION: make_fqdn
1115 * Appends the base dn if a relative ldap dn
1116 * (invoked only for LDAP read cycle)
1118 * RETURN VALUE: FALSE if error
1121 * INPUT: the relative dn and ldap base
1124 make_fqdn(__nis_object_dn_t
*dn
, const char *base
)
1132 while (dn
!= NULL
&& dn
->read
.base
!= NULL
) {
1133 len
= strlen(dn
->read
.base
);
1134 if (len
> 0 && (dn
->read
.base
)[len
-1] == COMMA_CHAR
) {
1135 len1
= strlen(base
) + 1;
1137 s_realloc(dn
->read
.base
, len
+ len1
);
1138 if (dn
->read
.base
!= NULL
)
1139 (void) strlcpy(dn
->read
.base
+ len
,
1151 * FUNCTION: get_default_ldap_base
1153 * Gets the default LDAP search base from the
1154 * nis+ default domain
1156 * RETURN VALUE: NULL if error
1159 * INPUT: the nis domain
1163 get_default_ldap_base(const char *domain
)
1166 int len
= strlen(domain
);
1168 int count
= len
+ 4;
1171 for (i
= 0; i
< len
- 1; i
++)
1172 if (domain
[i
] == PERIOD_CHAR
)
1174 if ((base
= malloc(count
)) == NULL
) {
1175 p_error
= parse_no_mem_error
;
1177 (void) strcpy(base
, "dc=");
1179 for (i
= 0; i
< len
- 1; i
++) {
1180 if (domain
[i
] == PERIOD_CHAR
) {
1181 (void) strcpy(base
+ count
, ",dc=");
1184 base
[count
++] = domain
[i
];
1193 * FUNCTION: add_domain
1195 * Appends the base domain if a relative object name
1197 * RETURN VALUE: FALSE if error
1200 * INPUT: the relative object name and base domain
1205 add_domain(char **objName
, const char *domain
)
1209 bool_t trailing_dot
;
1212 if (domain
== NULL
|| *objName
== NULL
) {
1213 p_error
= parse_internal_error
;
1216 len1
= strlen(domain
);
1217 trailing_dot
= (len1
> 0 && domain
[len1
- 1] == PERIOD_CHAR
) ?
1219 len
= strlen(*objName
);
1220 if (len
== 0 || (*objName
)[len
- 1] != PERIOD_CHAR
) {
1221 obj_name
= s_realloc(*objName
,
1222 len
+ len1
+ 2 + trailing_dot
);
1223 if (obj_name
!= NULL
) {
1224 obj_name
[len
++] = PERIOD_CHAR
;
1225 (void) strcpy(obj_name
+ len
, domain
);
1226 if (trailing_dot
!= 0) {
1227 obj_name
[len
+ len1
] = PERIOD_CHAR
;
1228 obj_name
[len
+ len1
+ 1] = '\0';
1230 *objName
= obj_name
;
1234 return (*objName
!= NULL
);
1238 dup_index(__nis_index_t
*in
, __nis_index_t
*out
)
1243 out
->name
= (char **)s_calloc(in
->numIndexes
, sizeof (char *));
1244 if (out
->name
== NULL
)
1246 out
->value
= (__nis_mapping_format_t
**)
1247 s_calloc(in
->numIndexes
, sizeof (__nis_mapping_format_t
*));
1248 if (out
->value
== NULL
) {
1254 for (i
= 0; i
< in
->numIndexes
; i
++) {
1255 out
->name
[i
] = s_strdup(in
->name
[i
]);
1256 if (out
->name
[i
] == NULL
)
1258 out
->value
[i
] = dup_format_mapping(in
->value
[i
]);
1259 if (out
->value
[i
] == NULL
)
1262 if (i
< in
->numIndexes
) {
1263 for (j
= 0; j
<= i
; j
++) {
1265 if (out
->value
[j
] != NULL
)
1266 free_mapping_format(out
->value
[j
]);
1273 out
->numIndexes
= in
->numIndexes
;
1275 return (i
== in
->numIndexes
);
1279 dup_mapping_item(__nis_mapping_item_t
*in
, __nis_mapping_item_t
*out
)
1283 if (in
->type
== mit_nisplus
) {
1284 ret
= dup_index(&in
->searchSpec
.obj
.index
,
1285 &out
->searchSpec
.obj
.index
);
1288 if (in
->searchSpec
.obj
.name
!= NULL
) {
1289 out
->searchSpec
.obj
.name
=
1290 s_strdup(in
->searchSpec
.obj
.name
);
1291 if (out
->searchSpec
.obj
.name
== NULL
)
1294 out
->searchSpec
.obj
.name
= NULL
;
1295 } else if (in
->type
== mit_ldap
) {
1296 if (in
->searchSpec
.triple
.base
!= NULL
) {
1297 out
->searchSpec
.triple
.base
=
1298 s_strdup(in
->searchSpec
.triple
.base
);
1299 if (out
->searchSpec
.triple
.base
== NULL
)
1302 out
->searchSpec
.triple
.base
= NULL
;
1303 out
->searchSpec
.triple
.scope
=
1304 in
->searchSpec
.triple
.scope
;
1305 if (in
->searchSpec
.triple
.attrs
!= NULL
) {
1306 out
->searchSpec
.triple
.attrs
=
1307 s_strdup(in
->searchSpec
.triple
.attrs
);
1308 if (out
->searchSpec
.triple
.attrs
== NULL
)
1311 out
->searchSpec
.triple
.attrs
= NULL
;
1312 if (in
->searchSpec
.triple
.element
!= NULL
) {
1313 out
->searchSpec
.triple
.element
=
1314 (__nis_mapping_element_t
*)
1315 s_calloc(1, sizeof (__nis_mapping_element_t
));
1316 if (out
->searchSpec
.triple
.element
!= NULL
)
1317 dup_mapping_element(
1318 in
->searchSpec
.triple
.element
,
1319 out
->searchSpec
.triple
.element
);
1320 if (out
->searchSpec
.triple
.element
== NULL
)
1323 out
->searchSpec
.triple
.element
= NULL
;
1326 if (in
->name
!= NULL
) {
1327 out
->name
= s_strdup(in
->name
);
1328 if (out
->name
== NULL
)
1332 out
->type
= in
->type
;
1333 out
->repeat
= in
->repeat
;
1335 out
->exItem
= (__nis_mapping_item_t
*)s_malloc
1336 (sizeof (__nis_mapping_item_t
));
1337 if (out
->exItem
== NULL
)
1341 (out
->exItem
, 0, sizeof (out
->exItem
[0]));
1342 if (!dup_mapping_item
1343 (in
->exItem
, out
->exItem
))
1344 p_error
= parse_internal_error
;
1349 return (p_error
== no_parse_error
);
1352 __nis_mapping_format_t
*
1353 dup_format_mapping(__nis_mapping_format_t
*in
)
1356 __nis_mapping_format_t
*out
;
1360 while (in
[i
].type
!= mmt_end
)
1362 out
= (__nis_mapping_format_t
*)s_calloc(
1363 i
+ 1, sizeof (__nis_mapping_format_t
));
1366 for (i
= 0; !got_end
; i
++) {
1367 switch (in
[i
].type
) {
1371 out
[i
].match
.string
=
1372 s_strdup(in
[i
].match
.string
);
1375 out
[i
].match
.single
.numRange
=
1376 in
[i
].match
.single
.numRange
;
1377 out
[i
].match
.single
.lo
=
1378 s_malloc(in
[i
].match
.single
.numRange
);
1379 if (out
[i
].match
.single
.lo
== NULL
)
1381 out
[i
].match
.single
.hi
=
1382 s_malloc(in
[i
].match
.single
.numRange
);
1383 if (out
[i
].match
.single
.hi
== NULL
)
1385 memcpy(out
[i
].match
.single
.lo
,
1386 in
[i
].match
.single
.lo
,
1387 in
[i
].match
.single
.numRange
);
1388 memcpy(out
[i
].match
.single
.hi
,
1389 in
[i
].match
.single
.hi
,
1390 in
[i
].match
.single
.numRange
);
1393 out
[i
].match
.limit
= in
[i
].match
.limit
;
1398 out
[i
].match
.berString
=
1399 s_strdup(in
[i
].match
.berString
);
1407 p_error
= parse_internal_error
;
1409 if (p_error
!= no_parse_error
)
1411 out
[i
].type
= in
[i
].type
;
1413 if (p_error
!= no_parse_error
) {
1414 free_mapping_format(out
);
1423 dup_mapping_sub_element(
1424 __nis_mapping_sub_element_t
*in
,
1425 __nis_mapping_sub_element_t
*out
)
1432 ret
= dup_mapping_item(&in
->element
.item
,
1433 &out
->element
.item
);
1436 out
->element
.print
.fmt
=
1437 dup_format_mapping(in
->element
.print
.fmt
);
1438 if (out
->element
.print
.fmt
== NULL
)
1440 out
->element
.print
.numItems
=
1441 in
->element
.print
.numItems
;
1442 out
->element
.print
.item
= (__nis_mapping_item_t
*)
1443 s_calloc(in
->element
.print
.numItems
,
1444 sizeof (__nis_mapping_item_t
));
1445 if (out
->element
.print
.item
== NULL
)
1447 for (i
= 0; i
< in
->element
.print
.numItems
; i
++)
1448 if (!dup_mapping_item(
1449 &in
->element
.print
.item
[i
],
1450 &out
->element
.print
.item
[i
]))
1452 if (i
< in
->element
.print
.numItems
)
1455 out
->element
.print
.doElide
= in
->element
.print
.doElide
;
1456 out
->element
.print
.elide
= in
->element
.print
.elide
;
1459 ret
= dup_mapping_item(&in
->element
.split
.item
,
1460 &out
->element
.split
.item
);
1461 out
->element
.split
.delim
= in
->element
.split
.delim
;
1464 out
->element
.extract
.fmt
=
1465 dup_format_mapping(in
->element
.extract
.fmt
);
1466 if (out
->element
.extract
.fmt
== NULL
)
1468 ret
= dup_mapping_item(&in
->element
.extract
.item
,
1469 &out
->element
.extract
.item
);
1472 p_error
= parse_internal_error
;
1474 out
->type
= in
->type
;
1480 dup_mapping_element(
1481 __nis_mapping_element_t
*in
,
1482 __nis_mapping_element_t
*out
)
1492 ret
= dup_mapping_item(&in
->element
.item
,
1493 &out
->element
.item
);
1496 out
->element
.print
.fmt
=
1497 dup_format_mapping(in
->element
.print
.fmt
);
1498 if (out
->element
.print
.fmt
== NULL
)
1500 out
->element
.print
.numSubElements
=
1501 in
->element
.print
.numSubElements
;
1502 out
->element
.print
.subElement
=
1503 (__nis_mapping_sub_element_t
*)
1504 s_calloc(in
->element
.print
.numSubElements
,
1505 sizeof (__nis_mapping_sub_element_t
));
1506 if (out
->element
.print
.subElement
== NULL
)
1508 for (i
= 0; i
< in
->element
.print
.numSubElements
; i
++)
1509 if (!dup_mapping_sub_element(
1510 &in
->element
.print
.subElement
[i
],
1511 &out
->element
.print
.subElement
[i
]))
1513 if (i
< in
->element
.print
.numSubElements
)
1516 out
->element
.print
.doElide
= in
->element
.print
.doElide
;
1517 out
->element
.print
.elide
= in
->element
.print
.elide
;
1520 ret
= dup_mapping_item(&in
->element
.split
.item
,
1521 &out
->element
.split
.item
);
1522 out
->element
.split
.delim
= in
->element
.split
.delim
;
1525 out
->element
.match
.fmt
=
1526 dup_format_mapping(in
->element
.match
.fmt
);
1527 if (out
->element
.match
.fmt
== NULL
)
1529 out
->element
.match
.numItems
=
1530 in
->element
.match
.numItems
;
1531 out
->element
.match
.item
= (__nis_mapping_item_t
*)
1532 s_calloc(in
->element
.match
.numItems
,
1533 sizeof (__nis_mapping_item_t
));
1534 if (out
->element
.match
.item
== NULL
)
1536 for (i
= 0; i
< in
->element
.match
.numItems
; i
++)
1537 if (!dup_mapping_item(
1538 &in
->element
.match
.item
[i
],
1539 &out
->element
.match
.item
[i
]))
1541 if (i
< in
->element
.match
.numItems
)
1546 out
->element
.extract
.fmt
=
1547 dup_format_mapping(in
->element
.extract
.fmt
);
1548 if (out
->element
.extract
.fmt
== NULL
)
1550 ret
= dup_mapping_item(&in
->element
.extract
.item
,
1551 &out
->element
.extract
.item
);
1554 p_error
= parse_internal_error
;
1556 out
->type
= in
->type
;
1561 __nis_mapping_rule_t
*
1562 dup_mapping_rule(__nis_mapping_rule_t
*in
)
1565 __nis_mapping_rlhs_t
*r_in
;
1566 __nis_mapping_rlhs_t
*r_out
;
1567 __nis_mapping_rule_t
*out
;
1569 out
= (__nis_mapping_rule_t
*)
1570 s_calloc(1, sizeof (__nis_mapping_rule_t
));
1574 r_out
->numElements
= r_in
->numElements
;
1575 r_out
->element
= (__nis_mapping_element_t
*)s_calloc
1576 (r_in
->numElements
, sizeof (__nis_mapping_element_t
));
1577 if (r_out
->element
== NULL
) {
1578 free_mapping_rule(out
);
1581 for (i
= 0; i
< r_in
->numElements
; i
++) {
1582 if (!dup_mapping_element(&r_in
->element
[i
],
1583 &r_out
->element
[i
]))
1586 if (i
< r_in
->numElements
) {
1587 free_mapping_rule(out
);
1593 r_out
->numElements
= r_in
->numElements
;
1594 r_out
->element
= (__nis_mapping_element_t
*)s_calloc
1595 (r_in
->numElements
, sizeof (__nis_mapping_element_t
));
1596 if (r_out
->element
== NULL
) {
1597 free_mapping_rule(out
);
1600 for (i
= 0; i
< r_in
->numElements
; i
++) {
1601 if (!dup_mapping_element(&r_in
->element
[i
],
1602 &r_out
->element
[i
]))
1605 if (i
< r_in
->numElements
) {
1606 free_mapping_rule(out
);
1613 __nis_mapping_rule_t
**
1614 dup_mapping_rules(__nis_mapping_rule_t
**rules
, int n_rules
)
1617 __nis_mapping_rule_t
**r
;
1619 r
= (__nis_mapping_rule_t
**)s_calloc(n_rules
,
1620 sizeof (__nis_mapping_rule_t
*));
1622 for (i
= 0; i
< n_rules
; i
++) {
1623 r
[i
] = dup_mapping_rule(rules
[i
]);
1625 for (j
= 0; j
< i
; j
++)
1626 free_mapping_rule(r
[j
]);
1637 * FUNCTION: add_column
1639 * Adds a column name to the column list in __nis_table_mapping_t
1641 * RETURN VALUE: FALSE if error
1642 * TRUE if __nis_index_t returned
1644 * INPUT: the __nis_table_mapping_t and column name
1648 add_column(__nis_table_mapping_t
*t
, const char *col_name
)
1654 for (i
= 0; i
< t
->numColumns
; i
++) {
1655 if (strcasecmp(col_name
, t
->column
[i
]) == 0)
1659 cols
= (char **)s_realloc(t
->column
, (t
->numColumns
+ 1) *
1664 cols
[t
->numColumns
] = s_strdup(col_name
);
1665 if (cols
[t
->numColumns
] == NULL
)
1672 * FUNCTION: add_element
1674 * Adds a __nis_mapping_element_t to __nis_mapping_rlhs_t
1676 * RETURN VALUE: FALSE if error
1677 * TRUE if __nis_index_t returned
1679 * INPUT: the __nis_mapping_element_t and
1680 * __nis_mapping_rlhs_t
1685 __nis_mapping_element_t
*e
,
1686 __nis_mapping_rlhs_t
*m
)
1688 __nis_mapping_element_t
*e1
;
1690 int n
= m
->numElements
;
1692 e1
= (__nis_mapping_element_t
*)s_realloc(m
->element
,
1693 (n
+ 1) * sizeof (__nis_mapping_element_t
));
1696 for (i
= 0; i
< n
; i
++)
1697 free_mapping_element(e1
++);
1702 e1
[m
->numElements
++] = *e
;
1704 m
->element
= (__nis_mapping_element_t
*)e1
;
1706 return (e1
!= NULL
);
1710 * FUNCTION: get_next_object_dn_token
1712 * Get the next token in parsing object_dn
1714 * RETURN VALUE: NULL if error
1715 * position of beginning next token after
1718 * INPUT: the attribute value
1722 get_next_object_dn_token(
1723 const char **begin_ret
,
1724 const char **end_ret
,
1725 object_dn_token
*token
)
1727 object_dn_token t
= dn_no_token
;
1728 const char *s
= *begin_ret
;
1730 const char *end
= *end_ret
;
1734 while (s
< end
&& is_whitespace(*s
))
1738 } else if (*s
== SEMI_COLON_CHAR
) {
1741 } else if (*s
== QUESTION_MARK
) {
1744 } else if (*s
== COLON_CHAR
) {
1747 } else if (*s
== OPEN_PAREN_CHAR
) {
1749 s
= get_ldap_filter(&begin
, &end
);
1759 if (*s
== ESCAPE_CHAR
) {
1761 p_error
= parse_unmatched_escape
;
1766 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
1767 in_quotes
= ! in_quotes
;
1768 } else if (in_quotes
)
1770 else if (*s
== SEMI_COLON_CHAR
||
1771 *s
== QUESTION_MARK
||
1778 while (is_whitespace(*s1
))
1781 if (same_string("base", begin
, s1
- begin
))
1783 else if (same_string("one", begin
, s1
- begin
))
1785 else if (same_string("sub", begin
, s1
- begin
))
1798 * FUNCTION: get_next_token
1800 * Get the next token in parsing mapping attribute
1802 * RETURN VALUE: NULL if error
1803 * position of beginning next token after
1806 * INPUT: the attribute value
1810 get_next_token(const char **begin_token
, const char **end_token
, token_type
*t
)
1812 const char *s
= *begin_token
;
1813 const char *end_s
= *end_token
;
1814 const char *s_begin
;
1816 while (s
< end_s
&& is_whitespace(*s
))
1825 if (*s
== OPEN_PAREN_CHAR
) {
1829 while (s
< end_s
&& is_whitespace(*s
))
1831 *t
= open_paren_token
;
1832 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
1835 if (*s
== ESCAPE_CHAR
)
1837 else if (*s
== DOUBLE_QUOTE_CHAR
)
1843 p_error
= parse_unmatched_escape
;
1847 *t
= quoted_string_token
;
1848 *begin_token
= s_begin
+ 1;
1850 } else if (*s
== EQUAL_CHAR
|| *s
== COMMA_CHAR
||
1851 *s
== CLOSE_PAREN_CHAR
|| *s
== COLON_CHAR
) {
1852 if (*s
== EQUAL_CHAR
)
1854 else if (*s
== COMMA_CHAR
)
1856 else if (*s
== CLOSE_PAREN_CHAR
)
1857 *t
= close_paren_token
;
1864 while (s
< end_s
&& !is_whitespace(*s
)) {
1865 if (*s
== ESCAPE_CHAR
)
1867 else if (*s
== EQUAL_CHAR
|| *s
== CLOSE_PAREN_CHAR
||
1868 *s
== OPEN_PAREN_CHAR
|| *s
== COMMA_CHAR
||
1869 *s
== COLON_CHAR
|| *s
== OPEN_BRACKET
||
1870 *s
== CLOSE_BRACKET
)
1876 p_error
= parse_unmatched_escape
;
1881 *begin_token
= s_begin
;
1884 while (s
< end_s
&& is_whitespace(*s
))
1891 * FUNCTION: skip_token
1893 * Skip over the specified token - An error is set if
1894 * next token does not match expected token
1896 * RETURN VALUE: NULL if error
1897 * position of beginning next token after
1900 * INPUT: the attribute value
1904 skip_token(const char *s
, const char *end_s
, token_type t
)
1911 while (s
< end_s
&& is_whitespace(*s
))
1913 c
= (s
== end_s
) ? 0 : *s
;
1916 match
= c
== EQUAL_CHAR
;
1918 p_error
= parse_equal_expected_error
;
1921 match
= c
== COMMA_CHAR
;
1923 p_error
= parse_comma_expected_error
;
1925 case close_paren_token
:
1926 match
= c
== CLOSE_PAREN_CHAR
;
1928 p_error
= parse_close_paren_expected_error
;
1936 while (s
< end_s
&& is_whitespace(*s
))
1945 * FUNCTION: get_next_extract_format_item
1947 * Get the next format token from the string. Note that
1948 * get_next_extract_format_item may change the input string.
1950 * RETURN VALUE: NULL if error
1951 * position of beginning next token after
1954 * INPUT: the format string
1958 get_next_extract_format_item(
1959 const char *begin_fmt
,
1960 const char *end_fmt
,
1961 __nis_mapping_format_t
*fmt
)
1963 const char *s
= begin_fmt
;
1964 const char *s_end
= end_fmt
;
1974 for (; p_error
== no_parse_error
; ) {
1978 if (*s
== PERCENT_SIGN
) {
1981 * If the format is %s, it is interpreted
1985 p_error
= parse_unsupported_format
;
1991 fmt
->type
= mmt_item
;
1993 case 'n': /* null */
1994 case 'x': /* skip the next element */
1997 case 'b': /* boolean */
1998 case 'e': /* enumerated */
2000 case 'o': /* octet string */
2001 case 'B': /* bit string */
2002 fmt
->match
.berString
= s_strndup(s
, 1);
2003 fmt
->type
= skip_ber
?
2004 mmt_berstring_null
:
2007 case 'a': /* octet string */
2009 fmt
->match
.berString
=
2011 fmt
->type
= skip_ber
?
2012 mmt_berstring_null
:
2015 } /* else FALLTHRU */
2016 case '{': /* begin sequence */
2017 case '[': /* begin set */
2018 case '}': /* end sequence */
2019 case ']': /* end set */
2020 case 'l': /* length of next item */
2021 case 'O': /* octet string */
2022 case 't': /* tag of next item */
2023 case 'T': /* skip tag of next item */
2024 case 'v': /* seq of strings */
2025 case 'V': /* seq of strings + lengths */
2027 p_error
= parse_bad_ber_format
;
2031 } else if (*s
== ASTERIX_CHAR
) {
2032 fmt
->type
= mmt_any
;
2034 while (s
< s_end
&& *s
== ASTERIX_CHAR
)
2037 } else if (*s
== OPEN_BRACKET
) {
2044 for (; s
< s_end
; s
++) {
2047 } else if (*s
== DASH_CHAR
) {
2048 if (in_range
|| !got_char
) {
2049 p_error
= parse_unexpected_dash
;
2055 } else if (*s
== CLOSE_BRACKET
) {
2057 p_error
= parse_unexpected_dash
;
2061 } else if (*s
== ESCAPE_CHAR
) {
2066 hi
[numRange
- 1] = *s
;
2069 lo
= s_realloc(lo
, numRange
+ 1);
2070 hi
= s_realloc(hi
, numRange
+ 1);
2071 if (lo
== NULL
|| hi
== NULL
)
2079 if (p_error
!= no_parse_error
) {
2082 p_error
= parse_mismatched_brackets
;
2086 fmt
->type
= mmt_single
;
2087 fmt
->match
.single
.numRange
= numRange
;
2088 fmt
->match
.single
.lo
= (unsigned char *)lo
;
2089 fmt
->match
.single
.hi
= (unsigned char *)hi
;
2091 /* go to next key symbol - copy escaped key symbols */
2116 p_error
= parse_unmatched_escape
;
2119 fmt
->type
= mmt_string
;
2121 s_strndup_esc(begin_fmt
, s
- begin_fmt
);
2122 if (fmt
->match
.string
== NULL
)
2126 if (p_error
== no_parse_error
)
2135 * FUNCTION: get_next_print_format_item
2137 * Get the next format token from the string
2139 * RETURN VALUE: NULL if error
2140 * position of beginning next token after
2143 * INPUT: the format string
2147 get_next_print_format_item(
2148 const char *begin_fmt
,
2149 const char *end_fmt
,
2150 __nis_mapping_format_t
*fmt
)
2152 const char *s
= begin_fmt
;
2153 const char *s_end
= end_fmt
;
2156 for (; p_error
== no_parse_error
; ) {
2158 p_error
= parse_internal_error
;
2162 if (*s
== PERCENT_SIGN
) {
2165 p_error
= parse_unsupported_format
;
2170 * If the format is %s, it is interpretted
2175 fmt
->type
= mmt_item
;
2177 case 'n': /* null */
2178 case 'x': /* skip the next element */
2181 case 'b': /* boolean */
2182 case 'e': /* enumerated */
2184 case 'o': /* octet string */
2185 case 'B': /* bit string */
2186 fmt
->match
.berString
= s_strndup(s
, 1);
2187 fmt
->type
= skip_ber
?
2188 mmt_berstring_null
:
2191 case '{': /* begin sequence */
2192 case '[': /* begin set */
2193 case '}': /* end sequence */
2194 case ']': /* end set */
2195 case 'a': /* octet string */
2196 case 'l': /* length of next item */
2197 case 'O': /* octet string */
2198 case 't': /* tag of next item */
2199 case 'T': /* skip tag of next item */
2200 case 'v': /* seq of strings */
2201 case 'V': /* seq of strings + lengths */
2203 p_error
= parse_bad_ber_format
;
2209 if (*s
== PERCENT_SIGN
)
2211 else if (*s
== ESCAPE_CHAR
)
2216 p_error
= parse_unmatched_escape
;
2220 s_strndup_esc(begin_fmt
, s
- begin_fmt
);
2221 if (fmt
->match
.string
== NULL
)
2223 fmt
->type
= mmt_string
;
2225 if (p_error
== no_parse_error
)
2232 * FUNCTION: get_ldap_filter
2234 * Gets an LDAP filter - see RFC 2254. Note that this does not
2235 * determine if the ldap filter is valid. This only determines
2236 * that the parentheses are balanced.
2238 * RETURN VALUE: NULL if error
2239 * position of beginning next token after
2242 * INPUT: the begin and end of string
2244 * OUTPUT: the begin and end of LDAP filter
2249 get_ldap_filter(const char **begin
, const char **end
)
2251 const char *s
= *begin
;
2252 const char *s_begin
;
2253 const char *s_end
= *end
;
2256 for (; p_error
== no_parse_error
; ) {
2257 while (s
< s_end
&& is_whitespace(*s
))
2265 if (*s
== OPEN_PAREN_CHAR
) {
2268 while (s
< s_end
&& nParen
> 0) {
2269 if (*s
== ESCAPE_CHAR
)
2271 else if (*s
== OPEN_PAREN_CHAR
)
2273 else if (*s
== CLOSE_PAREN_CHAR
)
2280 while (s
< s_end
&& is_whitespace(*s
))
2286 if (p_error
== no_parse_error
)
2290 p_error
= parse_invalid_ldap_search_filter
;
2296 * FUNCTION: get_ava_list
2298 * Gets an attribute value assertion list
2300 * RETURN VALUE: NULL if error
2301 * position of beginning next token after
2302 * after attribute assertion
2304 * INPUT: the begin and end of string
2305 * Indicator if ava list is part of a nisplus
2308 * OUTPUT: the begin and end of LDAP filter
2313 get_ava_list(const char **begin
, const char **end
, bool_t end_nisplus
)
2315 const char *s
= *begin
;
2316 const char *s_begin
;
2317 const char *s_end
= *end
;
2322 for (; p_error
== no_parse_error
; ) {
2323 while (s
< s_end
&& is_whitespace(*s
))
2335 if (*s
== ESCAPE_CHAR
) {
2338 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
2339 in_quote
= !in_quote
;
2341 } else if (in_quote
)
2343 else if (*s
== EQUAL_CHAR
) {
2344 if (end_nisplus
&& got_data
&& got_equal
)
2346 if (!got_data
|| got_equal
) {
2352 } else if (*s
== COMMA_CHAR
) {
2353 if (!got_data
|| !got_equal
)
2357 } else if (is_whitespace(*s
))
2363 if (!got_data
|| !got_equal
|| in_quote
)
2368 while (s
< s_end
&& is_whitespace(*s
))
2371 if (p_error
== no_parse_error
)
2375 p_error
= parse_invalid_ldap_search_filter
;
2380 /* Utility functions */
2382 validate_dn(const char *s
, int len
)
2384 const char *end
= s
+ len
;
2387 valid
= skip_get_dn(s
, end
) == end
;
2390 p_error
= parse_bad_dn
;
2395 validate_ldap_filter(const char *s
, const char *end
)
2397 const char *s_begin
;
2403 if (*s
== OPEN_PAREN_CHAR
) {
2404 s
= get_ldap_filter(&s_begin
, &s_end
);
2406 /* Assume an attribute value list */
2407 s
= get_ava_list(&s_begin
, &s_end
, FALSE
);
2409 if (s
== NULL
|| s_end
!= end
)
2410 p_error
= parse_invalid_ldap_search_filter
;
2412 return (p_error
== no_parse_error
);
2416 s_strndup(const char *s
, int n
)
2418 char *d
= (char *)malloc(n
+ 1);
2421 (void) memcpy(d
, s
, n
);
2424 p_error
= parse_no_mem_error
;
2431 s_strndup_esc(const char *s
, int n
)
2433 char *d
= (char *)malloc(n
+ 1);
2438 for (i
= 0, j
= 0; i
< n
; i
++) {
2439 if (s
[i
] == ESCAPE_CHAR
)
2445 p_error
= parse_no_mem_error
;
2452 s_calloc(size_t n
, size_t size
)
2454 void *d
= (char *)calloc(n
, size
);
2457 p_error
= parse_no_mem_error
;
2464 s_malloc(size_t size
)
2466 void *d
= malloc(size
);
2468 p_error
= parse_no_mem_error
;
2473 s_realloc(void *s
, size_t size
)
2475 s
= realloc(s
, size
);
2477 p_error
= parse_no_mem_error
;
2482 s_strdup(const char *s
)
2484 return (s
!= NULL
? s_strndup(s
, strlen(s
)) : NULL
);
2488 is_whitespace(int c
)
2490 return (c
== ' ' || c
== '\t');
2494 is_string_ok(char *buffer
, int buflen
)
2501 for (i
= 0; i
< buflen
; i
++) {
2502 if (!is_whitespace(buffer
[i
])) {
2503 if (buffer
[i
] == POUND_SIGN
)
2513 * Returns true if the first string is contained at the beginning of the
2514 * second string. Otherwise returns false.
2518 contains_string(const char *s1
, const char *s2
)
2520 return (strncasecmp(s1
, s2
, strlen(s1
)) == 0);
2524 * Returns the next character position in the second string, if the first
2525 * string is contained at the beginning of the second string. Otherwise
2530 skip_string(const char *s1
, const char *s2
, int len
)
2532 int len1
= strlen(s1
);
2534 if (len
>= len1
&& strncasecmp(s1
, s2
, strlen(s1
)) == 0)
2541 * The second string is not necessarily null terminated.
2542 * same_string returns true if the second string matches the first.
2543 * Otherwise returns false.
2547 same_string(const char *s1
, const char *s2
, int len
)
2549 int len1
= strlen(s1
);
2551 return (len1
== len
&& strncasecmp(s1
, s2
, len1
) == 0);
2555 report_error(const char *str
, const char *attr
)
2560 if (command_line_source
!= NULL
) {
2561 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error parsing %s: ",
2562 command_line_source
);
2563 pos
= strlen(fmt_buf
);
2564 } else if (file_source
!= NULL
) {
2565 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error parsing file '%s': ",
2567 pos
= strlen(fmt_buf
);
2568 } else if (ldap_source
!= NULL
) {
2569 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error for LDAP dn '%s': ",
2571 pos
= strlen(fmt_buf
);
2574 if (start_line_num
!= 0) {
2575 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "at line %d: ",
2577 pos
+= strlen(fmt_buf
+ pos
);
2581 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
,
2582 "for attribute %s: ", attr
);
2583 pos
+= strlen(fmt_buf
+ pos
);
2587 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "%s\n",
2588 parse_error_msg
[p_error
]);
2589 fprintf(cons
, fmt_buf
, str
== NULL
? "" : str
);
2591 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "%s",
2592 parse_error_msg
[p_error
]);
2593 syslog(LOG_ERR
, fmt_buf
, str
== NULL
? "" : str
);
2605 snprintf(fmt_buf
, sizeof (fmt_buf
),
2606 "%s\n", parse_error_msg
[p_error
]);
2607 fprintf(cons
, fmt_buf
, str1
, str2
);
2609 syslog(LOG_ERR
, parse_error_msg
[p_error
], str1
, str2
);
2622 snprintf(fmt_buf
, sizeof (fmt_buf
),
2623 "%s\n", conn_error_msg
[e
]);
2624 fprintf(cons
, fmt_buf
,
2625 str1
== NULL
? "" : str1
,
2626 str2
== NULL
? "" : str2
);
2630 str1
== NULL
? "" : str1
,
2631 str2
== NULL
? "" : str2
);
2646 syslog(LOG_INFO
, str
, arg
);