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
]);
171 if (r
->element
!= NULL
)
175 for (i
= 0; i
< r
->numElements
; i
++)
176 free_mapping_element(&r
->element
[i
]);
177 if (r
->element
!= NULL
)
185 * FUNCTION: free_mapping_element
187 * Frees __nis_mapping_element_t
189 * INPUT: __nis_mapping_element_t
193 free_mapping_element(__nis_mapping_element_t
*e
)
202 free_mapping_item(&e
->element
.item
);
205 if (e
->element
.print
.fmt
!= NULL
)
206 free_mapping_format(e
->element
.print
.fmt
);
207 e
->element
.print
.fmt
= NULL
;
208 for (i
= 0; i
< e
->element
.print
.numSubElements
; i
++)
209 free_mapping_sub_element(
210 &e
->element
.print
.subElement
[i
]);
211 e
->element
.print
.numSubElements
= 0;
212 if (e
->element
.print
.subElement
!= NULL
)
213 free(e
->element
.print
.subElement
);
214 e
->element
.print
.subElement
= NULL
;
217 free_mapping_item(&e
->element
.split
.item
);
220 if (e
->element
.match
.fmt
!= NULL
)
221 free_mapping_format(e
->element
.match
.fmt
);
222 e
->element
.match
.fmt
= NULL
;
223 for (i
= 0; i
< e
->element
.match
.numItems
; i
++)
224 free_mapping_item(&e
->element
.match
.item
[i
]);
225 e
->element
.match
.numItems
= 0;
226 if (e
->element
.match
.item
!= NULL
)
227 free(e
->element
.match
.item
);
228 e
->element
.match
.item
= NULL
;
231 if (e
->element
.extract
.fmt
!= NULL
)
232 free_mapping_format(e
->element
.extract
.fmt
);
233 e
->element
.extract
.fmt
= NULL
;
234 free_mapping_item(&e
->element
.extract
.item
);
241 * FUNCTION: free_table_mapping
243 * Frees __nis_table_mapping_t
245 * INPUT: __nis_table_mapping_t
249 * free_table_mapping does not remove the table mapping from
254 free_table_mapping(__nis_table_mapping_t
*mapping
)
261 if (mapping
->dbId
!= NULL
)
263 mapping
->dbId
= NULL
;
265 if (mapping
->objName
!= NULL
)
266 free(mapping
->objName
);
267 mapping
->objName
= NULL
;
269 for (i
= 0; i
< mapping
->index
.numIndexes
; i
++) {
270 free(mapping
->index
.name
[i
]);
271 free_mapping_format(mapping
->index
.value
[i
]);
274 if (mapping
->index
.name
!= NULL
)
275 free(mapping
->index
.name
);
276 mapping
->index
.name
= NULL
;
278 if (mapping
->index
.value
!= NULL
)
279 free(mapping
->index
.value
);
280 mapping
->index
.value
= NULL
;
282 mapping
->index
.numIndexes
= 0;
284 if (mapping
->column
!= NULL
) {
285 for (i
= 0; i
< mapping
->numColumns
; i
++) {
286 free(mapping
->column
[i
]);
288 mapping
->numColumns
= 0;
289 free(mapping
->column
);
290 mapping
->column
= NULL
;
293 if (mapping
->commentChar
!= NULL
)
294 mapping
->commentChar
= NULL
;
296 if (mapping
->objectDN
!= NULL
)
297 free_object_dn(mapping
->objectDN
);
298 mapping
->objectDN
= NULL
;
300 if (mapping
->separatorStr
!= NULL
)
301 mapping
->separatorStr
= NULL
;
303 for (i
= 0; i
< mapping
->numRulesFromLDAP
; i
++) {
304 if (mapping
->ruleFromLDAP
[i
]) /* See Comment below */
305 free_mapping_rule(mapping
->ruleFromLDAP
[i
]);
307 mapping
->numRulesFromLDAP
= 0;
309 if (mapping
->ruleFromLDAP
!= NULL
)
310 free(mapping
->ruleFromLDAP
);
311 mapping
->ruleFromLDAP
= NULL
;
313 for (i
= 0; i
< mapping
->numRulesToLDAP
; i
++) {
314 if (mapping
->ruleToLDAP
[i
])
316 * Normally mapping->ruleToLDAP[i] should
317 * always be non-null if
318 * mapping->numRulesToLDAP is > 0.
319 * However it is possible to have data
320 * corruption where numRulesToLDAP gets
321 * some integer value even though no real
322 * data is present in mapping->ruleToLDAP.
324 free_mapping_rule(mapping
->ruleToLDAP
[i
]);
326 mapping
->numRulesToLDAP
= 0;
328 if (mapping
->ruleToLDAP
!= NULL
)
329 free(mapping
->ruleToLDAP
);
330 mapping
->ruleToLDAP
= NULL
;
332 if (mapping
->e
!= NULL
) {
333 /* Similar logic as in above comment applies. */
334 for (i
= 0; i
<= mapping
->numSplits
; i
++) {
335 free_mapping_element(&mapping
->e
[i
]);
341 mapping
->numSplits
= 0;
347 * FUNCTION: free_config_info
349 * Frees __nis_config_info_t
351 * INPUT: __nis_config_info_t
355 free_config_info(__nis_config_info_t
*config_info
)
357 if (config_info
->config_dn
!= NULL
)
358 free(config_info
->config_dn
);
359 config_info
->config_dn
= NULL
;
361 if (config_info
->default_servers
!= NULL
)
362 free(config_info
->default_servers
);
363 config_info
->default_servers
= NULL
;
365 if (config_info
->proxy_dn
!= NULL
)
366 free(config_info
->proxy_dn
);
367 config_info
->proxy_dn
= NULL
;
369 if (config_info
->proxy_passwd
!= NULL
)
370 free(config_info
->proxy_passwd
);
371 config_info
->proxy_passwd
= NULL
;
373 if (config_info
->tls_cert_db
!= NULL
)
374 free(config_info
->tls_cert_db
);
375 config_info
->tls_cert_db
= NULL
;
379 * FUNCTION: free_proxy_info
381 * Frees __nis_ldap_proxy_info
383 * INPUT: __nis_ldap_proxy_info
387 free_proxy_info(__nis_ldap_proxy_info
*proxy_info
)
389 if (proxy_info
->tls_cert_db
!= NULL
)
390 free(proxy_info
->tls_cert_db
);
391 proxy_info
->tls_cert_db
= NULL
;
393 if (proxy_info
->default_servers
!= NULL
)
394 free(proxy_info
->default_servers
);
395 proxy_info
->default_servers
= NULL
;
397 if (proxy_info
->default_search_base
!= NULL
)
398 free(proxy_info
->default_search_base
);
399 proxy_info
->default_search_base
= NULL
;
401 if (proxy_info
->proxy_dn
!= NULL
)
402 free(proxy_info
->proxy_dn
);
403 proxy_info
->proxy_dn
= NULL
;
405 if (proxy_info
->proxy_passwd
!= NULL
)
406 free(proxy_info
->proxy_passwd
);
407 proxy_info
->proxy_passwd
= NULL
;
409 if (proxy_info
->default_nis_domain
!= NULL
)
410 free(proxy_info
->default_nis_domain
);
411 proxy_info
->default_nis_domain
= NULL
;
415 * FUNCTION: free_object_dn
417 * Frees __nis_object_dn_t
419 * INPUT: __nis_object_dn_t
423 free_object_dn(__nis_object_dn_t
*obj_dn
)
425 __nis_object_dn_t
*t
;
428 while (obj_dn
!= NULL
) {
429 if (obj_dn
->read
.base
!= NULL
)
430 free(obj_dn
->read
.base
);
431 obj_dn
->read
.base
= NULL
;
432 if (obj_dn
->read
.attrs
!= NULL
)
433 free(obj_dn
->read
.attrs
);
434 obj_dn
->read
.attrs
= NULL
;
435 if (obj_dn
->write
.base
!= NULL
)
436 free(obj_dn
->write
.base
);
437 obj_dn
->write
.base
= NULL
;
438 if (obj_dn
->write
.attrs
!= NULL
)
439 free(obj_dn
->write
.attrs
);
440 obj_dn
->write
.attrs
= NULL
;
441 if (obj_dn
->dbIdName
!= NULL
)
442 free(obj_dn
->dbIdName
);
443 obj_dn
->dbIdName
= NULL
;
444 for (i
= 0; i
< obj_dn
->numDbIds
; i
++)
445 free_mapping_rule(obj_dn
->dbId
[i
]);
446 obj_dn
->numDbIds
= 0;
448 if (obj_dn
->dbId
!= NULL
)
453 obj_dn
= obj_dn
->next
;
459 * FUNCTION: free_index
461 * Frees __nis_index_t
463 * INPUT: __nis_index_t
467 free_index(__nis_index_t
*index
)
470 for (i
= 0; i
< index
->numIndexes
; i
++) {
471 free(index
->name
[i
]);
472 free_mapping_format(index
->value
[i
]);
474 index
->numIndexes
= 0;
475 if (index
->name
!= NULL
)
478 if (index
->value
!= NULL
)
484 * FUNCTION: free_mapping_item
486 * Frees __nis_mapping_item_t
488 * INPUT: __nis_mapping_item_t
492 free_mapping_item(__nis_mapping_item_t
*item
)
497 if (item
->name
!= NULL
)
500 if (item
->type
== mit_nisplus
) {
501 free_index(&item
->searchSpec
.obj
.index
);
502 if (item
->searchSpec
.obj
.name
!= NULL
)
503 free(item
->searchSpec
.obj
.name
);
504 item
->searchSpec
.obj
.name
= NULL
;
505 } else if (item
->type
== mit_ldap
) {
506 if (item
->searchSpec
.triple
.base
!= NULL
)
507 free(item
->searchSpec
.triple
.base
);
508 item
->searchSpec
.triple
.base
= NULL
;
509 if (item
->searchSpec
.triple
.attrs
!= NULL
)
510 free(item
->searchSpec
.triple
.attrs
);
511 item
->searchSpec
.triple
.attrs
= NULL
;
512 if (item
->searchSpec
.triple
.element
!= NULL
) {
513 free_mapping_element(
514 item
->searchSpec
.triple
.element
);
515 free(item
->searchSpec
.triple
.element
);
517 item
->searchSpec
.triple
.element
= NULL
;
519 if (item
->exItem
!= NULL
) {
520 free_mapping_item(item
->exItem
);
527 * FUNCTION: free_mapping_format
529 * Frees __nis_mapping_format_t
531 * INPUT: __nis_mapping_format_t
535 free_mapping_format(__nis_mapping_format_t
*fmt
)
537 __nis_mapping_format_t
*f
= fmt
;
539 while (fmt
->type
!= mmt_end
) {
544 if (fmt
->match
.string
!= NULL
)
545 free(fmt
->match
.string
);
546 fmt
->match
.string
= NULL
;
549 if (fmt
->match
.single
.lo
!= NULL
)
550 free(fmt
->match
.single
.lo
);
551 fmt
->match
.single
.lo
= NULL
;
552 if (fmt
->match
.single
.hi
!= NULL
)
553 free(fmt
->match
.single
.hi
);
554 fmt
->match
.single
.hi
= NULL
;
561 case mmt_berstring_null
:
562 if (fmt
->match
.berString
!= NULL
)
563 free(fmt
->match
.berString
);
564 fmt
->match
.berString
= NULL
;
577 * FUNCTION: free_mapping_sub_element
579 * Frees __nis_mapping_sub_element_t
581 * INPUT: __nis_mapping_sub_element_t
585 free_mapping_sub_element(__nis_mapping_sub_element_t
*sub
)
591 free_mapping_item(&sub
->element
.item
);
594 if (sub
->element
.print
.fmt
!= NULL
)
595 free_mapping_format(sub
->element
.print
.fmt
);
596 sub
->element
.print
.fmt
= NULL
;
597 for (i
= 0; i
< sub
->element
.print
.numItems
; i
++)
598 free_mapping_item(&sub
->element
.print
.item
[i
]);
599 sub
->element
.print
.numItems
= 0;
600 if (sub
->element
.print
.item
!= NULL
)
601 free(sub
->element
.print
.item
);
602 sub
->element
.print
.item
= NULL
;
605 free_mapping_item(&sub
->element
.split
.item
);
608 if (sub
->element
.extract
.fmt
!= NULL
)
609 free_mapping_format(sub
->element
.extract
.fmt
);
610 sub
->element
.extract
.fmt
= NULL
;
611 free_mapping_item(&sub
->element
.extract
.item
);
617 * FUNCTION: read_line
619 * Gets next line in buffer - using '\' at end of line
620 * to indicate continuation. Lines beginning with # are
621 * ignored. start_line_num and start_line_num are
622 * maintained to track the line number currently being
625 * RETURN VALUE: The number of characters read. 0 for
628 * INPUT: file descriptor, buffer, and buffer size
632 read_line(int fd
, char *buffer
, int buflen
)
637 bool_t skip_line
= FALSE
;
638 bool_t begin_line
= TRUE
;
639 static bool_t prev_cr
= FALSE
;
641 start_line_num
= cur_line_num
;
642 (void) memset(buffer
, 0, buflen
);
643 for (; p_error
== no_parse_error
; ) {
645 while (linelen
< buflen
) {
646 rc
= read(fd
, &c
, 1);
648 if (c
== '\n' || c
== '\r') {
687 } else if (linelen
> 0 &&
691 } else if (linelen
> 0) {
692 buffer
[linelen
] = '\0';
698 skip_line
= c
== POUND_SIGN
;
701 buffer
[linelen
++] = c
;
705 buffer
[linelen
- 1] == ESCAPE_CHAR
) {
706 /* continuation on last line */
707 p_error
= parse_bad_continuation_error
;
710 buffer
[linelen
] = '\0';
715 p_error
= parse_line_too_long
;
721 * FUNCTION: finish_parse
723 * Adds any elements not configured, fully qualifies
726 * RETURN VALUE: 0 on success, -1 on failure
731 __nis_ldap_proxy_info
*proxy_info
,
732 __nis_table_mapping_t
**table_mapping
)
734 __nis_table_mapping_t
*t
;
735 __nis_table_mapping_t
*t1
;
736 __nis_table_mapping_t
*t2
;
737 __nis_table_mapping_t
*t_del
= NULL
;
741 __nis_object_dn_t
*objectDN
;
742 __nis_mapping_rlhs_t
*lhs
;
743 __nis_mapping_element_t
*e
;
747 /* set to default those values yet set */
748 if (proxy_info
->auth_method
==
749 (auth_method_t
)NO_VALUE_SET
) {
750 p_error
= parse_no_proxy_auth_error
;
751 report_error(NULL
, NULL
);
755 if (proxy_info
->default_servers
== NULL
) {
756 p_error
= parse_no_ldap_server_error
;
757 report_error(NULL
, NULL
);
761 if (proxy_info
->tls_method
== (tls_method_t
)NO_VALUE_SET
)
762 proxy_info
->tls_method
= no_tls
;
763 else if (proxy_info
->tls_method
== ssl_tls
&&
764 (proxy_info
->tls_cert_db
== NULL
||
765 *proxy_info
->tls_cert_db
== '\0')) {
766 p_error
= parse_no_cert_db
;
767 report_error(NULL
, NULL
);
771 if (proxy_info
->default_nis_domain
== NULL
)
772 proxy_info
->default_nis_domain
=
773 s_strdup(__nis_rpc_domain());
774 else if (*proxy_info
->default_nis_domain
== '\0') {
775 free(proxy_info
->default_nis_domain
);
776 proxy_info
->default_nis_domain
=
777 s_strdup(__nis_rpc_domain());
779 if (proxy_info
->default_nis_domain
!= NULL
)
780 append_dot(&proxy_info
->default_nis_domain
);
782 if (proxy_info
->tls_method
== ssl_tls
) {
783 if ((errnum
= ldapssl_client_init(
784 proxy_info
->tls_cert_db
, NULL
)) < 0) {
785 p_error
= parse_ldapssl_client_init_error
;
786 report_error(ldapssl_err2string(errnum
), NULL
);
791 if (proxy_info
->default_search_base
== NULL
)
792 proxy_info
->default_search_base
=
793 get_default_ldap_base(proxy_info
->default_nis_domain
);
795 /* convert a relative dn to a fullly qualified dn */
796 (void) make_full_dn(&proxy_info
->proxy_dn
,
797 proxy_info
->default_search_base
);
799 if (p_error
!= no_parse_error
) {
800 report_error(NULL
, NULL
);
805 * Create a list of potential delete mappings
806 * those have NULL objectDNs, but badly also rules
807 * that are missing object dn's will be included.
808 * We will use the ttl field to determine if the
809 * delete rule is actually used
812 for (t
= *table_mapping
; t
!= NULL
; t
= t1
) {
814 if (t
->objectDN
== NULL
) {
826 for (t
= *table_mapping
; t
!= NULL
; t
= t
->next
) {
827 objectDN
= t
->objectDN
;
828 while (objectDN
!= NULL
) {
829 if (objectDN
->dbIdName
!= NULL
) {
830 s
= objectDN
->dbIdName
;
831 t1
= find_table_mapping(s
, strlen(s
), t_del
);
833 p_error
= parse_no_db_del_mapping_rule
;
834 report_error2(objectDN
->dbIdName
, t
->dbId
);
836 } else if (t1
->objName
!= NULL
||
837 t1
->numRulesToLDAP
== 0 ||
838 t1
->numRulesFromLDAP
!= 0) {
839 p_error
= parse_invalid_db_del_mapping_rule
;
840 report_error(t1
->dbId
, NULL
);
844 dup_mapping_rules(t1
->ruleToLDAP
,
846 if (objectDN
->dbId
== NULL
) {
849 objectDN
->numDbIds
= t1
->numRulesToLDAP
;
852 objectDN
= objectDN
->next
;
856 for (t
= t_del
; t
!= NULL
; t
= t1
) {
859 p_error
= parse_no_object_dn
;
860 report_error(t
->dbId
, NULL
);
862 free_table_mapping(t
);
865 if (p_error
!= no_parse_error
)
868 /* set to default those table mapping values yet set */
869 for (t
= *table_mapping
; t
!= NULL
; t
= t
->next
) {
870 if (t
->objName
== 0) {
871 p_error
= parse_no_object_dn
;
872 report_error(t
->dbId
, NULL
);
876 if (!add_domain(&t
->objName
,
877 proxy_info
->default_nis_domain
)) {
878 report_error(NULL
, NULL
);
882 if (t
->initTtlHi
== (time_t)NO_VALUE_SET
)
883 t
->initTtlHi
= DEFAULT_TTL_HIGH
;
884 if (t
->initTtlLo
== (time_t)NO_VALUE_SET
)
885 t
->initTtlLo
= DEFAULT_TTL_LOW
;
886 if (t
->ttl
== (time_t)NO_VALUE_SET
)
887 t
->ttl
= DEFAULT_TTL
;
888 objectDN
= t
->objectDN
;
890 /* fixup relative dn's */
891 while (objectDN
!= NULL
) {
893 if (!make_full_dn(&objectDN
->read
.base
,
894 proxy_info
->default_search_base
))
897 if (objectDN
->write
.scope
!= LDAP_SCOPE_UNKNOWN
) {
898 if (objectDN
->write
.base
!= NULL
&&
899 !make_full_dn(&objectDN
->write
.base
,
900 proxy_info
->default_search_base
))
902 if (objectDN
->write
.base
== NULL
) {
903 objectDN
->write
.base
=
904 s_strdup(objectDN
->read
.base
);
905 if (objectDN
->write
.base
== NULL
)
909 objectDN
= objectDN
->next
;
912 if (p_error
!= no_parse_error
) {
913 report_error(NULL
, NULL
);
917 /* Check for ruleToLDAP with no rhs */
918 for (i
= 0; i
< t
->numRulesToLDAP
; i
++) {
919 if (t
->ruleToLDAP
[i
]->rhs
.numElements
== 0) {
920 p_error
= parse_unexpected_data_end_rule
;
921 report_error(t
->dbId
, NULL
);
926 /* populate cols field */
928 for (i
= 0; i
< t
->numRulesFromLDAP
; i
++) {
929 lhs
= &t
->ruleFromLDAP
[i
]->lhs
;
930 for (j
= 0; j
< lhs
->numElements
; j
++) {
931 e
= &lhs
->element
[j
];
935 e
->element
.item
.name
)) {
943 k
< e
->element
.match
.numItems
;
946 e
->element
.match
.item
[k
].name
)) {
961 * FUNCTION: set_default_values
963 * Sets unconfigured values to their default value
967 set_default_values(__nis_ldap_proxy_info
*proxy_info
,
968 __nis_config_t
*config_info
, __nisdb_table_mapping_t
*table_info
)
970 if (proxy_info
->bind_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
971 proxy_info
->bind_timeout
.tv_sec
= DEFAULT_BIND_TIMEOUT
;
972 if (proxy_info
->search_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
973 proxy_info
->search_timeout
.tv_sec
=
974 (yp2ldap
)?DEFAULT_YP_SEARCH_TIMEOUT
:
975 DEFAULT_SEARCH_TIMEOUT
;
976 if (proxy_info
->modify_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
977 proxy_info
->modify_timeout
.tv_sec
= DEFAULT_MODIFY_TIMEOUT
;
978 if (proxy_info
->add_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
979 proxy_info
->add_timeout
.tv_sec
= DEFAULT_ADD_TIMEOUT
;
980 if (proxy_info
->delete_timeout
.tv_sec
== (time_t)NO_VALUE_SET
)
981 proxy_info
->delete_timeout
.tv_sec
= DEFAULT_DELETE_TIMEOUT
;
983 if (proxy_info
->search_time_limit
== (int)NO_VALUE_SET
)
984 proxy_info
->search_time_limit
= DEFAULT_SEARCH_TIME_LIMIT
;
985 if (proxy_info
->search_size_limit
== (int)NO_VALUE_SET
)
986 proxy_info
->search_size_limit
= DEFAULT_SEARCH_SIZE_LIMIT
;
988 if (proxy_info
->follow_referral
== (follow_referral_t
)NO_VALUE_SET
)
989 proxy_info
->follow_referral
= no_follow
;
991 switch (config_info
->initialUpdate
) {
992 case (__nis_initial_update_t
)NO_VALUE_SET
:
993 case (__nis_initial_update_t
)INITIAL_UPDATE_NO_ACTION
:
994 case (__nis_initial_update_t
)NO_INITIAL_UPDATE_NO_ACTION
:
995 config_info
->initialUpdate
= ini_none
;
997 case (__nis_initial_update_t
)FROM_NO_INITIAL_UPDATE
:
998 config_info
->initialUpdate
= from_ldap
;
1000 case (__nis_initial_update_t
)TO_NO_INITIAL_UPDATE
:
1001 config_info
->initialUpdate
= to_ldap
;
1004 if (config_info
->threadCreationError
==
1005 (__nis_thread_creation_error_t
)NO_VALUE_SET
)
1006 config_info
->threadCreationError
= pass_error
;
1007 if (config_info
->threadCreationErrorTimeout
.attempts
== NO_VALUE_SET
)
1008 config_info
->threadCreationErrorTimeout
.attempts
=
1009 DEFAULT_THREAD_ERROR_ATTEMPTS
;
1010 if (config_info
->threadCreationErrorTimeout
.timeout
==
1011 (time_t)NO_VALUE_SET
)
1012 config_info
->threadCreationErrorTimeout
.timeout
=
1013 DEFAULT_THREAD_ERROR_TIME_OUT
;
1014 if (config_info
->dumpError
==
1015 (__nis_dump_error_t
)NO_VALUE_SET
)
1016 config_info
->dumpError
= de_retry
;
1017 if (config_info
->dumpErrorTimeout
.attempts
== NO_VALUE_SET
)
1018 config_info
->dumpErrorTimeout
.attempts
=
1019 DEFAULT_DUMP_ERROR_ATTEMPTS
;
1020 if (config_info
->dumpErrorTimeout
.timeout
== (time_t)NO_VALUE_SET
)
1021 config_info
->dumpErrorTimeout
.timeout
=
1022 DEFAULT_DUMP_ERROR_TIME_OUT
;
1023 if (config_info
->resyncService
==
1024 (__nis_resync_service_t
)NO_VALUE_SET
)
1025 config_info
->resyncService
= from_copy
;
1026 if (config_info
->updateBatching
==
1027 (__nis_update_batching_t
)NO_VALUE_SET
)
1028 config_info
->updateBatching
= accumulate
;
1029 if (config_info
->updateBatchingTimeout
.timeout
== (time_t)NO_VALUE_SET
)
1030 config_info
->updateBatchingTimeout
.timeout
=
1031 DEFAULT_BATCHING_TIME_OUT
;
1032 if (config_info
->numberOfServiceThreads
== (int)NO_VALUE_SET
)
1033 config_info
->numberOfServiceThreads
=
1034 DEFAULT_NUMBER_OF_THREADS
;
1035 if (config_info
->emulate_yp
== (int)NO_VALUE_SET
)
1036 config_info
->emulate_yp
=
1037 DEFAULT_YP_EMULATION
;
1038 if (config_info
->maxRPCRecordSize
== (int)NO_VALUE_SET
)
1039 config_info
->maxRPCRecordSize
= RPC_MAXDATASIZE
;
1041 if (table_info
->retrieveError
==
1042 (__nis_retrieve_error_t
)NO_VALUE_SET
)
1043 table_info
->retrieveError
= use_cached
;
1044 if (table_info
->retrieveErrorRetry
.attempts
== NO_VALUE_SET
)
1045 table_info
->retrieveErrorRetry
.attempts
=
1046 DEFAULT_RETRIEVE_ERROR_ATTEMPTS
;
1047 if (table_info
->retrieveErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1048 table_info
->retrieveErrorRetry
.timeout
=
1049 DEFAULT_RETRIEVE_ERROR_TIME_OUT
;
1050 if (table_info
->storeError
==
1051 (__nis_store_error_t
)NO_VALUE_SET
)
1052 table_info
->storeError
= sto_retry
;
1053 if (table_info
->storeErrorRetry
.attempts
== NO_VALUE_SET
)
1054 table_info
->storeErrorRetry
.attempts
=
1055 DEFAULT_STORE_ERROR_ATTEMPTS
;
1056 if (table_info
->storeErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1057 table_info
->storeErrorRetry
.timeout
=
1058 DEFAULT_STORE_ERROR_TIME_OUT
;
1059 if (table_info
->refreshError
==
1060 (__nis_refresh_error_t
)NO_VALUE_SET
)
1061 table_info
->refreshError
= continue_using
;
1062 if (table_info
->refreshErrorRetry
.attempts
== NO_VALUE_SET
)
1063 table_info
->refreshErrorRetry
.attempts
=
1064 DEFAULT_REFRESH_ERROR_ATTEMPTS
;
1065 if (table_info
->refreshErrorRetry
.timeout
== (time_t)NO_VALUE_SET
)
1066 table_info
->refreshErrorRetry
.timeout
=
1067 DEFAULT_REFRESH_ERROR_TIME_OUT
;
1068 if (table_info
->matchFetch
==
1069 (__nis_match_fetch_t
)NO_VALUE_SET
)
1070 table_info
->matchFetch
= no_match_only
;
1073 __nis_table_mapping_t
*
1074 find_table_mapping(const char *s
, int len
, __nis_table_mapping_t
*table_mapping
)
1076 __nis_table_mapping_t
*t
;
1078 for (t
= table_mapping
; t
!= NULL
; t
= t
->next
)
1079 if (strlen(t
->dbId
) == len
&&
1080 strncasecmp(t
->dbId
, s
, len
) == 0)
1086 append_dot(char **str
)
1089 int len
= strlen(s
);
1091 if (len
== 0 || s
[len
- 1] != PERIOD_CHAR
) {
1092 s
= s_realloc(s
, len
+ 2);
1094 s
[len
] = PERIOD_CHAR
;
1102 append_comma(char **str
)
1106 int len
= strlen(s
);
1108 if (len
== 0 || s
[len
- 1] != COMMA_CHAR
) {
1109 s
= s_realloc(s
, len
+ 2);
1111 s
[len
] = COMMA_CHAR
;
1119 * FUNCTION: make_full_dn
1121 * Appends the base dn if a relative ldap dn
1122 * (invoked only for LDAP write cycle)
1124 * RETURN VALUE: FALSE if error
1125 * TRUE if __nis_index_t returned
1127 * INPUT: the relative dn and ldap base
1131 make_full_dn(char **dn
, const char *base
)
1137 *dn
= s_strdup(base
);
1140 if (len
> 0 && (*dn
)[len
-1] == COMMA_CHAR
) {
1141 len1
= strlen(base
) + 1;
1142 *dn
= s_realloc(*dn
, len
+ len1
);
1144 (void) strcpy(*dn
+ len
, base
);
1147 return (*dn
!= NULL
);
1151 * FUNCTION: make_fqdn
1153 * Appends the base dn if a relative ldap dn
1154 * (invoked only for LDAP read cycle)
1156 * RETURN VALUE: FALSE if error
1159 * INPUT: the relative dn and ldap base
1162 make_fqdn(__nis_object_dn_t
*dn
, const char *base
)
1170 while (dn
!= NULL
&& dn
->read
.base
!= NULL
) {
1171 len
= strlen(dn
->read
.base
);
1172 if (len
> 0 && (dn
->read
.base
)[len
-1] == COMMA_CHAR
) {
1173 len1
= strlen(base
) + 1;
1175 s_realloc(dn
->read
.base
, len
+ len1
);
1176 if (dn
->read
.base
!= NULL
)
1177 (void) strlcpy(dn
->read
.base
+ len
,
1189 * FUNCTION: get_default_ldap_base
1191 * Gets the default LDAP search base from the
1192 * nis+ default domain
1194 * RETURN VALUE: NULL if error
1197 * INPUT: the nis domain
1201 get_default_ldap_base(const char *domain
)
1204 int len
= strlen(domain
);
1206 int count
= len
+ 4;
1209 for (i
= 0; i
< len
- 1; i
++)
1210 if (domain
[i
] == PERIOD_CHAR
)
1212 if ((base
= malloc(count
)) == NULL
) {
1213 p_error
= parse_no_mem_error
;
1215 (void) strcpy(base
, "dc=");
1217 for (i
= 0; i
< len
- 1; i
++) {
1218 if (domain
[i
] == PERIOD_CHAR
) {
1219 (void) strcpy(base
+ count
, ",dc=");
1222 base
[count
++] = domain
[i
];
1231 * FUNCTION: add_domain
1233 * Appends the base domain if a relative object name
1235 * RETURN VALUE: FALSE if error
1238 * INPUT: the relative object name and base domain
1243 add_domain(char **objName
, const char *domain
)
1247 bool_t trailing_dot
;
1250 if (domain
== NULL
|| *objName
== NULL
) {
1251 p_error
= parse_internal_error
;
1254 len1
= strlen(domain
);
1255 trailing_dot
= (len1
> 0 && domain
[len1
- 1] == PERIOD_CHAR
) ?
1257 len
= strlen(*objName
);
1258 if (len
== 0 || (*objName
)[len
- 1] != PERIOD_CHAR
) {
1259 obj_name
= s_realloc(*objName
,
1260 len
+ len1
+ 2 + trailing_dot
);
1261 if (obj_name
!= NULL
) {
1262 obj_name
[len
++] = PERIOD_CHAR
;
1263 (void) strcpy(obj_name
+ len
, domain
);
1264 if (trailing_dot
!= 0) {
1265 obj_name
[len
+ len1
] = PERIOD_CHAR
;
1266 obj_name
[len
+ len1
+ 1] = '\0';
1268 *objName
= obj_name
;
1272 return (*objName
!= NULL
);
1276 dup_index(__nis_index_t
*in
, __nis_index_t
*out
)
1281 out
->name
= (char **)s_calloc(in
->numIndexes
, sizeof (char *));
1282 if (out
->name
== NULL
)
1284 out
->value
= (__nis_mapping_format_t
**)
1285 s_calloc(in
->numIndexes
, sizeof (__nis_mapping_format_t
*));
1286 if (out
->value
== NULL
) {
1292 for (i
= 0; i
< in
->numIndexes
; i
++) {
1293 out
->name
[i
] = s_strdup(in
->name
[i
]);
1294 if (out
->name
[i
] == NULL
)
1296 out
->value
[i
] = dup_format_mapping(in
->value
[i
]);
1297 if (out
->value
[i
] == NULL
)
1300 if (i
< in
->numIndexes
) {
1301 for (j
= 0; j
<= i
; j
++) {
1302 if (out
->name
[j
] != NULL
)
1304 if (out
->value
[j
] != NULL
)
1305 free_mapping_format(out
->value
[j
]);
1312 out
->numIndexes
= in
->numIndexes
;
1314 return (i
== in
->numIndexes
);
1318 dup_mapping_item(__nis_mapping_item_t
*in
, __nis_mapping_item_t
*out
)
1322 if (in
->type
== mit_nisplus
) {
1323 ret
= dup_index(&in
->searchSpec
.obj
.index
,
1324 &out
->searchSpec
.obj
.index
);
1327 if (in
->searchSpec
.obj
.name
!= NULL
) {
1328 out
->searchSpec
.obj
.name
=
1329 s_strdup(in
->searchSpec
.obj
.name
);
1330 if (out
->searchSpec
.obj
.name
== NULL
)
1333 out
->searchSpec
.obj
.name
= NULL
;
1334 } else if (in
->type
== mit_ldap
) {
1335 if (in
->searchSpec
.triple
.base
!= NULL
) {
1336 out
->searchSpec
.triple
.base
=
1337 s_strdup(in
->searchSpec
.triple
.base
);
1338 if (out
->searchSpec
.triple
.base
== NULL
)
1341 out
->searchSpec
.triple
.base
= NULL
;
1342 out
->searchSpec
.triple
.scope
=
1343 in
->searchSpec
.triple
.scope
;
1344 if (in
->searchSpec
.triple
.attrs
!= NULL
) {
1345 out
->searchSpec
.triple
.attrs
=
1346 s_strdup(in
->searchSpec
.triple
.attrs
);
1347 if (out
->searchSpec
.triple
.attrs
== NULL
)
1350 out
->searchSpec
.triple
.attrs
= NULL
;
1351 if (in
->searchSpec
.triple
.element
!= NULL
) {
1352 out
->searchSpec
.triple
.element
=
1353 (__nis_mapping_element_t
*)
1354 s_calloc(1, sizeof (__nis_mapping_element_t
));
1355 if (out
->searchSpec
.triple
.element
!= NULL
)
1356 dup_mapping_element(
1357 in
->searchSpec
.triple
.element
,
1358 out
->searchSpec
.triple
.element
);
1359 if (out
->searchSpec
.triple
.element
== NULL
)
1362 out
->searchSpec
.triple
.element
= NULL
;
1365 if (in
->name
!= NULL
) {
1366 out
->name
= s_strdup(in
->name
);
1367 if (out
->name
== NULL
)
1371 out
->type
= in
->type
;
1372 out
->repeat
= in
->repeat
;
1374 out
->exItem
= (__nis_mapping_item_t
*)s_malloc
1375 (sizeof (__nis_mapping_item_t
));
1376 if (out
->exItem
== NULL
)
1380 (out
->exItem
, 0, sizeof (out
->exItem
[0]));
1381 if (!dup_mapping_item
1382 (in
->exItem
, out
->exItem
))
1383 p_error
= parse_internal_error
;
1388 return (p_error
== no_parse_error
);
1391 __nis_mapping_format_t
*
1392 dup_format_mapping(__nis_mapping_format_t
*in
)
1395 __nis_mapping_format_t
*out
;
1399 while (in
[i
].type
!= mmt_end
)
1401 out
= (__nis_mapping_format_t
*)s_calloc(
1402 i
+ 1, sizeof (__nis_mapping_format_t
));
1405 for (i
= 0; !got_end
; i
++) {
1406 switch (in
[i
].type
) {
1410 out
[i
].match
.string
=
1411 s_strdup(in
[i
].match
.string
);
1414 out
[i
].match
.single
.numRange
=
1415 in
[i
].match
.single
.numRange
;
1416 out
[i
].match
.single
.lo
=
1417 s_malloc(in
[i
].match
.single
.numRange
);
1418 if (out
[i
].match
.single
.lo
== NULL
)
1420 out
[i
].match
.single
.hi
=
1421 s_malloc(in
[i
].match
.single
.numRange
);
1422 if (out
[i
].match
.single
.hi
== NULL
)
1424 memcpy(out
[i
].match
.single
.lo
,
1425 in
[i
].match
.single
.lo
,
1426 in
[i
].match
.single
.numRange
);
1427 memcpy(out
[i
].match
.single
.hi
,
1428 in
[i
].match
.single
.hi
,
1429 in
[i
].match
.single
.numRange
);
1432 out
[i
].match
.limit
= in
[i
].match
.limit
;
1437 out
[i
].match
.berString
=
1438 s_strdup(in
[i
].match
.berString
);
1446 p_error
= parse_internal_error
;
1448 if (p_error
!= no_parse_error
)
1450 out
[i
].type
= in
[i
].type
;
1452 if (p_error
!= no_parse_error
) {
1453 free_mapping_format(out
);
1462 dup_mapping_sub_element(
1463 __nis_mapping_sub_element_t
*in
,
1464 __nis_mapping_sub_element_t
*out
)
1471 ret
= dup_mapping_item(&in
->element
.item
,
1472 &out
->element
.item
);
1475 out
->element
.print
.fmt
=
1476 dup_format_mapping(in
->element
.print
.fmt
);
1477 if (out
->element
.print
.fmt
== NULL
)
1479 out
->element
.print
.numItems
=
1480 in
->element
.print
.numItems
;
1481 out
->element
.print
.item
= (__nis_mapping_item_t
*)
1482 s_calloc(in
->element
.print
.numItems
,
1483 sizeof (__nis_mapping_item_t
));
1484 if (out
->element
.print
.item
== NULL
)
1486 for (i
= 0; i
< in
->element
.print
.numItems
; i
++)
1487 if (!dup_mapping_item(
1488 &in
->element
.print
.item
[i
],
1489 &out
->element
.print
.item
[i
]))
1491 if (i
< in
->element
.print
.numItems
)
1494 out
->element
.print
.doElide
= in
->element
.print
.doElide
;
1495 out
->element
.print
.elide
= in
->element
.print
.elide
;
1498 ret
= dup_mapping_item(&in
->element
.split
.item
,
1499 &out
->element
.split
.item
);
1500 out
->element
.split
.delim
= in
->element
.split
.delim
;
1503 out
->element
.extract
.fmt
=
1504 dup_format_mapping(in
->element
.extract
.fmt
);
1505 if (out
->element
.extract
.fmt
== NULL
)
1507 ret
= dup_mapping_item(&in
->element
.extract
.item
,
1508 &out
->element
.extract
.item
);
1511 p_error
= parse_internal_error
;
1513 out
->type
= in
->type
;
1519 dup_mapping_element(
1520 __nis_mapping_element_t
*in
,
1521 __nis_mapping_element_t
*out
)
1531 ret
= dup_mapping_item(&in
->element
.item
,
1532 &out
->element
.item
);
1535 out
->element
.print
.fmt
=
1536 dup_format_mapping(in
->element
.print
.fmt
);
1537 if (out
->element
.print
.fmt
== NULL
)
1539 out
->element
.print
.numSubElements
=
1540 in
->element
.print
.numSubElements
;
1541 out
->element
.print
.subElement
=
1542 (__nis_mapping_sub_element_t
*)
1543 s_calloc(in
->element
.print
.numSubElements
,
1544 sizeof (__nis_mapping_sub_element_t
));
1545 if (out
->element
.print
.subElement
== NULL
)
1547 for (i
= 0; i
< in
->element
.print
.numSubElements
; i
++)
1548 if (!dup_mapping_sub_element(
1549 &in
->element
.print
.subElement
[i
],
1550 &out
->element
.print
.subElement
[i
]))
1552 if (i
< in
->element
.print
.numSubElements
)
1555 out
->element
.print
.doElide
= in
->element
.print
.doElide
;
1556 out
->element
.print
.elide
= in
->element
.print
.elide
;
1559 ret
= dup_mapping_item(&in
->element
.split
.item
,
1560 &out
->element
.split
.item
);
1561 out
->element
.split
.delim
= in
->element
.split
.delim
;
1564 out
->element
.match
.fmt
=
1565 dup_format_mapping(in
->element
.match
.fmt
);
1566 if (out
->element
.match
.fmt
== NULL
)
1568 out
->element
.match
.numItems
=
1569 in
->element
.match
.numItems
;
1570 out
->element
.match
.item
= (__nis_mapping_item_t
*)
1571 s_calloc(in
->element
.match
.numItems
,
1572 sizeof (__nis_mapping_item_t
));
1573 if (out
->element
.match
.item
== NULL
)
1575 for (i
= 0; i
< in
->element
.match
.numItems
; i
++)
1576 if (!dup_mapping_item(
1577 &in
->element
.match
.item
[i
],
1578 &out
->element
.match
.item
[i
]))
1580 if (i
< in
->element
.match
.numItems
)
1585 out
->element
.extract
.fmt
=
1586 dup_format_mapping(in
->element
.extract
.fmt
);
1587 if (out
->element
.extract
.fmt
== NULL
)
1589 ret
= dup_mapping_item(&in
->element
.extract
.item
,
1590 &out
->element
.extract
.item
);
1593 p_error
= parse_internal_error
;
1595 out
->type
= in
->type
;
1600 __nis_mapping_rule_t
*
1601 dup_mapping_rule(__nis_mapping_rule_t
*in
)
1604 __nis_mapping_rlhs_t
*r_in
;
1605 __nis_mapping_rlhs_t
*r_out
;
1606 __nis_mapping_rule_t
*out
;
1608 out
= (__nis_mapping_rule_t
*)
1609 s_calloc(1, sizeof (__nis_mapping_rule_t
));
1613 r_out
->numElements
= r_in
->numElements
;
1614 r_out
->element
= (__nis_mapping_element_t
*)s_calloc
1615 (r_in
->numElements
, sizeof (__nis_mapping_element_t
));
1616 if (r_out
->element
== NULL
) {
1617 free_mapping_rule(out
);
1620 for (i
= 0; i
< r_in
->numElements
; i
++) {
1621 if (!dup_mapping_element(&r_in
->element
[i
],
1622 &r_out
->element
[i
]))
1625 if (i
< r_in
->numElements
) {
1626 free_mapping_rule(out
);
1632 r_out
->numElements
= r_in
->numElements
;
1633 r_out
->element
= (__nis_mapping_element_t
*)s_calloc
1634 (r_in
->numElements
, sizeof (__nis_mapping_element_t
));
1635 if (r_out
->element
== NULL
) {
1636 free_mapping_rule(out
);
1639 for (i
= 0; i
< r_in
->numElements
; i
++) {
1640 if (!dup_mapping_element(&r_in
->element
[i
],
1641 &r_out
->element
[i
]))
1644 if (i
< r_in
->numElements
) {
1645 free_mapping_rule(out
);
1652 __nis_mapping_rule_t
**
1653 dup_mapping_rules(__nis_mapping_rule_t
**rules
, int n_rules
)
1656 __nis_mapping_rule_t
**r
;
1658 r
= (__nis_mapping_rule_t
**)s_calloc(n_rules
,
1659 sizeof (__nis_mapping_rule_t
*));
1661 for (i
= 0; i
< n_rules
; i
++) {
1662 r
[i
] = dup_mapping_rule(rules
[i
]);
1664 for (j
= 0; j
< i
; j
++)
1665 free_mapping_rule(r
[j
]);
1676 * FUNCTION: add_column
1678 * Adds a column name to the column list in __nis_table_mapping_t
1680 * RETURN VALUE: FALSE if error
1681 * TRUE if __nis_index_t returned
1683 * INPUT: the __nis_table_mapping_t and column name
1687 add_column(__nis_table_mapping_t
*t
, const char *col_name
)
1693 for (i
= 0; i
< t
->numColumns
; i
++) {
1694 if (strcasecmp(col_name
, t
->column
[i
]) == 0)
1698 cols
= (char **)s_realloc(t
->column
, (t
->numColumns
+ 1) *
1703 cols
[t
->numColumns
] = s_strdup(col_name
);
1704 if (cols
[t
->numColumns
] == NULL
)
1711 * FUNCTION: add_element
1713 * Adds a __nis_mapping_element_t to __nis_mapping_rlhs_t
1715 * RETURN VALUE: FALSE if error
1716 * TRUE if __nis_index_t returned
1718 * INPUT: the __nis_mapping_element_t and
1719 * __nis_mapping_rlhs_t
1724 __nis_mapping_element_t
*e
,
1725 __nis_mapping_rlhs_t
*m
)
1727 __nis_mapping_element_t
*e1
;
1729 int n
= m
->numElements
;
1731 e1
= (__nis_mapping_element_t
*)s_realloc(m
->element
,
1732 (n
+ 1) * sizeof (__nis_mapping_element_t
));
1735 for (i
= 0; i
< n
; i
++)
1736 free_mapping_element(e1
++);
1737 if (m
->element
!= NULL
)
1742 e1
[m
->numElements
++] = *e
;
1744 m
->element
= (__nis_mapping_element_t
*)e1
;
1746 return (e1
!= NULL
);
1750 * FUNCTION: get_next_object_dn_token
1752 * Get the next token in parsing object_dn
1754 * RETURN VALUE: NULL if error
1755 * position of beginning next token after
1758 * INPUT: the attribute value
1762 get_next_object_dn_token(
1763 const char **begin_ret
,
1764 const char **end_ret
,
1765 object_dn_token
*token
)
1767 object_dn_token t
= dn_no_token
;
1768 const char *s
= *begin_ret
;
1770 const char *end
= *end_ret
;
1774 while (s
< end
&& is_whitespace(*s
))
1778 } else if (*s
== SEMI_COLON_CHAR
) {
1781 } else if (*s
== QUESTION_MARK
) {
1784 } else if (*s
== COLON_CHAR
) {
1787 } else if (*s
== OPEN_PAREN_CHAR
) {
1789 s
= get_ldap_filter(&begin
, &end
);
1799 if (*s
== ESCAPE_CHAR
) {
1801 p_error
= parse_unmatched_escape
;
1806 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
1807 in_quotes
= ! in_quotes
;
1808 } else if (in_quotes
)
1810 else if (*s
== SEMI_COLON_CHAR
||
1811 *s
== QUESTION_MARK
||
1818 while (is_whitespace(*s1
))
1821 if (same_string("base", begin
, s1
- begin
))
1823 else if (same_string("one", begin
, s1
- begin
))
1825 else if (same_string("sub", begin
, s1
- begin
))
1838 * FUNCTION: get_next_token
1840 * Get the next token in parsing mapping attribute
1842 * RETURN VALUE: NULL if error
1843 * position of beginning next token after
1846 * INPUT: the attribute value
1850 get_next_token(const char **begin_token
, const char **end_token
, token_type
*t
)
1852 const char *s
= *begin_token
;
1853 const char *end_s
= *end_token
;
1854 const char *s_begin
;
1856 while (s
< end_s
&& is_whitespace(*s
))
1865 if (*s
== OPEN_PAREN_CHAR
) {
1869 while (s
< end_s
&& is_whitespace(*s
))
1871 *t
= open_paren_token
;
1872 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
1875 if (*s
== ESCAPE_CHAR
)
1877 else if (*s
== DOUBLE_QUOTE_CHAR
)
1883 p_error
= parse_unmatched_escape
;
1887 *t
= quoted_string_token
;
1888 *begin_token
= s_begin
+ 1;
1890 } else if (*s
== EQUAL_CHAR
|| *s
== COMMA_CHAR
||
1891 *s
== CLOSE_PAREN_CHAR
|| *s
== COLON_CHAR
) {
1892 if (*s
== EQUAL_CHAR
)
1894 else if (*s
== COMMA_CHAR
)
1896 else if (*s
== CLOSE_PAREN_CHAR
)
1897 *t
= close_paren_token
;
1904 while (s
< end_s
&& !is_whitespace(*s
)) {
1905 if (*s
== ESCAPE_CHAR
)
1907 else if (*s
== EQUAL_CHAR
|| *s
== CLOSE_PAREN_CHAR
||
1908 *s
== OPEN_PAREN_CHAR
|| *s
== COMMA_CHAR
||
1909 *s
== COLON_CHAR
|| *s
== OPEN_BRACKET
||
1910 *s
== CLOSE_BRACKET
)
1916 p_error
= parse_unmatched_escape
;
1921 *begin_token
= s_begin
;
1924 while (s
< end_s
&& is_whitespace(*s
))
1931 * FUNCTION: skip_token
1933 * Skip over the specified token - An error is set if
1934 * next token does not match expected token
1936 * RETURN VALUE: NULL if error
1937 * position of beginning next token after
1940 * INPUT: the attribute value
1944 skip_token(const char *s
, const char *end_s
, token_type t
)
1951 while (s
< end_s
&& is_whitespace(*s
))
1953 c
= (s
== end_s
) ? 0 : *s
;
1956 match
= c
== EQUAL_CHAR
;
1958 p_error
= parse_equal_expected_error
;
1961 match
= c
== COMMA_CHAR
;
1963 p_error
= parse_comma_expected_error
;
1965 case close_paren_token
:
1966 match
= c
== CLOSE_PAREN_CHAR
;
1968 p_error
= parse_close_paren_expected_error
;
1976 while (s
< end_s
&& is_whitespace(*s
))
1985 * FUNCTION: get_next_extract_format_item
1987 * Get the next format token from the string. Note that
1988 * get_next_extract_format_item may change the input string.
1990 * RETURN VALUE: NULL if error
1991 * position of beginning next token after
1994 * INPUT: the format string
1998 get_next_extract_format_item(
1999 const char *begin_fmt
,
2000 const char *end_fmt
,
2001 __nis_mapping_format_t
*fmt
)
2003 const char *s
= begin_fmt
;
2004 const char *s_end
= end_fmt
;
2014 for (; p_error
== no_parse_error
; ) {
2018 if (*s
== PERCENT_SIGN
) {
2021 * If the format is %s, it is interpreted
2025 p_error
= parse_unsupported_format
;
2031 fmt
->type
= mmt_item
;
2033 case 'n': /* null */
2034 case 'x': /* skip the next element */
2037 case 'b': /* boolean */
2038 case 'e': /* enumerated */
2040 case 'o': /* octet string */
2041 case 'B': /* bit string */
2042 fmt
->match
.berString
= s_strndup(s
, 1);
2043 fmt
->type
= skip_ber
?
2044 mmt_berstring_null
:
2047 case 'a': /* octet string */
2049 fmt
->match
.berString
=
2051 fmt
->type
= skip_ber
?
2052 mmt_berstring_null
:
2055 } /* else FALLTHRU */
2056 case '{': /* begin sequence */
2057 case '[': /* begin set */
2058 case '}': /* end sequence */
2059 case ']': /* end set */
2060 case 'l': /* length of next item */
2061 case 'O': /* octet string */
2062 case 't': /* tag of next item */
2063 case 'T': /* skip tag of next item */
2064 case 'v': /* seq of strings */
2065 case 'V': /* seq of strings + lengths */
2067 p_error
= parse_bad_ber_format
;
2071 } else if (*s
== ASTERIX_CHAR
) {
2072 fmt
->type
= mmt_any
;
2074 while (s
< s_end
&& *s
== ASTERIX_CHAR
)
2077 } else if (*s
== OPEN_BRACKET
) {
2084 for (; s
< s_end
; s
++) {
2087 } else if (*s
== DASH_CHAR
) {
2088 if (in_range
|| !got_char
) {
2089 p_error
= parse_unexpected_dash
;
2095 } else if (*s
== CLOSE_BRACKET
) {
2097 p_error
= parse_unexpected_dash
;
2101 } else if (*s
== ESCAPE_CHAR
) {
2106 hi
[numRange
- 1] = *s
;
2109 lo
= s_realloc(lo
, numRange
+ 1);
2110 hi
= s_realloc(hi
, numRange
+ 1);
2111 if (lo
== NULL
|| hi
== NULL
)
2119 if (p_error
!= no_parse_error
) {
2122 p_error
= parse_mismatched_brackets
;
2126 fmt
->type
= mmt_single
;
2127 fmt
->match
.single
.numRange
= numRange
;
2128 fmt
->match
.single
.lo
= (unsigned char *)lo
;
2129 fmt
->match
.single
.hi
= (unsigned char *)hi
;
2131 /* go to next key symbol - copy escaped key symbols */
2156 p_error
= parse_unmatched_escape
;
2159 fmt
->type
= mmt_string
;
2161 s_strndup_esc(begin_fmt
, s
- begin_fmt
);
2162 if (fmt
->match
.string
== NULL
)
2166 if (p_error
== no_parse_error
)
2177 * FUNCTION: get_next_print_format_item
2179 * Get the next format token from the string
2181 * RETURN VALUE: NULL if error
2182 * position of beginning next token after
2185 * INPUT: the format string
2189 get_next_print_format_item(
2190 const char *begin_fmt
,
2191 const char *end_fmt
,
2192 __nis_mapping_format_t
*fmt
)
2194 const char *s
= begin_fmt
;
2195 const char *s_end
= end_fmt
;
2198 for (; p_error
== no_parse_error
; ) {
2200 p_error
= parse_internal_error
;
2204 if (*s
== PERCENT_SIGN
) {
2207 p_error
= parse_unsupported_format
;
2212 * If the format is %s, it is interpretted
2217 fmt
->type
= mmt_item
;
2219 case 'n': /* null */
2220 case 'x': /* skip the next element */
2223 case 'b': /* boolean */
2224 case 'e': /* enumerated */
2226 case 'o': /* octet string */
2227 case 'B': /* bit string */
2228 fmt
->match
.berString
= s_strndup(s
, 1);
2229 fmt
->type
= skip_ber
?
2230 mmt_berstring_null
:
2233 case '{': /* begin sequence */
2234 case '[': /* begin set */
2235 case '}': /* end sequence */
2236 case ']': /* end set */
2237 case 'a': /* octet string */
2238 case 'l': /* length of next item */
2239 case 'O': /* octet string */
2240 case 't': /* tag of next item */
2241 case 'T': /* skip tag of next item */
2242 case 'v': /* seq of strings */
2243 case 'V': /* seq of strings + lengths */
2245 p_error
= parse_bad_ber_format
;
2251 if (*s
== PERCENT_SIGN
)
2253 else if (*s
== ESCAPE_CHAR
)
2258 p_error
= parse_unmatched_escape
;
2262 s_strndup_esc(begin_fmt
, s
- begin_fmt
);
2263 if (fmt
->match
.string
== NULL
)
2265 fmt
->type
= mmt_string
;
2267 if (p_error
== no_parse_error
)
2274 * FUNCTION: get_ldap_filter
2276 * Gets an LDAP filter - see RFC 2254. Note that this does not
2277 * determine if the ldap filter is valid. This only determines
2278 * that the parentheses are balanced.
2280 * RETURN VALUE: NULL if error
2281 * position of beginning next token after
2284 * INPUT: the begin and end of string
2286 * OUTPUT: the begin and end of LDAP filter
2291 get_ldap_filter(const char **begin
, const char **end
)
2293 const char *s
= *begin
;
2294 const char *s_begin
;
2295 const char *s_end
= *end
;
2298 for (; p_error
== no_parse_error
; ) {
2299 while (s
< s_end
&& is_whitespace(*s
))
2307 if (*s
== OPEN_PAREN_CHAR
) {
2310 while (s
< s_end
&& nParen
> 0) {
2311 if (*s
== ESCAPE_CHAR
)
2313 else if (*s
== OPEN_PAREN_CHAR
)
2315 else if (*s
== CLOSE_PAREN_CHAR
)
2322 while (s
< s_end
&& is_whitespace(*s
))
2328 if (p_error
== no_parse_error
)
2332 p_error
= parse_invalid_ldap_search_filter
;
2338 * FUNCTION: get_ava_list
2340 * Gets an attribute value assertion list
2342 * RETURN VALUE: NULL if error
2343 * position of beginning next token after
2344 * after attribute assertion
2346 * INPUT: the begin and end of string
2347 * Indicator if ava list is part of a nisplus
2350 * OUTPUT: the begin and end of LDAP filter
2355 get_ava_list(const char **begin
, const char **end
, bool_t end_nisplus
)
2357 const char *s
= *begin
;
2358 const char *s_begin
;
2359 const char *s_end
= *end
;
2364 for (; p_error
== no_parse_error
; ) {
2365 while (s
< s_end
&& is_whitespace(*s
))
2377 if (*s
== ESCAPE_CHAR
) {
2380 } else if (*s
== DOUBLE_QUOTE_CHAR
) {
2381 in_quote
= !in_quote
;
2383 } else if (in_quote
)
2385 else if (*s
== EQUAL_CHAR
) {
2386 if (end_nisplus
&& got_data
&& got_equal
)
2388 if (!got_data
|| got_equal
) {
2394 } else if (*s
== COMMA_CHAR
) {
2395 if (!got_data
|| !got_equal
)
2399 } else if (is_whitespace(*s
))
2405 if (!got_data
|| !got_equal
|| in_quote
)
2410 while (s
< s_end
&& is_whitespace(*s
))
2413 if (p_error
== no_parse_error
)
2417 p_error
= parse_invalid_ldap_search_filter
;
2422 /* Utility functions */
2424 validate_dn(const char *s
, int len
)
2426 const char *end
= s
+ len
;
2429 valid
= skip_get_dn(s
, end
) == end
;
2432 p_error
= parse_bad_dn
;
2437 validate_ldap_filter(const char *s
, const char *end
)
2439 const char *s_begin
;
2445 if (*s
== OPEN_PAREN_CHAR
) {
2446 s
= get_ldap_filter(&s_begin
, &s_end
);
2448 /* Assume an attribute value list */
2449 s
= get_ava_list(&s_begin
, &s_end
, FALSE
);
2451 if (s
== NULL
|| s_end
!= end
)
2452 p_error
= parse_invalid_ldap_search_filter
;
2454 return (p_error
== no_parse_error
);
2458 s_strndup(const char *s
, int n
)
2460 char *d
= (char *)malloc(n
+ 1);
2463 (void) memcpy(d
, s
, n
);
2466 p_error
= parse_no_mem_error
;
2473 s_strndup_esc(const char *s
, int n
)
2475 char *d
= (char *)malloc(n
+ 1);
2480 for (i
= 0, j
= 0; i
< n
; i
++) {
2481 if (s
[i
] == ESCAPE_CHAR
)
2487 p_error
= parse_no_mem_error
;
2494 s_calloc(size_t n
, size_t size
)
2496 void *d
= (char *)calloc(n
, size
);
2499 p_error
= parse_no_mem_error
;
2506 s_malloc(size_t size
)
2508 void *d
= malloc(size
);
2510 p_error
= parse_no_mem_error
;
2515 s_realloc(void *s
, size_t size
)
2517 s
= realloc(s
, size
);
2519 p_error
= parse_no_mem_error
;
2524 s_strdup(const char *s
)
2526 return (s
!= NULL
? s_strndup(s
, strlen(s
)) : NULL
);
2530 is_whitespace(int c
)
2532 return (c
== ' ' || c
== '\t');
2536 is_string_ok(char *buffer
, int buflen
)
2543 for (i
= 0; i
< buflen
; i
++) {
2544 if (!is_whitespace(buffer
[i
])) {
2545 if (buffer
[i
] == POUND_SIGN
)
2555 * Returns true if the first string is contained at the beginning of the
2556 * second string. Otherwise returns false.
2560 contains_string(const char *s1
, const char *s2
)
2562 return (strncasecmp(s1
, s2
, strlen(s1
)) == 0);
2566 * Returns the next character position in the second string, if the first
2567 * string is contained at the beginning of the second string. Otherwise
2572 skip_string(const char *s1
, const char *s2
, int len
)
2574 int len1
= strlen(s1
);
2576 if (len
>= len1
&& strncasecmp(s1
, s2
, strlen(s1
)) == 0)
2583 * The second string is not necessarily null terminated.
2584 * same_string returns true if the second string matches the first.
2585 * Otherwise returns false.
2589 same_string(const char *s1
, const char *s2
, int len
)
2591 int len1
= strlen(s1
);
2593 return (len1
== len
&& strncasecmp(s1
, s2
, len1
) == 0);
2597 report_error(const char *str
, const char *attr
)
2602 if (command_line_source
!= NULL
) {
2603 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error parsing %s: ",
2604 command_line_source
);
2605 pos
= strlen(fmt_buf
);
2606 } else if (file_source
!= NULL
) {
2607 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error parsing file '%s': ",
2609 pos
= strlen(fmt_buf
);
2610 } else if (ldap_source
!= NULL
) {
2611 snprintf(fmt_buf
, sizeof (fmt_buf
), "Error for LDAP dn '%s': ",
2613 pos
= strlen(fmt_buf
);
2616 if (start_line_num
!= 0) {
2617 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "at line %d: ",
2619 pos
+= strlen(fmt_buf
+ pos
);
2623 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
,
2624 "for attribute %s: ", attr
);
2625 pos
+= strlen(fmt_buf
+ pos
);
2629 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "%s\n",
2630 parse_error_msg
[p_error
]);
2631 fprintf(cons
, fmt_buf
, str
== NULL
? "" : str
);
2633 snprintf(fmt_buf
+ pos
, sizeof (fmt_buf
) - pos
, "%s",
2634 parse_error_msg
[p_error
]);
2635 syslog(LOG_ERR
, fmt_buf
, str
== NULL
? "" : str
);
2647 snprintf(fmt_buf
, sizeof (fmt_buf
),
2648 "%s\n", parse_error_msg
[p_error
]);
2649 fprintf(cons
, fmt_buf
, str1
, str2
);
2651 syslog(LOG_ERR
, parse_error_msg
[p_error
], str1
, str2
);
2664 snprintf(fmt_buf
, sizeof (fmt_buf
),
2665 "%s\n", conn_error_msg
[e
]);
2666 fprintf(cons
, fmt_buf
,
2667 str1
== NULL
? "" : str1
,
2668 str2
== NULL
? "" : str2
);
2672 str1
== NULL
? "" : str1
,
2673 str2
== NULL
? "" : str2
);
2688 syslog(LOG_INFO
, str
, arg
);