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
= NULL
;
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
]);
1344 if (fmt_string
!= NULL
)
1347 free_mapping_format(base
);
1353 * FUNCTION: get_lhs_paren_item
1355 * Parse left hand side of mapping rule attribute in case of
1356 * (item1, ..., item-n)
1358 * RETURN VALUE: NULL if error
1359 * position of beginning rhs
1361 * INPUT: the attribute value and mapping rule type
1368 __nis_mapping_rlhs_t
*lhs
,
1369 __nis_mapping_item_type_t item_type
)
1372 const char *begin_token
;
1373 const char *end_token
;
1374 __nis_mapping_element_t
*e
= NULL
;
1379 * "(" namespec *("," namespec) ")"
1383 e
= (__nis_mapping_element_t
*)s_realloc(e
, (n
+ 1) *
1384 sizeof (__nis_mapping_element_t
));
1388 s
= get_mapping_item(s
, end_s
, &e
[n
].element
.item
,
1392 e
[n
].type
= me_item
;
1397 s
= get_next_token(&begin_token
, &end_token
, &t
);
1398 if (s
!= NULL
&& t
== close_paren_token
) {
1399 lhs
->numElements
= n
;
1401 e
[0].element
.item
.repeat
= TRUE
;
1405 if (s
== NULL
|| t
!= comma_token
) {
1406 p_error
= parse_comma_expected_error
;
1410 for (i
= 0; i
< n
; i
++)
1411 free_mapping_element(&e
[i
]);
1420 * Parse right hand side of mapping rule attribute
1422 * RETURN VALUE: NULL if error
1423 * position of beginning next mapping rule
1425 * INPUT: the attribute value and mapping rule type
1432 __nis_mapping_rlhs_t
*rhs
,
1433 __nis_mapping_item_type_t item_type
)
1436 * This handles the following cases:
1439 * (fmt, name-list) me_print
1440 * (item, fmt) me_extract
1444 const char *begin_token
;
1445 const char *end_token
;
1447 __nis_mapping_format_t
*fmt
= NULL
;
1448 __nis_mapping_element_t
*e
= NULL
;
1449 __nis_mapping_item_t item
;
1452 (void) memset(&item
, 0, sizeof (item
));
1454 for (; p_error
== no_parse_error
; ) {
1457 s
= get_next_token(&begin_token
, &end_token
, &t
);
1461 e
= (__nis_mapping_element_t
*)
1462 s_calloc(1, sizeof (__nis_mapping_element_t
));
1466 if (t
== string_token
) {
1467 s
= get_mapping_item(begin_token
, end_s
,
1468 &e
->element
.item
, item_type
);
1469 } else if (t
== open_paren_token
) {
1472 s
= get_next_token(&begin_token
, &end_token
, &t
);
1475 if (t
== string_token
) {
1476 /* (item, fmt) - me_extract */
1477 /* (item, "c") - me_split */
1478 s
= get_mapping_item(begin_token
, end_s
,
1484 s
= get_next_token(&begin_token
, &end_token
,
1488 else if (t
== close_paren_token
) {
1490 e
->element
.item
= item
;
1492 rhs
->numElements
= 1;
1495 } else if (t
!= comma_token
) {
1496 p_error
= parse_comma_expected_error
;
1502 s
= get_next_token(&begin_token
, &end_token
,
1504 if (s
== NULL
|| t
!= quoted_string_token
) {
1506 parse_format_string_expected_error
;
1510 if (end_token
== begin_token
+ 1 ||
1511 (*begin_token
== ESCAPE_CHAR
&&
1512 end_token
== begin_token
+ 2)) {
1514 e
->element
.split
.item
= item
;
1515 e
->element
.split
.delim
= *begin_token
;
1517 str
= s_strndup(begin_token
,
1518 end_token
- begin_token
);
1521 if (!get_mapping_format(str
, &fmt
,
1528 parse_bad_extract_format_spec
;
1531 e
->type
= me_extract
;
1532 e
->element
.extract
.item
= item
;
1533 e
->element
.extract
.fmt
= fmt
;
1535 s
= skip_token(s
, end_s
, close_paren_token
);
1536 } else if (t
== quoted_string_token
) {
1537 /* (fmt, name-list) - me_print */
1538 str
= s_strndup(begin_token
,
1539 end_token
- begin_token
);
1543 s
= get_print_mapping_element(s
, end_s
,
1548 p_error
= parse_start_rhs_unrecognized
;
1552 p_error
= parse_start_rhs_unrecognized
;
1557 rhs
->numElements
= 1;
1559 if (p_error
== no_parse_error
)
1565 free_mapping_format(fmt
);
1567 free_mapping_element(e
);
1568 free_mapping_item(&item
);
1574 * FUNCTION: get_print_mapping_element
1576 * Parse a print mapping rule attribute in case of the form
1579 * RETURN VALUE: NULL if error
1580 * position of beginning next mapping rule
1582 * INPUT: the attribute value and mapping rule type
1586 get_print_mapping_element(
1590 __nis_mapping_element_t
*e
,
1591 __nis_mapping_item_type_t item_type
)
1594 const char *begin_token
;
1595 const char *end_token
;
1598 __nis_mapping_format_t
*base
= NULL
;
1599 __nis_mapping_sub_element_t
*subElement
= NULL
;
1604 for (; p_error
== no_parse_error
; ) {
1605 if (!get_mapping_format(fmt_string
, &base
, &n
,
1606 &numSubElements
, TRUE
))
1608 subElement
= (__nis_mapping_sub_element_t
*)
1609 s_calloc(numSubElements
,
1610 sizeof (__nis_mapping_sub_element_t
));
1611 if (subElement
== NULL
)
1613 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
1614 if (base
[n
].type
!= mmt_item
&&
1615 base
[n
].type
!= mmt_berstring
) {
1616 if (base
[n
].type
== mmt_berstring_null
)
1617 base
[n
].type
= mmt_berstring
;
1620 if (nSub
< numSubElements
) {
1621 s
= skip_token(s
, end_s
, comma_token
);
1623 p_error
= parse_bad_print_format
;
1628 /* namelist may have parens around it */
1629 s
= get_subElement(s
, end_s
, &subElement
[nSub
],
1635 if (p_error
!= no_parse_error
)
1640 s
= get_next_token(&begin_token
, &end_token
, &t
);
1641 if (s
== NULL
|| t
== no_token
) {
1642 p_error
= parse_unexpected_data_end_rule
;
1644 } else if (t
== close_paren_token
) {
1647 } else if (t
== comma_token
) {
1650 s
= get_next_token(&begin_token
, &end_token
, &t
);
1651 if (s
!= NULL
&& t
== quoted_string_token
&&
1652 (end_token
== begin_token
+ 1 ||
1653 (*begin_token
== ESCAPE_CHAR
&&
1654 end_token
== begin_token
+ 2))) {
1655 if (numSubElements
!= 1 ||
1656 subElement
->type
== me_extract
||
1657 subElement
->type
== me_split
) {
1658 p_error
= parse_cannot_elide
;
1661 if (subElement
->type
== me_item
&&
1662 !subElement
->element
.item
.repeat
) {
1663 p_error
= parse_cannot_elide
;
1666 elide
= *begin_token
;
1670 p_error
= parse_bad_elide_char
;
1673 s
= skip_token(s
, end_s
, close_paren_token
);
1679 e
->element
.print
.fmt
= base
;
1680 e
->element
.print
.numSubElements
= numSubElements
;
1681 e
->element
.print
.subElement
= subElement
;
1682 e
->element
.print
.elide
= elide
;
1683 e
->element
.print
.doElide
= doElide
;
1685 if (p_error
== no_parse_error
)
1689 free_mapping_format(base
);
1690 if (subElement
!= NULL
) {
1691 for (n
= 0; n
< numSubElements
; n
++)
1692 free_mapping_sub_element(&subElement
[n
]);
1700 * FUNCTION: get_mapping_item
1702 * Parse attribute string to get mapping item
1704 * RETURN VALUE: NULL if error
1705 * position of beginning next token after item
1707 * INPUT: the attribute value and mapping rule type
1714 __nis_mapping_item_t
*item
,
1715 __nis_mapping_item_type_t type
)
1718 const char *begin_token
;
1719 const char *end_token
;
1725 (void) memset(item
, 0, sizeof (*item
));
1728 * A namepec is defined as follows:
1729 * namespec = ["ldap:"] attrspec [searchTriple] |
1730 * ["nis+:"] colspec [objectspec]
1732 * The form of the item is assumed to be as follows:
1733 * ["ldap:"] attrspec [searchTriple]
1734 * attrspec = attribute | "(" attribute ")"
1735 * searchTriple = ":" [baseDN] ["?" [scope] ["?" [filter]]]
1736 * baseDN = Base DN for search
1737 * scope = "base" | "one" | "sub"
1738 * filter = LDAP search filter
1740 * The form of the objectspec is as follows:
1741 * ["nis+:"] colspec [objectspec]
1742 * objectspec = objectname | "[" indexlist "]" tablename
1743 * objectname = The name of a NIS+ object
1744 * tablename = The name of a NIS+ table
1745 * indexlist = colspec ["," colspec]
1746 * colspec = colname "=" colvalue
1747 * colname = The name of a column in the table
1748 * colvalue = colvaluestring | \" colvaluestring \"
1751 for (; p_error
== no_parse_error
; ) {
1752 while (s
< end_s
&& is_whitespace(*s
))
1756 if ((begin_token
= skip_string("ldap:", s
,
1758 item
->type
= mit_ldap
;
1759 } else if ((begin_token
= skip_string("yp:", s
,
1761 item
->type
= mit_nisplus
;
1767 if ((begin_token
= skip_string("ldap:", s
,
1769 item
->type
= mit_ldap
;
1770 } else if ((begin_token
= skip_string("nis+:", s
,
1772 item
->type
= mit_nisplus
;
1773 } else if ((begin_token
= skip_string("nisplus:", s
,
1775 item
->type
= mit_nisplus
;
1783 s
= get_next_token(&begin_token
, &end_token
, &t
);
1784 if (s
== NULL
|| t
!= string_token
) {
1785 p_error
= parse_bad_item_format
;
1789 item
->name
= s_strndup_esc(begin_token
,
1790 end_token
- begin_token
);
1791 if (item
->name
== NULL
)
1793 if (item
->type
== mit_ldap
) {
1794 item
->searchSpec
.triple
.scope
= LDAP_SCOPE_UNKNOWN
;
1798 s
= get_next_token(&begin_token
, &end_token
, &t
);
1799 if (s
!= NULL
&& t
== colon_token
) {
1800 s
= get_search_triple(s
, end_s
,
1801 &item
->searchSpec
.triple
);
1806 } else if (item
->type
== mit_nisplus
) {
1807 while (s
< end_s
&& is_whitespace(*s
))
1810 if (s
< end_s
&& *s
== OPEN_BRACKET
) {
1811 index_string
= getIndex(&s
, end_s
);
1812 if (index_string
== NULL
)
1814 (void) parse_index(index_string
,
1815 index_string
+ strlen(index_string
),
1816 &item
->searchSpec
.obj
.index
);
1818 if (p_error
!= no_parse_error
)
1824 s
= get_next_token(&begin_token
, &end_token
, &t
);
1825 if (s
!= NULL
&& t
== string_token
) {
1826 name
= s_strndup_esc(begin_token
,
1827 end_token
- begin_token
);
1830 item
->searchSpec
.obj
.name
= name
;
1834 if (p_error
== no_parse_error
)
1837 free_mapping_item(item
);
1838 (void) memset(item
, 0, sizeof (*item
));
1845 get_print_sub_element(const char *s
,
1847 __nis_mapping_item_type_t type
,
1848 __nis_mapping_sub_element_t
*sub
)
1853 const char *begin_token
;
1854 const char *end_token
;
1856 __nis_mapping_format_t
*base
;
1857 __nis_mapping_item_t
*print_item
;
1860 base
= sub
->element
.print
.fmt
;
1861 print_item
= sub
->element
.print
.item
;
1862 sub
->element
.print
.doElide
= FALSE
;
1863 sub
->element
.print
.elide
= '\0';
1865 for (n
= 0; base
[n
].type
!= mmt_end
; n
++) {
1866 if (base
[n
].type
!= mmt_item
&& base
[n
].type
!= mmt_berstring
) {
1867 if (base
[n
].type
== mmt_berstring_null
)
1868 base
[n
].type
= mmt_berstring
;
1871 s
= skip_token(s
, end_s
, comma_token
);
1873 p_error
= parse_bad_print_format
;
1879 s
= get_next_token(&begin_token
, &end_token
, &t
);
1883 * Determine if of the form
1884 * ("fmt", (item), "delim") or
1885 * ("fmt", item1, item2, ..., item n)
1887 if (t
== open_paren_token
) {
1888 if (sub
->element
.print
.numItems
!= 1) {
1889 p_error
= parse_invalid_print_arg
;
1892 s
= get_mapping_item(s
, end_s
, &print_item
[k
++], type
);
1893 s
= skip_token(s
, end_s
, close_paren_token
);
1894 s
= skip_token(s
, end_s
, comma_token
);
1896 p_error
= parse_bad_print_format
;
1901 s
= get_next_token(&begin_token
, &end_token
, &t
);
1904 if (t
!= quoted_string_token
||
1905 begin_token
+ 1 != end_token
) {
1906 p_error
= parse_bad_elide_char
;
1909 sub
->element
.print
.elide
= *begin_token
;
1910 sub
->element
.print
.doElide
= TRUE
;
1911 print_item
[0].repeat
= TRUE
;
1914 s
= get_mapping_item(begin_token
, end_s
,
1915 &print_item
[k
++], type
);
1919 if (p_error
!= no_parse_error
)
1923 return (p_error
== no_parse_error
? s
: NULL
);
1927 * FUNCTION: get_subElement
1929 * Parse attribute string to get sub element item
1931 * RETURN VALUE: NULL if error
1932 * position of beginning next token after item
1934 * INPUT: the attribute value and mapping rule type
1941 __nis_mapping_sub_element_t
*subelement
,
1942 __nis_mapping_item_type_t type
)
1945 const char *begin_token
;
1946 const char *end_token
;
1948 __nis_mapping_item_t item
;
1949 __nis_mapping_element_type_t e_type
;
1950 __nis_mapping_item_t
*print_item
= NULL
;
1951 __nis_mapping_format_t
*base
= NULL
;
1954 unsigned char delim
;
1955 __nis_mapping_sub_element_t sub
;
1958 * What is the form of we are expecting here
1961 * ("fmt", item1, item2, ..., item n) me_print
1962 * ("fmt", (item), "elide") me_print
1963 * (name, "delim") me_split
1964 * (item, "fmt") me_extract
1966 (void) memset(&item
, 0, sizeof (item
));
1968 for (; p_error
== no_parse_error
; ) {
1971 s
= get_next_token(&begin_token
, &end_token
, &t
);
1974 if (t
== string_token
) { /* me_item */
1975 s
= get_mapping_item(begin_token
, end_s
,
1976 &subelement
->element
.item
, type
);
1979 subelement
->type
= me_item
;
1981 } else if (t
!= open_paren_token
) {
1982 p_error
= parse_item_expected_error
;
1988 s
= get_next_token(&begin_token
, &end_token
, &t
);
1992 if (t
!= string_token
&& t
!= quoted_string_token
) {
1993 p_error
= parse_item_expected_error
;
1997 if (t
== string_token
) {
1998 /* me_item, me_extract or me_split */
1999 s
= get_mapping_item(begin_token
, end_s
, &item
, type
);
2005 s
= get_next_token(&begin_token
, &end_token
, &t
);
2007 p_error
= parse_unexpected_data_end_rule
;
2009 } else if (t
== close_paren_token
) {
2010 subelement
->type
= me_item
;
2012 subelement
->element
.item
= item
;
2014 while (s
< end_s
&& is_whitespace(*s
))
2018 parse_unexpected_data_end_rule
;
2021 if (*s
== DASH_CHAR
&& s
< end_s
) {
2029 subelement
->element
.item
.exItem
2031 (__nis_mapping_item_t
*)
2032 s_malloc(sizeof (__nis_mapping_item_t
));
2034 element
.item
.exItem
)
2036 s
= get_mapping_item(s
, end_s
,
2038 element
.item
.exItem
,
2042 parse_internal_error
;
2045 element
.item
.exItem
);
2047 element
.item
.exItem
=
2054 } else if (t
!= comma_token
) {
2055 p_error
= parse_comma_expected_error
;
2061 s
= get_next_token(&begin_token
, &end_token
, &t
);
2062 if (s
== NULL
|| t
!= quoted_string_token
) {
2063 p_error
= parse_format_string_expected_error
;
2066 if (end_token
== begin_token
+ 1 ||
2067 (*begin_token
== ESCAPE_CHAR
&&
2068 end_token
== begin_token
+ 2)) {
2070 delim
= (unsigned char)end_token
[-1];
2071 s
= skip_token(s
, end_s
, close_paren_token
);
2074 subelement
->element
.split
.item
= item
;
2075 subelement
->element
.split
.delim
= delim
;
2076 subelement
->type
= me_split
;
2079 e_type
= me_extract
;
2081 fmt_string
= s_strndup(begin_token
, end_token
- begin_token
);
2082 if (fmt_string
== NULL
)
2084 if (!get_mapping_format(fmt_string
, &base
, &n
, &numItems
,
2085 e_type
== me_print
)) {
2091 if (numItems
!= 1 && e_type
== me_extract
) {
2092 p_error
= numItems
== 0 ?
2093 parse_not_enough_extract_items
:
2094 parse_too_many_extract_items
;
2096 } else if (numItems
> 0 && e_type
== me_print
) {
2097 print_item
= (__nis_mapping_item_t
*)s_calloc(numItems
,
2098 sizeof (__nis_mapping_item_t
));
2099 if (print_item
== NULL
)
2103 if (e_type
== me_print
) {
2104 sub
.element
.print
.numItems
= numItems
;
2105 sub
.element
.print
.fmt
= base
;
2106 sub
.element
.print
.item
= print_item
;
2107 s
= get_print_sub_element(s
, end_s
, type
, &sub
);
2111 s
= skip_token(s
, end_s
, close_paren_token
);
2115 subelement
->type
= e_type
;
2116 if (e_type
== me_extract
) {
2117 subelement
->element
.extract
.fmt
= base
;
2118 subelement
->element
.extract
.item
= item
;
2120 subelement
->type
= me_print
;
2121 subelement
->element
.print
.fmt
= base
;
2122 subelement
->element
.print
.numItems
= numItems
;
2123 subelement
->element
.print
.item
= print_item
;
2124 subelement
->element
.print
.doElide
=
2125 sub
.element
.print
.doElide
;
2126 subelement
->element
.print
.elide
=
2127 sub
.element
.print
.elide
;
2129 if (p_error
== no_parse_error
)
2132 free_mapping_item(&item
);
2134 free_mapping_format(base
);
2136 for (n
= 0; n
< numItems
; n
++)
2137 free_mapping_item(&print_item
[n
]);
2145 * FUNCTION: skip_get_dn
2147 * Get first token after dn
2149 * RETURN VALUE: NULL if error (not valid dn)
2150 * position of beginning next token after dn
2152 * INPUT: the attribute value
2156 skip_get_dn(const char *dn
, const char *end
)
2159 bool_t in_quote
= FALSE
;
2160 bool_t goteq
= FALSE
;
2161 bool_t gotch
= FALSE
;
2162 bool_t done
= FALSE
;
2163 bool_t last_comma
= FALSE
;
2164 const char *last_dn
= dn
;
2180 case DOUBLE_QUOTE_CHAR
:
2181 in_quote
= !in_quote
;
2184 case CLOSE_PAREN_CHAR
:
2188 case SEMI_COLON_CHAR
:
2192 if (!goteq
|| !gotch
)
2196 if (*dn
!= PLUS_SIGN
)
2198 last_comma
= *dn
== COMMA_CHAR
;
2205 if (!gotch
|| goteq
)
2214 if (!is_whitespace(*dn
))
2221 if (!in_quote
&& goteq
&& gotch
)
2229 * FUNCTION: get_ldap_filter_element
2231 * Get an ldap filter element for a given string
2233 * RETURN VALUE: NULL if error
2234 * __nis_mapping_element_t if success
2236 * INPUT: the string to parse
2239 static __nis_mapping_element_t
*
2240 get_ldap_filter_element(
2246 const char *begin_token
;
2247 const char *end_token
;
2249 __nis_mapping_element_t
*e
= NULL
;
2253 s
= get_next_token(&begin_token
, &end_token
, &t
);
2254 if (s
== NULL
|| t
!= open_paren_token
)
2259 s
= get_next_token(&begin_token
, &end_token
, &t
);
2260 if (s
== NULL
|| t
!= quoted_string_token
)
2263 format_str
= s_strndup(begin_token
, end_token
- begin_token
);
2264 if (format_str
== NULL
)
2266 e
= (__nis_mapping_element_t
*)
2267 s_calloc(1, sizeof (__nis_mapping_element_t
));
2269 (void) get_print_mapping_element(s
, end_s
,
2270 format_str
, e
, mit_nisplus
);
2271 if (p_error
!= no_parse_error
) {
2272 free_mapping_element(e
);
2281 * FUNCTION: get_search_triple
2283 * Get the search triple or if NULL determine if valid
2285 * RETURN VALUE: NULL if error
2286 * position of beginning next token after
2289 * INPUT: the attribute value
2296 __nis_search_triple_t
*triple
2299 const char *begin_token
;
2300 const char *end_token
;
2301 char *search_base
= NULL
;
2302 int scope
= LDAP_SCOPE_ONELEVEL
;
2303 char *filter
= NULL
;
2305 __nis_mapping_element_t
2309 * The form of the searchTriple is assumed to be as follows:
2310 * searchTriple = [baseDN] ["?" [scope] ["?" [filter]]]
2311 * baseDN = Base DN for search
2312 * scope = "base" | "one" | "sub"
2313 * filter = LDAP search filter
2315 for (; p_error
== no_parse_error
; ) {
2316 while (s
< end_s
&& is_whitespace(*s
))
2321 if (!IS_TERMINAL_CHAR(*s
)) {
2323 s
= skip_get_dn(begin_token
, end_s
);
2325 p_error
= parse_invalid_dn
;
2328 if (triple
!= NULL
) {
2329 search_base
= s_strndup(begin_token
,
2331 if (search_base
== NULL
)
2334 while (s
< end_s
&& is_whitespace(*s
))
2340 if (!IS_TERMINAL_CHAR(*s
)) {
2341 p_error
= parse_bad_ldap_item_format
;
2344 if (*s
!= QUESTION_MARK
)
2348 while (s
< end_s
&& is_whitespace(*s
))
2353 /* base, one, or sub, or empty value */
2354 if (!IS_TERMINAL_CHAR(*s
)) {
2355 if ((s1
= skip_string("base", s
, end_s
- s
)) != NULL
) {
2356 scope
= LDAP_SCOPE_BASE
;
2357 } else if ((s1
= skip_string("one", s
, end_s
- s
)) !=
2359 scope
= LDAP_SCOPE_ONELEVEL
;
2360 } else if ((s1
= skip_string("sub", s
, end_s
- s
)) !=
2362 scope
= LDAP_SCOPE_SUBTREE
;
2363 } else if (s
+ 1 < end_s
&& *s
!= QUESTION_MARK
) {
2364 p_error
= parse_invalid_scope
;
2369 while (s
< end_s
&& is_whitespace(*s
))
2375 if (*s
!= QUESTION_MARK
)
2378 while (s
< end_s
&& is_whitespace(*s
))
2380 if (s
== end_s
|| IS_TERMINAL_CHAR(*s
))
2383 /* LDAP search filter */
2384 if (*s
== OPEN_PAREN_CHAR
) {
2387 s
= get_ldap_filter(&begin_token
, &end_token
);
2391 element
= get_ldap_filter_element(begin_token
, end_token
);
2392 if (element
!= NULL
)
2397 s
= get_ava_list(&begin_token
, &end_token
, TRUE
);
2403 filter
= s_strndup(begin_token
, s
- begin_token
);
2404 if (p_error
== no_parse_error
)
2407 if (p_error
== no_parse_error
&& triple
!= NULL
) {
2408 triple
->base
= search_base
;
2409 triple
->scope
= scope
;
2410 triple
->attrs
= filter
;
2411 triple
->element
= element
;
2417 if (search_base
!= NULL
)
2421 if (element
!= NULL
) {
2422 free_mapping_element(element
);
2425 return (p_error
== no_parse_error
? s
: NULL
);
2429 * FUNCTION: get_mapping_format
2431 * Get the __nis_mapping_format_t from the string
2433 * RETURN VALUE: FALSE if error
2434 * TRUE if __nis_mapping_format_t returned
2436 * INPUT: the format string
2441 const char *fmt_string
,
2442 __nis_mapping_format_t
**fmt
,
2445 bool_t print_mapping
)
2447 const char *f
= fmt_string
;
2449 __nis_mapping_format_t
*b
;
2450 __nis_mapping_format_t
*base
= NULL
;
2456 base
= (__nis_mapping_format_t
*)
2457 s_calloc(1, sizeof (__nis_mapping_format_t
));
2461 base
->type
= mmt_begin
;
2465 b
= (__nis_mapping_format_t
*)s_realloc(
2466 base
, (n
+ 1) * sizeof (__nis_mapping_format_t
));
2471 base
[n
].type
= mmt_end
;
2481 f
= get_next_print_format_item(f
, ef
, &base
[n
]);
2483 f
= get_next_extract_format_item(f
, ef
, &base
[n
]);
2488 if (base
[n
].type
== mmt_item
||
2489 base
[n
].type
== mmt_berstring
)
2494 free_mapping_format(base
);
2499 * FUNCTION: getIndex
2501 * Returns a string containing the index
2503 * RETURN VALUE: NULL if error
2504 * a string containing the index
2506 * INPUT: attribute containing the index
2510 getIndex(const char **s_cur
, const char *s_end
)
2512 const char *s
= *s_cur
+ 1;
2518 bool_t in_quotes
= FALSE
;
2521 while (s
< s_end
&& is_whitespace(*s
))
2523 for (s1
= s
; s1
< s_end
; s1
++) {
2524 if (*s1
== ESCAPE_CHAR
)
2526 else if (*s1
== DOUBLE_QUOTE_CHAR
) {
2527 in_quotes
= !in_quotes
;
2528 } else if (in_quotes
)
2530 else if (*s1
== CLOSE_BRACKET
) {
2531 if (--n_brackets
== 0)
2533 } else if (*s1
== OPEN_BRACKET
)
2537 if (n_brackets
== 0) {
2538 index
= s_strndup(s
, s1
- s
);
2539 if (index
!= NULL
) {
2540 s_index_end
= index
+ (s1
- s
);
2542 for (s_index
= index
; s_index
< s_index_end
;
2544 if (*s_index
== ESCAPE_CHAR
) {
2545 *s_index1
++ = *s_index
++;
2546 } else if (*s_index
== DOUBLE_QUOTE_CHAR
) {
2547 in_quotes
= !in_quotes
;
2548 } else if (!in_quotes
&&
2549 is_whitespace(*s_index
)) {
2552 *s_index1
++ = *s_index
;
2554 *s_index1
= *s_index
;
2558 while (s
< s_end
&& is_whitespace(*s
))
2563 p_error
= parse_mismatched_brackets
;
2569 * FUNCTION: parse_index
2571 * Parse attribute string to get __nis_index_t
2573 * RETURN VALUE: FALSE if error
2574 * TRUE if __nis_index_t returned
2576 * INPUT: the attribute value to parse
2580 parse_index(const char *s
, const char *end_s
, __nis_index_t
*index
)
2582 const char *begin_token
;
2583 const char *end_token
;
2584 char *name_str
= NULL
;
2586 char *fmt_string
= NULL
;
2587 __nis_mapping_format_t
*v
= NULL
;
2588 __nis_mapping_format_t
**value
;
2593 (void) memset(index
, 0, sizeof (*index
));
2597 s
= skip_token(s
, end_s
, comma_token
);
2599 p_error
= parse_bad_index_format
;
2605 s
= get_next_token(&begin_token
, &end_token
, &t
);
2608 if (t
!= string_token
) {
2609 p_error
= parse_bad_index_format
;
2612 s
= skip_token(s
, end_s
, equal_token
);
2614 p_error
= parse_bad_index_format
;
2617 if (index
!= NULL
) {
2618 name_str
= s_strndup_esc(begin_token
,
2619 end_token
- begin_token
);
2620 if (name_str
== NULL
)
2625 s
= get_next_token(&begin_token
, &end_token
, &t
);
2628 if (t
!= string_token
&& t
!= quoted_string_token
) {
2629 p_error
= parse_bad_index_format
;
2632 fmt_string
= s_strndup(begin_token
, end_token
- begin_token
);
2633 if (fmt_string
== NULL
)
2635 if (!get_mapping_format(fmt_string
, &v
, NULL
, NULL
, FALSE
))
2639 if (index
!= NULL
) {
2640 name
= s_realloc(index
->name
,
2641 (n
+ 1) * sizeof (char *));
2644 value
= s_realloc(index
->value
,
2645 (n
+ 1) * sizeof (__nis_mapping_format_t
*));
2652 index
->numIndexes
= ++n
;
2654 index
->value
= value
;
2655 } else if (v
!= NULL
) {
2656 free_mapping_format(v
);
2660 if (p_error
!= no_parse_error
) {
2661 if (name_str
!= NULL
)
2664 free_mapping_format(v
);
2665 if (fmt_string
!= NULL
)
2670 return (p_error
!= no_parse_error
);
2674 * FUNCTION: get_deleteDisp
2676 * Parse deleteDisp. Sets p_error if an error occurred.
2678 * RETURN VALUE: TRUE on success
2679 * FAILURE on failure
2681 * INPUT: begin and end of string and __nis_object_dn_t
2685 get_deleteDisp(const char *s_begin
, const char *s_end
,
2686 __nis_object_dn_t
*obj_dn
)
2689 * deleteDisp: "always" | perDbId | "never"
2690 * perDbId: "dbid" "=" delDatabaseId
2693 if (same_string("always", s_begin
, s_end
- s_begin
)) {
2694 obj_dn
->delDisp
= dd_always
;
2695 } else if (same_string("never", s_begin
, s_end
- s_begin
)) {
2696 obj_dn
->delDisp
= dd_never
;
2697 } else if ((s_begin
= skip_string("dbid", s_begin
, s_end
- s_begin
))
2699 obj_dn
->delDisp
= dd_perDbId
;
2700 while (s_begin
< s_end
&& is_whitespace(*s_begin
))
2702 if (s_begin
== s_end
|| *s_begin
!= EQUAL_CHAR
) {
2703 p_error
= parse_object_dn_syntax_error
;
2706 while (s_begin
< s_end
&& is_whitespace(*s_begin
))
2708 while (s_begin
< s_end
&& is_whitespace(s_end
[-1]))
2710 if (s_begin
== s_end
) {
2711 p_error
= parse_object_dn_syntax_error
;
2714 s_strndup(s_begin
, s_end
- s_begin
);
2718 p_error
= parse_object_dn_syntax_error
;
2720 return (p_error
== no_parse_error
);