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 2001-2003 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
36 #include "ldap_parse.h"
37 #include "nis_parse_ldap_conf.h"
38 #include "nis_parse_ldap_yp_util.h"
39 #include "nis_parse_ldap_util.h"
41 /* other attribute functions */
42 static char *getIndex(const char **s_cur
, const char *end_s
);
43 static bool_t
get_ttls(const char *s
, const char *s_end
,
44 __nis_table_mapping_t
*t_mapping
);
45 static __nis_object_dn_t
*parse_object_dn(const char *s
, const char *end
);
46 static int parse_name_fields(const char *name_s
, const char *name_s_end
,
47 __nis_table_mapping_t
*t_mapping
);
48 static void get_mapping_rule(const char *s
, int len
,
49 __nis_table_mapping_t
*tbl
, bool_t to_ldap
);
50 static bool_t
get_deleteDisp(const char *s_begin
, const char *s_end
,
51 __nis_object_dn_t
*obj_dn
);
53 /* mapping rule functions */
54 static const char *get_lhs(const char *s
, const char *end_s
,
55 __nis_mapping_rlhs_t
*lhs
, __nis_mapping_item_type_t item_type
);
56 static const char *get_lhs_match(const char *s
, const char *end_s
,
57 __nis_mapping_rlhs_t
*lhs
, __nis_mapping_item_type_t item_type
);
58 static const char *get_lhs_paren_item(const char *s
, const char *end_s
,
59 __nis_mapping_rlhs_t
*lhs
, __nis_mapping_item_type_t item_type
);
60 static const char *get_rhs(const char *s
, const char *end_s
,
61 __nis_mapping_rlhs_t
*lhs
, __nis_mapping_item_type_t item_type
);
62 static const char *get_mapping_item(const char *s
, const char *end_s
,
63 __nis_mapping_item_t
*item
, __nis_mapping_item_type_t type
);
64 static const char *get_print_mapping_element(const char *s
,
65 const char *end_s
, char *fmt_string
, __nis_mapping_element_t
*e
,
66 __nis_mapping_item_type_t item_type
);
67 static const char *get_subElement(const char *s
, const char *end_s
,
68 __nis_mapping_sub_element_t
*subelement
,
69 __nis_mapping_item_type_t type
);
70 static bool_t
get_mapping_format(const char *fmt_string
,
71 __nis_mapping_format_t
**fmt
, int *nfmt
, int *numItems
,
72 bool_t print_mapping
);
73 extern __yp_domain_context_t ypDomains
;
76 * FUNCTION: add_mapping_attribute
78 * Adds the attribute value to __nis_table_mapping_t
79 * if the value is not yet set for the given database.
81 * RETURN VALUE: 0 on success, -1 on failure
83 * INPUT: attribute number and value
87 add_mapping_attribute(
88 config_key attrib_num
,
89 const char *attrib_val
,
91 __nis_table_mapping_t
**table_mapping
)
94 const char *attrib_end
;
95 const char *db_id_end
;
96 const char *begin_token
;
98 __nis_object_dn_t
*objectDN
;
99 __nis_table_mapping_t
*t_mapping
;
100 __nis_table_mapping_t
*t
;
102 bool_t new_mapping
= FALSE
;
106 attrib_end
= attrib_val
+ attrib_len
;
107 for (s
= attrib_val
; s
< attrib_end
; s
++)
108 if (*s
== COLON_CHAR
)
111 if (s
== attrib_end
|| *attrib_val
== COLON_CHAR
) {
112 p_error
= parse_unexpected_data_end_rule
;
117 while (s
> attrib_val
&& is_whitespace(s
[-1]))
120 if (s
== attrib_val
) {
121 p_error
= parse_unexpected_data_end_rule
;
126 tmp_dbId
= s_strndup(attrib_val
, s
- attrib_val
);
127 if (tmp_dbId
== NULL
) {
128 p_error
= parse_no_mem_error
;
131 if (strchr(tmp_dbId
, COMMA_CHAR
)) {
132 /* domain explicitly specified */
133 nm
= check_domain_specific_order(tmp_dbId
,
134 attrib_num
, *table_mapping
, &ypDomains
);
136 * No logging is needed here, as
137 * check_domain_specific_order
138 * will log any appropriate errors.
148 if ((t_mapping
= find_table_mapping(attrib_val
,
149 s
- attrib_val
, *table_mapping
)) == NULL
) {
150 /* No mapping with this id, create one */
151 t_mapping
= (__nis_table_mapping_t
*)
152 s_calloc(1, sizeof (__nis_table_mapping_t
));
154 if (t_mapping
== NULL
) {
155 p_error
= parse_no_mem_error
;
158 (void) initialize_table_mapping(t_mapping
);
160 /* dbId is the label before the colon */
161 t_mapping
->dbId
= s_strndup(attrib_val
, s
- attrib_val
);
162 if (t_mapping
->dbId
== NULL
) {
163 p_error
= parse_no_mem_error
;
169 /* a table mapping already exists, use it */
174 while (s
< attrib_end
&& is_whitespace(*s
))
177 switch (attrib_num
) {
178 case key_yp_map_flags
:
179 if (t_mapping
->usedns_flag
!= 0 ||
180 t_mapping
->securemap_flag
!= 0) {
181 warn_duplicate_map(t_mapping
->dbId
,
185 while (is_whitespace(*s
) && s
< attrib_end
)
187 while (s
< attrib_end
) {
188 if (s
< attrib_end
&& *s
== 'b')
189 t_mapping
->usedns_flag
= 1;
190 if (s
< attrib_end
&& *s
== 's')
191 t_mapping
->securemap_flag
= 1;
195 case key_yp_comment_char
:
196 if (t_mapping
->commentChar
!=
197 DEFAULT_COMMENT_CHAR
) {
198 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
201 while (is_whitespace(*s
) && s
< attrib_end
)
203 if (s
< attrib_end
&& (s
+1) < attrib_end
&&
204 (s
+2) <= attrib_end
) {
205 while (is_whitespace(attrib_end
[-1]))
207 while (*s
!= SINGLE_QUOTE_CHAR
)
209 if (*s
== SINGLE_QUOTE_CHAR
&&
210 *(s
+2) == SINGLE_QUOTE_CHAR
) {
211 t_mapping
->commentChar
= *(s
+1);
212 } else if (*s
== SINGLE_QUOTE_CHAR
&&
213 *(s
+1) == SINGLE_QUOTE_CHAR
) {
214 t_mapping
->commentChar
= '\0';
216 /* anything else is an error */
217 p_error
= parse_bad_yp_comment_error
;
221 p_error
= parse_bad_yp_comment_error
;
224 case key_yp_repeated_field_separators
:
225 while (s
< attrib_end
&& is_whitespace(*s
))
227 if (s
< attrib_end
) {
228 while (is_whitespace(attrib_end
[-1]))
230 while (s
< attrib_end
&&
231 *s
!= DOUBLE_QUOTE_CHAR
)
235 while (s
< attrib_end
&&
236 *s
!= DOUBLE_QUOTE_CHAR
) {
237 if (*s
== ESCAPE_CHAR
)
241 t_mapping
->separatorStr
=
242 s_strndup(begin_token
, s
- begin_token
);
243 if (t_mapping
->separatorStr
== NULL
)
246 p_error
= parse_bad_field_separator_error
;
249 case key_yp_name_fields
:
250 case key_yp_split_field
:
251 if (t_mapping
->e
|| t_mapping
->numSplits
> 0) {
252 warn_duplicate_map(t_mapping
->dbId
,
256 if (parse_name_fields(s
, attrib_end
, t_mapping
)) {
257 p_error
= parse_bad_name_field
;
260 case key_yp_db_id_map
:
262 if (t_mapping
->objName
!= NULL
) {
263 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
267 if (s
< attrib_end
&& *s
== OPEN_BRACKET
) {
268 index_string
= getIndex(&s
, attrib_end
);
269 if (index_string
== NULL
)
271 (void) parse_index(index_string
,
272 index_string
+ strlen(index_string
),
275 if (p_error
!= no_parse_error
)
278 while (is_whitespace(*s
) && s
< attrib_end
)
280 if (s
< attrib_end
) {
281 while (is_whitespace(attrib_end
[-1]))
284 s_strndup_esc(s
, attrib_end
- s
);
287 p_error
= parse_bad_map_error
;
289 t_mapping
->objName
= s_strndup(s
, 0);
294 case key_yp_entry_ttl
:
296 if (t_mapping
->initTtlLo
!= (time_t)NO_VALUE_SET
) {
297 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
301 if (!get_ttls(s
, attrib_end
, t_mapping
))
302 p_error
= parse_bad_ttl_format_error
;
305 case key_yp_ldap_object_dn
:
306 case key_ldap_object_dn
:
307 if (t_mapping
->objectDN
!= NULL
) {
308 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
311 objectDN
= parse_object_dn(s
, attrib_end
);
312 if (objectDN
== NULL
)
314 t_mapping
->objectDN
= objectDN
;
315 t_mapping
->seq_num
= seq_num
++;
318 case key_nis_to_ldap_map
:
319 case key_nisplus_to_ldap_map
:
320 if (t_mapping
->ruleToLDAP
!= 0) {
321 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
325 get_mapping_rule(s
, attrib_end
- s
, t_mapping
, TRUE
);
328 case key_ldap_to_nis_map
:
329 case key_ldap_to_nisplus_map
:
330 if (t_mapping
->ruleFromLDAP
!= NULL
) {
331 warn_duplicate_map(t_mapping
->dbId
, attrib_num
);
335 get_mapping_rule(s
, attrib_end
- s
, t_mapping
, FALSE
);
339 p_error
= parse_internal_error
;
342 if (p_error
== no_parse_error
) {
344 if (*table_mapping
== NULL
)
345 *table_mapping
= t_mapping
;
347 for (t
= *table_mapping
; t
->next
!= NULL
;
355 free_table_mapping(t_mapping
);
357 return (p_error
== no_parse_error
? 0 : -1);
361 * FUNCTION: add_ypdomains_attribute
363 * Adds the yp domains information to the __yp_domain_context_t
366 * RETURN: 0 on success, -1 on failure
368 * INPUT: attribute number and value
372 add_ypdomains_attribute(
373 config_key attrib_num
,
374 const char *attrib_val
,
376 __yp_domain_context_t
*ypDomains
)
379 const char *attrib_end
;
382 attrib_end
= attrib_val
+ attrib_len
;
383 for (s
= attrib_val
; s
< attrib_end
; s
++) {
384 if (*s
== COLON_CHAR
) {
388 while (s
> attrib_val
&& is_whitespace(s
[-1]))
391 if (s
== attrib_val
) {
392 p_error
= parse_unexpected_data_end_rule
;
396 if (ypDomains
== NULL
) {
398 * No point allocating. We cant return the resulting structure,
399 * so just return failure. Should not ever happen because we
400 * are always called with a pointer to the global ypDomains
406 switch (attrib_num
) {
407 case key_yp_domain_context
:
408 numDomains
= ypDomains
->numDomains
;
409 ypDomains
->domainLabels
=
410 (char **)s_realloc(ypDomains
->domainLabels
,
412 sizeof (ypDomains
->domainLabels
[0]));
413 if (ypDomains
->domainLabels
== NULL
) {
414 p_error
= parse_no_mem_error
;
415 free_yp_domain_context(ypDomains
);
418 ypDomains
->domainLabels
[numDomains
] =
419 s_strndup(attrib_val
, s
- attrib_val
);
420 if (ypDomains
->domainLabels
[numDomains
] == NULL
) {
421 p_error
= parse_no_mem_error
;
422 free_yp_domain_context(ypDomains
);
425 ypDomains
->numDomains
= numDomains
+ 1;
426 while (s
< attrib_end
&& is_whitespace(*s
))
428 if (*s
== COLON_CHAR
)
430 while (s
< attrib_end
&& is_whitespace(*s
))
433 (char **)s_realloc(ypDomains
->domains
,
435 sizeof (ypDomains
->domains
[0]));
436 if (ypDomains
->domains
== NULL
) {
437 p_error
= parse_no_mem_error
;
438 free_yp_domain_context(ypDomains
);
442 if (s
< attrib_end
) {
443 while (is_whitespace(attrib_end
[-1]))
445 ypDomains
->domains
[numDomains
] =
446 s_strndup_esc(s
, attrib_end
- s
);
447 if (ypDomains
->domains
[numDomains
] == NULL
) {
448 p_error
= parse_no_mem_error
;
449 free_yp_domain_context(ypDomains
);
453 p_error
= parse_unexpected_yp_domain_end_error
;
454 free(ypDomains
->domainLabels
[numDomains
]);
455 ypDomains
->domainLabels
[numDomains
] = NULL
;
456 ypDomains
->numDomains
--;
457 free_yp_domain_context(ypDomains
);
460 case key_yppasswdd_domains
:
461 ypDomains
->yppasswddDomainLabels
=
463 ypDomains
->yppasswddDomainLabels
,
464 (ypDomains
->numYppasswdd
+ 1) *
465 sizeof (ypDomains
->yppasswddDomainLabels
[0]));
466 if (ypDomains
->yppasswddDomainLabels
== NULL
) {
467 p_error
= parse_no_mem_error
;
470 ypDomains
->yppasswddDomainLabels
471 [ypDomains
->numYppasswdd
] =
472 s_strndup(attrib_val
, s
- attrib_val
);
473 if (ypDomains
->yppasswddDomainLabels
474 [ypDomains
->numYppasswdd
] == NULL
) {
475 p_error
= parse_no_mem_error
;
477 ypDomains
->numYppasswdd
++;
481 return (p_error
== no_parse_error
? 0 : -1);
487 * Parse time to live attribute
489 * RETURN VALUE: TRUE on success, FALSE on failure
491 * INPUT: the attribute value
498 __nis_table_mapping_t
*t_mapping
)
500 time_t initTtlHi
= 0;
501 time_t initTtlLo
= 0;
506 * attribute should be of the form
507 * initialTTLlo ":" initialTTLhi ":" runningTTL
511 p_error
= parse_bad_ttl_format_error
;
516 while (s
< s_end
&& isdigit(*s
)) {
517 digit
= (*s
++) - '0';
518 if (WILL_OVERFLOW_TIME(initTtlLo
, digit
))
519 initTtlLo
= TIME_MAX
;
521 initTtlLo
= initTtlLo
* 10 + digit
;
524 initTtlLo
= ONE_HOUR
;
527 while (s
< s_end
&& is_whitespace(*s
))
529 if (s
+ 1 >= s_end
|| *s
++ != COLON_CHAR
) {
530 p_error
= parse_bad_ttl_format_error
;
534 while (s
< s_end
&& is_whitespace(*s
))
537 while (s
< s_end
&& isdigit(*s
)) {
538 digit
= (*s
++) - '0';
539 if (WILL_OVERFLOW_TIME(initTtlHi
, digit
))
540 initTtlHi
= TIME_MAX
;
542 initTtlHi
= initTtlHi
* 10 + digit
;
545 initTtlHi
= initTtlLo
;
548 while (s
< s_end
&& is_whitespace(*s
))
550 if (s
>= s_end
|| *s
++ != COLON_CHAR
) {
551 p_error
= parse_bad_ttl_format_error
;
555 while (s
< s_end
&& is_whitespace(*s
))
558 while (s
< s_end
&& isdigit(*s
)) {
559 digit
= (*s
++) - '0';
560 if (WILL_OVERFLOW_TIME(ttl
, digit
))
563 ttl
= ttl
* 10 + digit
;
568 while (s
< s_end
&& is_whitespace(*s
))
571 p_error
= parse_bad_ttl_format_error
;
575 t_mapping
->initTtlLo
= initTtlLo
;
576 t_mapping
->initTtlHi
= initTtlHi
;
577 t_mapping
->ttl
= ttl
;
582 * FUNCTION: parse_name_fields
584 * Parse yp name fields
586 * RETURN VALUE: 0 on success, non-zero on failure
588 * INPUTS: attrib_value and attribute_end pointers.
592 parse_name_fields(const char *name_s
,
593 const char *name_s_end
,
594 __nis_table_mapping_t
*t_map
)
599 int parse_next_line
= 1;
601 const char *begin_fmt
;
603 const char *begin_token
;
604 const char *end_token
;
605 char *fmt_string
= NULL
;
606 __nis_mapping_format_t
*base
= NULL
;
607 __nis_mapping_item_t
*item
= NULL
;
608 __nis_mapping_element_t
*elmnt
= NULL
;
609 __nis_mapping_item_type_t item_type
= mit_nisplus
;
612 t_map
->numColumns
= 0;
614 for (; parse_next_line
> 0; parse_next_line
--) {
618 while (name_s
< name_s_end
&& *name_s
!= OPEN_PAREN_CHAR
)
620 if (name_s
== name_s_end
) {
621 p_error
= parse_unexpected_data_end_rule
;
624 while (name_s
< name_s_end
&& *name_s
!= DOUBLE_QUOTE_CHAR
)
626 if (name_s
== name_s_end
) {
627 p_error
= parse_unexpected_data_end_rule
;
630 begin_fmt
= ++name_s
; /* start of format string */
631 while (name_s
< name_s_end
&& *name_s
!= DOUBLE_QUOTE_CHAR
)
633 if (name_s
== name_s_end
) {
634 p_error
= parse_unexpected_data_end_rule
;
638 fmt_string
= s_strndup(begin_fmt
, end_fmt
- begin_fmt
);
639 if (fmt_string
== NULL
) {
640 p_error
= parse_no_mem_error
;
643 if (!get_mapping_format(fmt_string
, &base
, &n
, NULL
, FALSE
)) {
644 p_error
= parse_internal_error
;
651 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
652 if (base
[n
].type
!= mmt_item
&& base
[n
].type
654 if (base
[n
].type
== mmt_berstring_null
)
655 base
[n
].type
= mmt_berstring
;
658 while (name_s
< name_s_end
&& *name_s
!= COMMA_CHAR
)
660 name_s
++; /* now at comma char */
661 while (name_s
< name_s_end
&& is_whitespace(*name_s
))
663 begin_token
= name_s
++;
664 end_token
= name_s_end
;
665 name_s
= get_next_token(
666 &begin_token
, &end_token
, &token
);
667 if (name_s
== NULL
) {
668 p_error
= parse_item_expected_error
;
671 if (token
!= string_token
) {
672 p_error
= parse_item_expected_error
;
675 item
= (__nis_mapping_item_t
*)s_realloc(item
,
677 sizeof (__nis_mapping_item_t
));
679 p_error
= parse_no_mem_error
;
682 name_s
= get_mapping_item(begin_token
, name_s_end
,
683 &item
[nElements
], item_type
);
684 if (name_s
== NULL
) {
685 p_error
= parse_unmatched_escape
;
686 for (n
= 0; n
< (nElements
+ 1); n
++)
687 free_mapping_item(&item
[n
]);
688 free_mapping_format(base
);
693 if (p_error
!= no_parse_error
) {
694 for (n
= 0; n
< (nElements
+ 1); n
++)
695 free_mapping_item(&item
[n
]);
696 free_mapping_format(base
);
699 name_s
= skip_token(name_s
, name_s_end
, close_paren_token
);
700 if (name_s
== NULL
) {
701 p_error
= parse_close_paren_expected_error
;
702 for (n
= 0; n
< (nElements
+ 1); n
++)
703 free_mapping_item(&item
[n
]);
704 free_mapping_format(base
);
707 while (name_s
< name_s_end
&& is_whitespace(*name_s
))
709 if (*name_s
== COMMA_CHAR
)
712 if (nElements
== 0) {
713 p_error
= parse_no_match_item
;
714 for (n
= 0; n
< (nElements
+ 1); n
++)
715 free_mapping_item(&item
[n
]);
716 free_mapping_format(base
);
719 elmnt
= (__nis_mapping_element_t
*)s_realloc(elmnt
,
721 sizeof (__nis_mapping_element_t
));
723 for (n
= 0; n
< (nElements
+ 1); n
++)
724 free_mapping_item(&item
[n
]);
725 free_mapping_format(base
);
726 p_error
= parse_no_mem_error
;
729 elmnt
[numSplits
].type
= me_match
;
730 elmnt
[numSplits
].element
.match
.numItems
= nElements
;
731 elmnt
[numSplits
].element
.match
.item
= item
;
732 elmnt
[numSplits
].element
.match
.fmt
= base
;
737 t_map
->numSplits
= numSplits
;
738 n
= t_map
->numColumns
;
740 for (i
= n
, itm_count
= 0; i
< n
+ nElements
; i
++) {
741 if (t_map
->e
[numSplits
].element
.
742 match
.item
[itm_count
].name
) {
743 if (!add_column(t_map
,
744 t_map
->e
[numSplits
].element
.
745 match
.item
[itm_count
].name
))
749 p_error
= parse_internal_error
;
750 for (n
= 0; n
< (nElements
+ 1); n
++)
751 free_mapping_item(&item
[n
]);
752 free_mapping_format(base
);
753 free_mapping_element(elmnt
);
762 for (n
= 0; n
< t_map
->numColumns
; n
++) {
763 free_mapping_item(&item
[n
]);
768 free_mapping_element(elmnt
);
770 free_mapping_format(base
);
772 return (p_error
== no_parse_error
? 0 : -1);
776 * FUNCTION: parse_object_dn
778 * Parse object dn attribute
780 * RETURN VALUE: __nis_object_dn_t on success
783 * INPUT: the attribute value
786 static __nis_object_dn_t
*
787 parse_object_dn(const char *s
, const char *end
)
791 object_dn_token token
;
792 parse_object_dn_state dn_state
= dn_begin_parse
;
793 __nis_object_dn_t
*obj_dn
= NULL
;
794 __nis_object_dn_t
*next
= NULL
;
795 __nis_object_dn_t
*last
= NULL
;
798 * The attribute should be of form
799 * objectDN *( ";" objectDN )
800 * objectDN = readObjectSpec [":"[writeObjectSpec]]
801 * readObjectSpec = [baseAndScope [filterAttrValList]]
802 * writeObjectSpec = [baseAndScope [attrValList [":" deleteDisp]]]
808 s
= get_next_object_dn_token(&s_begin
, &s_end
, &token
);
812 if (token
== dn_no_token
|| token
== dn_semi_token
) {
819 if (token
== dn_no_token
)
821 dn_state
= dn_begin_parse
;
824 next
= (__nis_object_dn_t
*)
825 s_calloc(1, sizeof (__nis_object_dn_t
));
828 next
->read
.scope
= LDAP_SCOPE_ONELEVEL
;
829 next
->write
.scope
= LDAP_SCOPE_UNKNOWN
;
830 next
->delDisp
= dd_always
;
832 if (token
== dn_semi_token
)
837 if (token
== dn_ques_token
)
838 dn_state
= dn_got_read_q_scope
;
839 else if (token
== dn_colon_token
) {
840 dn_state
= dn_got_write_colon
;
841 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
843 if (!validate_dn(s_begin
, s_end
- s_begin
))
846 s_strndup_esc(s_begin
, s_end
- s_begin
);
847 dn_state
= dn_got_read_dn
;
851 if (token
== dn_ques_token
)
852 dn_state
= dn_got_read_q_scope
;
853 else if (token
== dn_colon_token
) {
854 dn_state
= dn_got_write_colon
;
855 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
857 p_error
= parse_object_dn_syntax_error
;
859 case dn_got_read_q_scope
:
860 if (token
== dn_ques_token
)
861 dn_state
= dn_got_read_q_filter
;
862 else if (token
== dn_colon_token
) {
863 dn_state
= dn_got_write_colon
;
864 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
865 } else if (token
== dn_base_token
) {
866 next
->read
.scope
= LDAP_SCOPE_BASE
;
867 dn_state
= dn_got_read_scope
;
868 } else if (token
== dn_one_token
) {
869 next
->read
.scope
= LDAP_SCOPE_ONELEVEL
;
870 dn_state
= dn_got_read_scope
;
871 } else if (token
== dn_sub_token
) {
872 next
->read
.scope
= LDAP_SCOPE_SUBTREE
;
873 dn_state
= dn_got_read_scope
;
875 p_error
= parse_invalid_scope
;
878 case dn_got_read_scope
:
879 if (token
== dn_ques_token
)
880 dn_state
= dn_got_read_q_filter
;
881 else if (token
== dn_colon_token
) {
882 dn_state
= dn_got_write_colon
;
883 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
885 p_error
= parse_object_dn_syntax_error
;
887 case dn_got_read_q_filter
:
888 if (token
== dn_ques_token
) {
889 p_error
= parse_object_dn_syntax_error
;
890 } else if (token
== dn_colon_token
) {
891 dn_state
= dn_got_write_colon
;
892 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
894 if (!validate_ldap_filter(s_begin
, s_end
))
897 s_strndup_esc(s_begin
, s_end
- s_begin
);
898 dn_state
= dn_got_read_filter
;
901 case dn_got_read_filter
:
902 if (token
== dn_ques_token
) {
903 p_error
= parse_object_dn_syntax_error
;
904 } else if (token
== dn_colon_token
) {
905 dn_state
= dn_got_write_colon
;
906 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
908 p_error
= parse_object_dn_syntax_error
;
910 case dn_got_write_colon
:
911 if (token
== dn_ques_token
)
912 dn_state
= dn_got_write_q_scope
;
913 else if (token
== dn_colon_token
) {
914 dn_state
= dn_got_delete_colon
;
916 if (!validate_dn(s_begin
, s_end
- s_begin
))
919 s_strndup_esc(s_begin
, s_end
- s_begin
);
920 dn_state
= dn_got_write_dn
;
923 case dn_got_write_dn
:
924 if (token
== dn_ques_token
)
925 dn_state
= dn_got_write_q_scope
;
926 else if (token
== dn_colon_token
) {
927 dn_state
= dn_got_delete_colon
;
929 p_error
= parse_object_dn_syntax_error
;
931 case dn_got_write_q_scope
:
932 if (token
== dn_ques_token
)
933 dn_state
= dn_got_write_q_filter
;
934 else if (token
== dn_colon_token
) {
935 dn_state
= dn_got_delete_colon
;
936 } else if (token
== dn_base_token
) {
937 next
->write
.scope
= LDAP_SCOPE_BASE
;
938 dn_state
= dn_got_write_scope
;
939 } else if (token
== dn_one_token
) {
940 next
->write
.scope
= LDAP_SCOPE_ONELEVEL
;
941 dn_state
= dn_got_write_scope
;
942 } else if (token
== dn_sub_token
) {
943 next
->write
.scope
= LDAP_SCOPE_SUBTREE
;
944 dn_state
= dn_got_write_scope
;
946 p_error
= parse_invalid_scope
;
949 case dn_got_write_scope
:
950 if (token
== dn_ques_token
)
951 dn_state
= dn_got_write_q_filter
;
952 else if (token
== dn_colon_token
) {
953 dn_state
= dn_got_delete_colon
;
955 p_error
= parse_object_dn_syntax_error
;
957 case dn_got_write_q_filter
:
958 if (token
== dn_ques_token
) {
959 p_error
= parse_object_dn_syntax_error
;
960 } else if (token
== dn_colon_token
) {
961 dn_state
= dn_got_delete_colon
;
963 if (!validate_ldap_filter(s_begin
, s_end
))
966 s_strndup_esc(s_begin
, s_end
- s_begin
);
967 dn_state
= dn_got_write_filter
;
970 case dn_got_write_filter
:
971 if (token
== dn_ques_token
) {
972 p_error
= parse_object_dn_syntax_error
;
973 } else if (token
== dn_colon_token
) {
974 dn_state
= dn_got_delete_colon
;
977 p_error
= parse_semi_expected_error
;
979 case dn_got_delete_colon
:
980 if (token
== dn_ques_token
) {
981 p_error
= parse_object_dn_syntax_error
;
982 } else if (token
== dn_colon_token
) {
983 p_error
= parse_object_dn_syntax_error
;
985 if (!get_deleteDisp(s_begin
, s_end
, next
))
987 dn_state
= dn_got_delete_dsp
;
990 case dn_got_delete_dsp
:
991 p_error
= parse_object_dn_syntax_error
;
995 if (p_error
!= no_parse_error
)
998 if (p_error
!= no_parse_error
) {
1000 free_object_dn(obj_dn
);
1002 free_object_dn(next
);
1004 } else if (next
!= NULL
) {
1009 } else if (obj_dn
== NULL
)
1010 obj_dn
= (__nis_object_dn_t
*)
1011 s_calloc(1, sizeof (__nis_object_dn_t
));
1017 * FUNCTION: get_mapping_rule
1019 * Parse mapping rule attributes
1021 * RETURN VALUE: None. Errors determined by p_error
1023 * INPUT: the attribute value and mapping rule type
1030 __nis_table_mapping_t
*tbl
,
1033 const char *end_s
= s
+ len
;
1034 const char *begin_token
;
1035 const char *end_token
;
1036 __nis_mapping_rule_t
**rule
= NULL
;
1037 __nis_mapping_rule_t
*next
= NULL
;
1038 /* __nis_mapping_rule_t **r; */
1045 * The attribute value is of the form
1046 * colattrspec *("," colattrspec)
1047 * colattrspec = lhs "=" rhs
1048 * lhs = lval | namespeclist
1049 * rhs = rval | [namespec]
1053 if ((next
= (__nis_mapping_rule_t
*)
1054 s_calloc(1, sizeof (__nis_mapping_rule_t
))) == NULL
)
1057 s
= get_lhs(s
, end_s
, &next
->lhs
,
1058 to_ldap
? mit_ldap
: mit_nisplus
);
1064 s1
= get_next_token(&begin_token
, &end_token
, &t
);
1067 if (!(to_ldap
&& (t
== comma_token
|| t
== no_token
))) {
1068 s
= get_rhs(s
, end_s
, &next
->rhs
,
1069 to_ldap
? mit_nisplus
: mit_ldap
);
1074 if (next
->lhs
.numElements
> 1 &&
1075 (next
->rhs
.numElements
!= 1 ||
1076 next
->rhs
.element
[0].type
!= me_split
)) {
1077 p_error
= parse_lhs_rhs_type_mismatch
;
1081 rule
= (__nis_mapping_rule_t
**)
1082 malloc(sizeof (__nis_mapping_rule_t
*));
1086 rule
= (__nis_mapping_rule_t
**)s_realloc(rule
,
1088 sizeof (__nis_mapping_rule_t
*));
1093 rule
[nRules
++] = next
;
1098 s
= get_next_token(&begin_token
, &end_token
, &t
);
1101 if (t
== comma_token
)
1103 if (t
!= no_token
) {
1104 p_error
= parse_unexpected_data_end_rule
;
1108 tbl
->numRulesToLDAP
= nRules
;
1109 tbl
->ruleToLDAP
= rule
;
1111 tbl
->numRulesFromLDAP
= nRules
;
1112 tbl
->ruleFromLDAP
= rule
;
1118 for (i
= 0; i
< nRules
; i
++)
1119 free_mapping_rule(rule
[i
]);
1123 free_mapping_rule(next
);
1129 * Parse left hand side of mapping rule attribute
1131 * RETURN VALUE: NULL if error
1132 * position of beginning rhs
1134 * INPUT: the attribute value and mapping rule type
1138 get_lhs(const char *s
,
1140 __nis_mapping_rlhs_t
*lhs
,
1141 __nis_mapping_item_type_t item_type
)
1144 const char *begin_token
;
1145 const char *end_token
;
1147 __nis_mapping_element_t
*e
= NULL
;
1150 * lhs can be expressed as:
1156 * lhs = lval | namespeclist
1157 * lval = "(" formatspec "," namespec *("," namespec) ")"
1158 * namespeclist = namespec | "(" namespec *("," namespec) ")"
1161 for (; p_error
== no_parse_error
; ) {
1164 s
= get_next_token(&begin_token
, &end_token
, &t
);
1167 if (t
== no_token
) {
1168 p_error
= parse_unexpected_data_end_rule
;
1172 e
= (__nis_mapping_element_t
*)
1173 s_calloc(1, sizeof (__nis_mapping_element_t
));
1177 if (t
== open_paren_token
) {
1184 s
= get_next_token(&begin_token
, &end_token
, &t
);
1188 if (t
== quoted_string_token
) {
1189 s
= get_lhs_match(sav_s
, end_s
, lhs
, item_type
);
1192 } else if (t
== string_token
) {
1193 s
= get_lhs_paren_item(sav_s
, end_s
, lhs
,
1198 p_error
= parse_bad_lhs_format_error
;
1201 } else if (t
== string_token
) {
1202 s
= get_mapping_item(begin_token
, end_s
,
1203 &e
->element
.item
, item_type
);
1207 if (!add_element(e
, lhs
))
1211 p_error
= parse_bad_lhs_format_error
;
1215 s
= skip_token(s
, end_s
, equal_token
);
1218 if (p_error
== no_parse_error
)
1222 free_mapping_element(e
);
1228 * FUNCTION: get_lhs_match
1230 * Parse left hand side of mapping rule attribute in case of
1233 * RETURN VALUE: NULL if error
1234 * position of beginning rhs
1236 * INPUT: the attribute value and mapping rule type
1243 __nis_mapping_rlhs_t
*lhs
,
1244 __nis_mapping_item_type_t item_type
)
1247 const char *begin_token
;
1248 const char *end_token
;
1251 char *fmt_string
= NULL
;
1252 __nis_mapping_format_t
*base
= NULL
;
1253 __nis_mapping_item_t
*item
= NULL
;
1254 __nis_mapping_item_t
*itm
;
1255 __nis_mapping_element_t
*e
;
1258 * lval = "(" formatspec "," namespec *("," namespec) ")"
1261 for (; p_error
== no_parse_error
; ) {
1264 s
= get_next_token(&begin_token
, &end_token
, &t
);
1265 if (s
== NULL
|| t
!= quoted_string_token
) {
1266 p_error
= parse_internal_error
;
1271 fmt_string
= s_strndup(begin_token
, end_token
- begin_token
);
1272 if (fmt_string
== NULL
)
1275 if (!get_mapping_format(fmt_string
, &base
, &n
, NULL
, FALSE
))
1278 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
1279 if (base
[n
].type
!= mmt_item
&&
1280 base
[n
].type
!= mmt_berstring
) {
1281 if (base
[n
].type
== mmt_berstring_null
)
1282 base
[n
].type
= mmt_berstring
;
1285 s
= skip_token(s
, end_s
, comma_token
);
1287 p_error
= parse_not_enough_extract_items
;
1292 s
= get_next_token(&begin_token
, &end_token
, &t
);
1295 if (t
!= string_token
) {
1296 p_error
= parse_item_expected_error
;
1299 itm
= (__nis_mapping_item_t
*)
1300 s_realloc(item
, (nElements
+ 1) *
1301 sizeof (__nis_mapping_item_t
));
1306 s
= get_mapping_item(begin_token
, end_s
,
1307 &item
[nElements
], item_type
);
1312 if (p_error
!= no_parse_error
)
1315 s
= skip_token(s
, end_s
, close_paren_token
);
1321 if (nElements
== 0) {
1322 p_error
= parse_no_match_item
;
1325 e
= (__nis_mapping_element_t
*)s_calloc(1,
1326 sizeof (__nis_mapping_element_t
));
1330 e
->element
.match
.numItems
= nElements
;
1331 e
->element
.match
.item
= item
;
1332 e
->element
.match
.fmt
= base
;
1333 lhs
->numElements
= 1;
1336 if (p_error
== no_parse_error
)
1340 for (n
= 0; n
< nElements
; n
++)
1341 free_mapping_item(&item
[n
]);
1346 free_mapping_format(base
);
1352 * FUNCTION: get_lhs_paren_item
1354 * Parse left hand side of mapping rule attribute in case of
1355 * (item1, ..., item-n)
1357 * RETURN VALUE: NULL if error
1358 * position of beginning rhs
1360 * INPUT: the attribute value and mapping rule type
1367 __nis_mapping_rlhs_t
*lhs
,
1368 __nis_mapping_item_type_t item_type
)
1371 const char *begin_token
;
1372 const char *end_token
;
1373 __nis_mapping_element_t
*e
= NULL
;
1378 * "(" namespec *("," namespec) ")"
1382 e
= (__nis_mapping_element_t
*)s_realloc(e
, (n
+ 1) *
1383 sizeof (__nis_mapping_element_t
));
1387 s
= get_mapping_item(s
, end_s
, &e
[n
].element
.item
,
1391 e
[n
].type
= me_item
;
1396 s
= get_next_token(&begin_token
, &end_token
, &t
);
1397 if (s
!= NULL
&& t
== close_paren_token
) {
1398 lhs
->numElements
= n
;
1400 e
[0].element
.item
.repeat
= TRUE
;
1404 if (s
== NULL
|| t
!= comma_token
) {
1405 p_error
= parse_comma_expected_error
;
1409 for (i
= 0; i
< n
; i
++)
1410 free_mapping_element(&e
[i
]);
1418 * Parse right hand side of mapping rule attribute
1420 * RETURN VALUE: NULL if error
1421 * position of beginning next mapping rule
1423 * INPUT: the attribute value and mapping rule type
1430 __nis_mapping_rlhs_t
*rhs
,
1431 __nis_mapping_item_type_t item_type
)
1434 * This handles the following cases:
1437 * (fmt, name-list) me_print
1438 * (item, fmt) me_extract
1442 const char *begin_token
;
1443 const char *end_token
;
1445 __nis_mapping_format_t
*fmt
= NULL
;
1446 __nis_mapping_element_t
*e
= NULL
;
1447 __nis_mapping_item_t item
;
1450 (void) memset(&item
, 0, sizeof (item
));
1452 for (; p_error
== no_parse_error
; ) {
1455 s
= get_next_token(&begin_token
, &end_token
, &t
);
1459 e
= (__nis_mapping_element_t
*)
1460 s_calloc(1, sizeof (__nis_mapping_element_t
));
1464 if (t
== string_token
) {
1465 s
= get_mapping_item(begin_token
, end_s
,
1466 &e
->element
.item
, item_type
);
1467 } else if (t
== open_paren_token
) {
1470 s
= get_next_token(&begin_token
, &end_token
, &t
);
1473 if (t
== string_token
) {
1474 /* (item, fmt) - me_extract */
1475 /* (item, "c") - me_split */
1476 s
= get_mapping_item(begin_token
, end_s
,
1482 s
= get_next_token(&begin_token
, &end_token
,
1486 else if (t
== close_paren_token
) {
1488 e
->element
.item
= item
;
1490 rhs
->numElements
= 1;
1493 } else if (t
!= comma_token
) {
1494 p_error
= parse_comma_expected_error
;
1500 s
= get_next_token(&begin_token
, &end_token
,
1502 if (s
== NULL
|| t
!= quoted_string_token
) {
1504 parse_format_string_expected_error
;
1508 if (end_token
== begin_token
+ 1 ||
1509 (*begin_token
== ESCAPE_CHAR
&&
1510 end_token
== begin_token
+ 2)) {
1512 e
->element
.split
.item
= item
;
1513 e
->element
.split
.delim
= *begin_token
;
1515 str
= s_strndup(begin_token
,
1516 end_token
- begin_token
);
1519 if (!get_mapping_format(str
, &fmt
,
1526 parse_bad_extract_format_spec
;
1529 e
->type
= me_extract
;
1530 e
->element
.extract
.item
= item
;
1531 e
->element
.extract
.fmt
= fmt
;
1533 s
= skip_token(s
, end_s
, close_paren_token
);
1534 } else if (t
== quoted_string_token
) {
1535 /* (fmt, name-list) - me_print */
1536 str
= s_strndup(begin_token
,
1537 end_token
- begin_token
);
1541 s
= get_print_mapping_element(s
, end_s
,
1546 p_error
= parse_start_rhs_unrecognized
;
1550 p_error
= parse_start_rhs_unrecognized
;
1555 rhs
->numElements
= 1;
1557 if (p_error
== no_parse_error
)
1562 free_mapping_format(fmt
);
1564 free_mapping_element(e
);
1565 free_mapping_item(&item
);
1571 * FUNCTION: get_print_mapping_element
1573 * Parse a print mapping rule attribute in case of the form
1576 * RETURN VALUE: NULL if error
1577 * position of beginning next mapping rule
1579 * INPUT: the attribute value and mapping rule type
1583 get_print_mapping_element(
1587 __nis_mapping_element_t
*e
,
1588 __nis_mapping_item_type_t item_type
)
1591 const char *begin_token
;
1592 const char *end_token
;
1595 __nis_mapping_format_t
*base
= NULL
;
1596 __nis_mapping_sub_element_t
*subElement
= NULL
;
1601 for (; p_error
== no_parse_error
; ) {
1602 if (!get_mapping_format(fmt_string
, &base
, &n
,
1603 &numSubElements
, TRUE
))
1605 subElement
= (__nis_mapping_sub_element_t
*)
1606 s_calloc(numSubElements
,
1607 sizeof (__nis_mapping_sub_element_t
));
1608 if (subElement
== NULL
)
1610 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
1611 if (base
[n
].type
!= mmt_item
&&
1612 base
[n
].type
!= mmt_berstring
) {
1613 if (base
[n
].type
== mmt_berstring_null
)
1614 base
[n
].type
= mmt_berstring
;
1617 if (nSub
< numSubElements
) {
1618 s
= skip_token(s
, end_s
, comma_token
);
1620 p_error
= parse_bad_print_format
;
1625 /* namelist may have parens around it */
1626 s
= get_subElement(s
, end_s
, &subElement
[nSub
],
1632 if (p_error
!= no_parse_error
)
1637 s
= get_next_token(&begin_token
, &end_token
, &t
);
1638 if (s
== NULL
|| t
== no_token
) {
1639 p_error
= parse_unexpected_data_end_rule
;
1641 } else if (t
== close_paren_token
) {
1644 } else if (t
== comma_token
) {
1647 s
= get_next_token(&begin_token
, &end_token
, &t
);
1648 if (s
!= NULL
&& t
== quoted_string_token
&&
1649 (end_token
== begin_token
+ 1 ||
1650 (*begin_token
== ESCAPE_CHAR
&&
1651 end_token
== begin_token
+ 2))) {
1652 if (numSubElements
!= 1 ||
1653 subElement
->type
== me_extract
||
1654 subElement
->type
== me_split
) {
1655 p_error
= parse_cannot_elide
;
1658 if (subElement
->type
== me_item
&&
1659 !subElement
->element
.item
.repeat
) {
1660 p_error
= parse_cannot_elide
;
1663 elide
= *begin_token
;
1667 p_error
= parse_bad_elide_char
;
1670 s
= skip_token(s
, end_s
, close_paren_token
);
1676 e
->element
.print
.fmt
= base
;
1677 e
->element
.print
.numSubElements
= numSubElements
;
1678 e
->element
.print
.subElement
= subElement
;
1679 e
->element
.print
.elide
= elide
;
1680 e
->element
.print
.doElide
= doElide
;
1682 if (p_error
== no_parse_error
)
1686 free_mapping_format(base
);
1687 if (subElement
!= NULL
) {
1688 for (n
= 0; n
< numSubElements
; n
++)
1689 free_mapping_sub_element(&subElement
[n
]);
1697 * FUNCTION: get_mapping_item
1699 * Parse attribute string to get mapping item
1701 * RETURN VALUE: NULL if error
1702 * position of beginning next token after item
1704 * INPUT: the attribute value and mapping rule type
1711 __nis_mapping_item_t
*item
,
1712 __nis_mapping_item_type_t type
)
1715 const char *begin_token
;
1716 const char *end_token
;
1722 (void) memset(item
, 0, sizeof (*item
));
1725 * A namepec is defined as follows:
1726 * namespec = ["ldap:"] attrspec [searchTriple] |
1727 * ["nis+:"] colspec [objectspec]
1729 * The form of the item is assumed to be as follows:
1730 * ["ldap:"] attrspec [searchTriple]
1731 * attrspec = attribute | "(" attribute ")"
1732 * searchTriple = ":" [baseDN] ["?" [scope] ["?" [filter]]]
1733 * baseDN = Base DN for search
1734 * scope = "base" | "one" | "sub"
1735 * filter = LDAP search filter
1737 * The form of the objectspec is as follows:
1738 * ["nis+:"] colspec [objectspec]
1739 * objectspec = objectname | "[" indexlist "]" tablename
1740 * objectname = The name of a NIS+ object
1741 * tablename = The name of a NIS+ table
1742 * indexlist = colspec ["," colspec]
1743 * colspec = colname "=" colvalue
1744 * colname = The name of a column in the table
1745 * colvalue = colvaluestring | \" colvaluestring \"
1748 for (; p_error
== no_parse_error
; ) {
1749 while (s
< end_s
&& is_whitespace(*s
))
1753 if ((begin_token
= skip_string("ldap:", s
,
1755 item
->type
= mit_ldap
;
1756 } else if ((begin_token
= skip_string("yp:", s
,
1758 item
->type
= mit_nisplus
;
1764 if ((begin_token
= skip_string("ldap:", s
,
1766 item
->type
= mit_ldap
;
1767 } else if ((begin_token
= skip_string("nis+:", s
,
1769 item
->type
= mit_nisplus
;
1770 } else if ((begin_token
= skip_string("nisplus:", s
,
1772 item
->type
= mit_nisplus
;
1780 s
= get_next_token(&begin_token
, &end_token
, &t
);
1781 if (s
== NULL
|| t
!= string_token
) {
1782 p_error
= parse_bad_item_format
;
1786 item
->name
= s_strndup_esc(begin_token
,
1787 end_token
- begin_token
);
1788 if (item
->name
== NULL
)
1790 if (item
->type
== mit_ldap
) {
1791 item
->searchSpec
.triple
.scope
= LDAP_SCOPE_UNKNOWN
;
1795 s
= get_next_token(&begin_token
, &end_token
, &t
);
1796 if (s
!= NULL
&& t
== colon_token
) {
1797 s
= get_search_triple(s
, end_s
,
1798 &item
->searchSpec
.triple
);
1803 } else if (item
->type
== mit_nisplus
) {
1804 while (s
< end_s
&& is_whitespace(*s
))
1807 if (s
< end_s
&& *s
== OPEN_BRACKET
) {
1808 index_string
= getIndex(&s
, end_s
);
1809 if (index_string
== NULL
)
1811 (void) parse_index(index_string
,
1812 index_string
+ strlen(index_string
),
1813 &item
->searchSpec
.obj
.index
);
1815 if (p_error
!= no_parse_error
)
1821 s
= get_next_token(&begin_token
, &end_token
, &t
);
1822 if (s
!= NULL
&& t
== string_token
) {
1823 name
= s_strndup_esc(begin_token
,
1824 end_token
- begin_token
);
1827 item
->searchSpec
.obj
.name
= name
;
1831 if (p_error
== no_parse_error
)
1834 free_mapping_item(item
);
1835 (void) memset(item
, 0, sizeof (*item
));
1842 get_print_sub_element(const char *s
,
1844 __nis_mapping_item_type_t type
,
1845 __nis_mapping_sub_element_t
*sub
)
1850 const char *begin_token
;
1851 const char *end_token
;
1853 __nis_mapping_format_t
*base
;
1854 __nis_mapping_item_t
*print_item
;
1857 base
= sub
->element
.print
.fmt
;
1858 print_item
= sub
->element
.print
.item
;
1859 sub
->element
.print
.doElide
= FALSE
;
1860 sub
->element
.print
.elide
= '\0';
1862 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
1863 if (base
[n
].type
!= mmt_item
&& base
[n
].type
!= mmt_berstring
) {
1864 if (base
[n
].type
== mmt_berstring_null
)
1865 base
[n
].type
= mmt_berstring
;
1868 s
= skip_token(s
, end_s
, comma_token
);
1870 p_error
= parse_bad_print_format
;
1876 s
= get_next_token(&begin_token
, &end_token
, &t
);
1880 * Determine if of the form
1881 * ("fmt", (item), "delim") or
1882 * ("fmt", item1, item2, ..., item n)
1884 if (t
== open_paren_token
) {
1885 if (sub
->element
.print
.numItems
!= 1) {
1886 p_error
= parse_invalid_print_arg
;
1889 s
= get_mapping_item(s
, end_s
, &print_item
[k
++], type
);
1890 s
= skip_token(s
, end_s
, close_paren_token
);
1891 s
= skip_token(s
, end_s
, comma_token
);
1893 p_error
= parse_bad_print_format
;
1898 s
= get_next_token(&begin_token
, &end_token
, &t
);
1901 if (t
!= quoted_string_token
||
1902 begin_token
+ 1 != end_token
) {
1903 p_error
= parse_bad_elide_char
;
1906 sub
->element
.print
.elide
= *begin_token
;
1907 sub
->element
.print
.doElide
= TRUE
;
1908 print_item
[0].repeat
= TRUE
;
1911 s
= get_mapping_item(begin_token
, end_s
,
1912 &print_item
[k
++], type
);
1916 if (p_error
!= no_parse_error
)
1920 return (p_error
== no_parse_error
? s
: NULL
);
1924 * FUNCTION: get_subElement
1926 * Parse attribute string to get sub element item
1928 * RETURN VALUE: NULL if error
1929 * position of beginning next token after item
1931 * INPUT: the attribute value and mapping rule type
1938 __nis_mapping_sub_element_t
*subelement
,
1939 __nis_mapping_item_type_t type
)
1942 const char *begin_token
;
1943 const char *end_token
;
1945 __nis_mapping_item_t item
;
1946 __nis_mapping_element_type_t e_type
;
1947 __nis_mapping_item_t
*print_item
= NULL
;
1948 __nis_mapping_format_t
*base
= NULL
;
1951 unsigned char delim
;
1952 __nis_mapping_sub_element_t sub
;
1955 * What is the form of we are expecting here
1958 * ("fmt", item1, item2, ..., item n) me_print
1959 * ("fmt", (item), "elide") me_print
1960 * (name, "delim") me_split
1961 * (item, "fmt") me_extract
1963 (void) memset(&item
, 0, sizeof (item
));
1965 for (; p_error
== no_parse_error
; ) {
1968 s
= get_next_token(&begin_token
, &end_token
, &t
);
1971 if (t
== string_token
) { /* me_item */
1972 s
= get_mapping_item(begin_token
, end_s
,
1973 &subelement
->element
.item
, type
);
1976 subelement
->type
= me_item
;
1978 } else if (t
!= open_paren_token
) {
1979 p_error
= parse_item_expected_error
;
1985 s
= get_next_token(&begin_token
, &end_token
, &t
);
1989 if (t
!= string_token
&& t
!= quoted_string_token
) {
1990 p_error
= parse_item_expected_error
;
1994 if (t
== string_token
) {
1995 /* me_item, me_extract or me_split */
1996 s
= get_mapping_item(begin_token
, end_s
, &item
, type
);
2002 s
= get_next_token(&begin_token
, &end_token
, &t
);
2004 p_error
= parse_unexpected_data_end_rule
;
2006 } else if (t
== close_paren_token
) {
2007 subelement
->type
= me_item
;
2009 subelement
->element
.item
= item
;
2011 while (s
< end_s
&& is_whitespace(*s
))
2015 parse_unexpected_data_end_rule
;
2018 if (*s
== DASH_CHAR
&& s
< end_s
) {
2026 subelement
->element
.item
.exItem
2028 (__nis_mapping_item_t
*)
2029 s_malloc(sizeof (__nis_mapping_item_t
));
2031 element
.item
.exItem
)
2033 s
= get_mapping_item(s
, end_s
,
2035 element
.item
.exItem
,
2039 parse_internal_error
;
2042 element
.item
.exItem
);
2044 element
.item
.exItem
=
2051 } else if (t
!= comma_token
) {
2052 p_error
= parse_comma_expected_error
;
2058 s
= get_next_token(&begin_token
, &end_token
, &t
);
2059 if (s
== NULL
|| t
!= quoted_string_token
) {
2060 p_error
= parse_format_string_expected_error
;
2063 if (end_token
== begin_token
+ 1 ||
2064 (*begin_token
== ESCAPE_CHAR
&&
2065 end_token
== begin_token
+ 2)) {
2067 delim
= (unsigned char)end_token
[-1];
2068 s
= skip_token(s
, end_s
, close_paren_token
);
2071 subelement
->element
.split
.item
= item
;
2072 subelement
->element
.split
.delim
= delim
;
2073 subelement
->type
= me_split
;
2076 e_type
= me_extract
;
2078 fmt_string
= s_strndup(begin_token
, end_token
- begin_token
);
2079 if (fmt_string
== NULL
)
2081 if (!get_mapping_format(fmt_string
, &base
, &n
, &numItems
,
2082 e_type
== me_print
)) {
2088 if (numItems
!= 1 && e_type
== me_extract
) {
2089 p_error
= numItems
== 0 ?
2090 parse_not_enough_extract_items
:
2091 parse_too_many_extract_items
;
2093 } else if (numItems
> 0 && e_type
== me_print
) {
2094 print_item
= (__nis_mapping_item_t
*)s_calloc(numItems
,
2095 sizeof (__nis_mapping_item_t
));
2096 if (print_item
== NULL
)
2100 if (e_type
== me_print
) {
2101 sub
.element
.print
.numItems
= numItems
;
2102 sub
.element
.print
.fmt
= base
;
2103 sub
.element
.print
.item
= print_item
;
2104 s
= get_print_sub_element(s
, end_s
, type
, &sub
);
2108 s
= skip_token(s
, end_s
, close_paren_token
);
2112 subelement
->type
= e_type
;
2113 if (e_type
== me_extract
) {
2114 subelement
->element
.extract
.fmt
= base
;
2115 subelement
->element
.extract
.item
= item
;
2117 subelement
->type
= me_print
;
2118 subelement
->element
.print
.fmt
= base
;
2119 subelement
->element
.print
.numItems
= numItems
;
2120 subelement
->element
.print
.item
= print_item
;
2121 subelement
->element
.print
.doElide
=
2122 sub
.element
.print
.doElide
;
2123 subelement
->element
.print
.elide
=
2124 sub
.element
.print
.elide
;
2126 if (p_error
== no_parse_error
)
2129 free_mapping_item(&item
);
2131 free_mapping_format(base
);
2133 for (n
= 0; n
< numItems
; n
++)
2134 free_mapping_item(&print_item
[n
]);
2142 * FUNCTION: skip_get_dn
2144 * Get first token after dn
2146 * RETURN VALUE: NULL if error (not valid dn)
2147 * position of beginning next token after dn
2149 * INPUT: the attribute value
2153 skip_get_dn(const char *dn
, const char *end
)
2156 bool_t in_quote
= FALSE
;
2157 bool_t goteq
= FALSE
;
2158 bool_t gotch
= FALSE
;
2159 bool_t done
= FALSE
;
2160 bool_t last_comma
= FALSE
;
2161 const char *last_dn
= dn
;
2177 case DOUBLE_QUOTE_CHAR
:
2178 in_quote
= !in_quote
;
2181 case CLOSE_PAREN_CHAR
:
2185 case SEMI_COLON_CHAR
:
2189 if (!goteq
|| !gotch
)
2193 if (*dn
!= PLUS_SIGN
)
2195 last_comma
= *dn
== COMMA_CHAR
;
2202 if (!gotch
|| goteq
)
2211 if (!is_whitespace(*dn
))
2218 if (!in_quote
&& goteq
&& gotch
)
2226 * FUNCTION: get_ldap_filter_element
2228 * Get an ldap filter element for a given string
2230 * RETURN VALUE: NULL if error
2231 * __nis_mapping_element_t if success
2233 * INPUT: the string to parse
2236 static __nis_mapping_element_t
*
2237 get_ldap_filter_element(
2243 const char *begin_token
;
2244 const char *end_token
;
2246 __nis_mapping_element_t
*e
= NULL
;
2250 s
= get_next_token(&begin_token
, &end_token
, &t
);
2251 if (s
== NULL
|| t
!= open_paren_token
)
2256 s
= get_next_token(&begin_token
, &end_token
, &t
);
2257 if (s
== NULL
|| t
!= quoted_string_token
)
2260 format_str
= s_strndup(begin_token
, end_token
- begin_token
);
2261 if (format_str
== NULL
)
2263 e
= (__nis_mapping_element_t
*)
2264 s_calloc(1, sizeof (__nis_mapping_element_t
));
2266 (void) get_print_mapping_element(s
, end_s
,
2267 format_str
, e
, mit_nisplus
);
2268 if (p_error
!= no_parse_error
) {
2269 free_mapping_element(e
);
2278 * FUNCTION: get_search_triple
2280 * Get the search triple or if NULL determine if valid
2282 * RETURN VALUE: NULL if error
2283 * position of beginning next token after
2286 * INPUT: the attribute value
2293 __nis_search_triple_t
*triple
2296 const char *begin_token
;
2297 const char *end_token
;
2298 char *search_base
= NULL
;
2299 int scope
= LDAP_SCOPE_ONELEVEL
;
2300 char *filter
= NULL
;
2302 __nis_mapping_element_t
2306 * The form of the searchTriple is assumed to be as follows:
2307 * searchTriple = [baseDN] ["?" [scope] ["?" [filter]]]
2308 * baseDN = Base DN for search
2309 * scope = "base" | "one" | "sub"
2310 * filter = LDAP search filter
2312 for (; p_error
== no_parse_error
; ) {
2313 while (s
< end_s
&& is_whitespace(*s
))
2318 if (!IS_TERMINAL_CHAR(*s
)) {
2320 s
= skip_get_dn(begin_token
, end_s
);
2322 p_error
= parse_invalid_dn
;
2325 if (triple
!= NULL
) {
2326 search_base
= s_strndup(begin_token
,
2328 if (search_base
== NULL
)
2331 while (s
< end_s
&& is_whitespace(*s
))
2337 if (!IS_TERMINAL_CHAR(*s
)) {
2338 p_error
= parse_bad_ldap_item_format
;
2341 if (*s
!= QUESTION_MARK
)
2345 while (s
< end_s
&& is_whitespace(*s
))
2350 /* base, one, or sub, or empty value */
2351 if (!IS_TERMINAL_CHAR(*s
)) {
2352 if ((s1
= skip_string("base", s
, end_s
- s
)) != NULL
) {
2353 scope
= LDAP_SCOPE_BASE
;
2354 } else if ((s1
= skip_string("one", s
, end_s
- s
)) !=
2356 scope
= LDAP_SCOPE_ONELEVEL
;
2357 } else if ((s1
= skip_string("sub", s
, end_s
- s
)) !=
2359 scope
= LDAP_SCOPE_SUBTREE
;
2360 } else if (s
+ 1 < end_s
&& *s
!= QUESTION_MARK
) {
2361 p_error
= parse_invalid_scope
;
2366 while (s
< end_s
&& is_whitespace(*s
))
2372 if (*s
!= QUESTION_MARK
)
2375 while (s
< end_s
&& is_whitespace(*s
))
2377 if (s
== end_s
|| IS_TERMINAL_CHAR(*s
))
2380 /* LDAP search filter */
2381 if (*s
== OPEN_PAREN_CHAR
) {
2384 s
= get_ldap_filter(&begin_token
, &end_token
);
2388 element
= get_ldap_filter_element(begin_token
, end_token
);
2389 if (element
!= NULL
)
2394 s
= get_ava_list(&begin_token
, &end_token
, TRUE
);
2400 filter
= s_strndup(begin_token
, s
- begin_token
);
2401 if (p_error
== no_parse_error
)
2404 if (p_error
== no_parse_error
&& triple
!= NULL
) {
2405 triple
->base
= search_base
;
2406 triple
->scope
= scope
;
2407 triple
->attrs
= filter
;
2408 triple
->element
= element
;
2416 if (element
!= NULL
) {
2417 free_mapping_element(element
);
2420 return (p_error
== no_parse_error
? s
: NULL
);
2424 * FUNCTION: get_mapping_format
2426 * Get the __nis_mapping_format_t from the string
2428 * RETURN VALUE: FALSE if error
2429 * TRUE if __nis_mapping_format_t returned
2431 * INPUT: the format string
2436 const char *fmt_string
,
2437 __nis_mapping_format_t
**fmt
,
2440 bool_t print_mapping
)
2442 const char *f
= fmt_string
;
2444 __nis_mapping_format_t
*b
;
2445 __nis_mapping_format_t
*base
= NULL
;
2451 base
= (__nis_mapping_format_t
*)
2452 s_calloc(1, sizeof (__nis_mapping_format_t
));
2456 base
->type
= mmt_begin
;
2460 b
= (__nis_mapping_format_t
*)s_realloc(
2461 base
, (n
+ 1) * sizeof (__nis_mapping_format_t
));
2466 base
[n
].type
= mmt_end
;
2476 f
= get_next_print_format_item(f
, ef
, &base
[n
]);
2478 f
= get_next_extract_format_item(f
, ef
, &base
[n
]);
2483 if (base
[n
].type
== mmt_item
||
2484 base
[n
].type
== mmt_berstring
)
2489 free_mapping_format(base
);
2494 * FUNCTION: getIndex
2496 * Returns a string containing the index
2498 * RETURN VALUE: NULL if error
2499 * a string containing the index
2501 * INPUT: attribute containing the index
2505 getIndex(const char **s_cur
, const char *s_end
)
2507 const char *s
= *s_cur
+ 1;
2513 bool_t in_quotes
= FALSE
;
2516 while (s
< s_end
&& is_whitespace(*s
))
2518 for (s1
= s
; s1
< s_end
; s1
++) {
2519 if (*s1
== ESCAPE_CHAR
)
2521 else if (*s1
== DOUBLE_QUOTE_CHAR
) {
2522 in_quotes
= !in_quotes
;
2523 } else if (in_quotes
)
2525 else if (*s1
== CLOSE_BRACKET
) {
2526 if (--n_brackets
== 0)
2528 } else if (*s1
== OPEN_BRACKET
)
2532 if (n_brackets
== 0) {
2533 index
= s_strndup(s
, s1
- s
);
2534 if (index
!= NULL
) {
2535 s_index_end
= index
+ (s1
- s
);
2537 for (s_index
= index
; s_index
< s_index_end
;
2539 if (*s_index
== ESCAPE_CHAR
) {
2540 *s_index1
++ = *s_index
++;
2541 } else if (*s_index
== DOUBLE_QUOTE_CHAR
) {
2542 in_quotes
= !in_quotes
;
2543 } else if (!in_quotes
&&
2544 is_whitespace(*s_index
)) {
2547 *s_index1
++ = *s_index
;
2549 *s_index1
= *s_index
;
2553 while (s
< s_end
&& is_whitespace(*s
))
2558 p_error
= parse_mismatched_brackets
;
2564 * FUNCTION: parse_index
2566 * Parse attribute string to get __nis_index_t
2568 * RETURN VALUE: FALSE if error
2569 * TRUE if __nis_index_t returned
2571 * INPUT: the attribute value to parse
2575 parse_index(const char *s
, const char *end_s
, __nis_index_t
*index
)
2577 const char *begin_token
;
2578 const char *end_token
;
2579 char *name_str
= NULL
;
2581 char *fmt_string
= NULL
;
2582 __nis_mapping_format_t
*v
= NULL
;
2583 __nis_mapping_format_t
**value
;
2588 (void) memset(index
, 0, sizeof (*index
));
2592 s
= skip_token(s
, end_s
, comma_token
);
2594 p_error
= parse_bad_index_format
;
2600 s
= get_next_token(&begin_token
, &end_token
, &t
);
2603 if (t
!= string_token
) {
2604 p_error
= parse_bad_index_format
;
2607 s
= skip_token(s
, end_s
, equal_token
);
2609 p_error
= parse_bad_index_format
;
2612 if (index
!= NULL
) {
2613 name_str
= s_strndup_esc(begin_token
,
2614 end_token
- begin_token
);
2615 if (name_str
== NULL
)
2620 s
= get_next_token(&begin_token
, &end_token
, &t
);
2623 if (t
!= string_token
&& t
!= quoted_string_token
) {
2624 p_error
= parse_bad_index_format
;
2627 fmt_string
= s_strndup(begin_token
, end_token
- begin_token
);
2628 if (fmt_string
== NULL
)
2630 if (!get_mapping_format(fmt_string
, &v
, NULL
, NULL
, FALSE
))
2634 if (index
!= NULL
) {
2635 name
= s_realloc(index
->name
,
2636 (n
+ 1) * sizeof (char *));
2639 value
= s_realloc(index
->value
,
2640 (n
+ 1) * sizeof (__nis_mapping_format_t
*));
2647 index
->numIndexes
= ++n
;
2649 index
->value
= value
;
2650 } else if (v
!= NULL
) {
2651 free_mapping_format(v
);
2655 if (p_error
!= no_parse_error
) {
2658 free_mapping_format(v
);
2663 return (p_error
!= no_parse_error
);
2667 * FUNCTION: get_deleteDisp
2669 * Parse deleteDisp. Sets p_error if an error occurred.
2671 * RETURN VALUE: TRUE on success
2672 * FAILURE on failure
2674 * INPUT: begin and end of string and __nis_object_dn_t
2678 get_deleteDisp(const char *s_begin
, const char *s_end
,
2679 __nis_object_dn_t
*obj_dn
)
2682 * deleteDisp: "always" | perDbId | "never"
2683 * perDbId: "dbid" "=" delDatabaseId
2686 if (same_string("always", s_begin
, s_end
- s_begin
)) {
2687 obj_dn
->delDisp
= dd_always
;
2688 } else if (same_string("never", s_begin
, s_end
- s_begin
)) {
2689 obj_dn
->delDisp
= dd_never
;
2690 } else if ((s_begin
= skip_string("dbid", s_begin
, s_end
- s_begin
))
2692 obj_dn
->delDisp
= dd_perDbId
;
2693 while (s_begin
< s_end
&& is_whitespace(*s_begin
))
2695 if (s_begin
== s_end
|| *s_begin
!= EQUAL_CHAR
) {
2696 p_error
= parse_object_dn_syntax_error
;
2699 while (s_begin
< s_end
&& is_whitespace(*s_begin
))
2701 while (s_begin
< s_end
&& is_whitespace(s_end
[-1]))
2703 if (s_begin
== s_end
) {
2704 p_error
= parse_object_dn_syntax_error
;
2707 s_strndup(s_begin
, s_end
- s_begin
);
2711 p_error
= parse_object_dn_syntax_error
;
2713 return (p_error
== no_parse_error
);