Print this page
5910 libnisdb won't build with modern GCC
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libnisdb/nis_parse_ldap_map.c
+++ new/usr/src/lib/libnisdb/nis_parse_ldap_map.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 + * Copyright 2015 Gary Mills
23 24 * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
24 25 * Use is subject to license terms.
25 26 */
26 27
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 28 #include <stdio.h>
30 29 #include <string.h>
31 30 #include <stdlib.h>
32 31 #include <ctype.h>
33 32 #include <fcntl.h>
34 33 #include <unistd.h>
35 34 #include <locale.h>
36 35
37 36 #include "ldap_parse.h"
38 37 #include "nis_parse_ldap_conf.h"
38 +#include "nis_parse_ldap_yp_util.h"
39 +#include "nis_parse_ldap_util.h"
39 40
40 41 /* other attribute functions */
41 42 static char *getIndex(const char **s_cur, const char *end_s);
42 43 static bool_t get_ttls(const char *s, const char *s_end,
43 44 __nis_table_mapping_t *t_mapping);
44 45 static __nis_object_dn_t *parse_object_dn(const char *s, const char *end);
45 46 static int parse_name_fields(const char *name_s, const char *name_s_end,
46 47 __nis_table_mapping_t *t_mapping);
47 48 static void get_mapping_rule(const char *s, int len,
48 49 __nis_table_mapping_t *tbl, bool_t to_ldap);
49 50 static bool_t get_deleteDisp(const char *s_begin, const char *s_end,
50 51 __nis_object_dn_t *obj_dn);
51 52
52 53 /* mapping rule functions */
53 54 static const char *get_lhs(const char *s, const char *end_s,
54 55 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type);
55 56 static const char *get_lhs_match(const char *s, const char *end_s,
56 57 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type);
57 58 static const char *get_lhs_paren_item(const char *s, const char *end_s,
58 59 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type);
59 60 static const char *get_rhs(const char *s, const char *end_s,
60 61 __nis_mapping_rlhs_t *lhs, __nis_mapping_item_type_t item_type);
61 62 static const char *get_mapping_item(const char *s, const char *end_s,
62 63 __nis_mapping_item_t *item, __nis_mapping_item_type_t type);
63 64 static const char *get_print_mapping_element(const char *s,
64 65 const char *end_s, char *fmt_string, __nis_mapping_element_t *e,
65 66 __nis_mapping_item_type_t item_type);
66 67 static const char *get_subElement(const char *s, const char *end_s,
67 68 __nis_mapping_sub_element_t *subelement,
68 69 __nis_mapping_item_type_t type);
69 70 static bool_t get_mapping_format(const char *fmt_string,
70 71 __nis_mapping_format_t **fmt, int *nfmt, int *numItems,
71 72 bool_t print_mapping);
72 73 extern __yp_domain_context_t ypDomains;
73 74
74 75 /*
75 76 * FUNCTION: add_mapping_attribute
76 77 *
77 78 * Adds the attribute value to __nis_table_mapping_t
78 79 * if the value is not yet set for the given database.
79 80 *
80 81 * RETURN VALUE: 0 on success, -1 on failure
81 82 *
82 83 * INPUT: attribute number and value
83 84 */
84 85
85 86 int
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
86 87 add_mapping_attribute(
87 88 config_key attrib_num,
88 89 const char *attrib_val,
89 90 int attrib_len,
90 91 __nis_table_mapping_t **table_mapping)
91 92 {
92 93 const char *s;
93 94 const char *attrib_end;
94 95 const char *db_id_end;
95 96 const char *begin_token;
96 - const char *end_token;
97 97 char *index_string;
98 98 __nis_object_dn_t *objectDN;
99 99 __nis_table_mapping_t *t_mapping;
100 100 __nis_table_mapping_t *t;
101 101
102 102 bool_t new_mapping = FALSE;
103 103 int nm;
104 104 char *tmp_dbId;
105 105
106 106 attrib_end = attrib_val + attrib_len;
107 107 for (s = attrib_val; s < attrib_end; s++)
108 108 if (*s == COLON_CHAR)
109 109 break;
110 110
111 111 if (s == attrib_end || *attrib_val == COLON_CHAR) {
112 112 p_error = parse_unexpected_data_end_rule;
113 113 return (-1);
114 114 }
115 115
116 116 db_id_end = s;
117 117 while (s > attrib_val && is_whitespace(s[-1]))
118 118 s--;
119 119
120 120 if (s == attrib_val) {
121 121 p_error = parse_unexpected_data_end_rule;
122 122 return (-1);
123 123 }
124 124
125 125 if (yp2ldap) {
126 126 tmp_dbId = s_strndup(attrib_val, s - attrib_val);
127 127 if (tmp_dbId == NULL) {
128 128 p_error = parse_no_mem_error;
129 129 return (-1);
130 130 }
131 131 if (strchr(tmp_dbId, COMMA_CHAR)) {
132 132 /* domain explicitly specified */
133 133 nm = check_domain_specific_order(tmp_dbId,
134 134 attrib_num, *table_mapping, &ypDomains);
135 135 /*
136 136 * No logging is needed here, as
137 137 * check_domain_specific_order
138 138 * will log any appropriate errors.
139 139 */
140 140 if (nm != 0) {
141 141 free(tmp_dbId);
142 142 return (-1);
143 143 }
144 144 }
145 145 free(tmp_dbId);
146 146 }
147 147
148 148 if ((t_mapping = find_table_mapping(attrib_val,
149 149 s - attrib_val, *table_mapping)) == NULL) {
150 150 /* No mapping with this id, create one */
151 151 t_mapping = (__nis_table_mapping_t *)
152 152 s_calloc(1, sizeof (__nis_table_mapping_t));
153 153
154 154 if (t_mapping == NULL) {
155 155 p_error = parse_no_mem_error;
156 156 return (-1);
157 157 }
158 158 (void) initialize_table_mapping(t_mapping);
159 159
160 160 /* dbId is the label before the colon */
161 161 t_mapping->dbId = s_strndup(attrib_val, s - attrib_val);
162 162 if (t_mapping->dbId == NULL) {
163 163 p_error = parse_no_mem_error;
164 164 free(t_mapping);
165 165 return (-1);
166 166 }
167 167 new_mapping = TRUE;
168 168 } else {
169 169 /* a table mapping already exists, use it */
170 170 new_mapping = FALSE;
171 171 }
172 172
173 173 s = db_id_end + 1;
174 174 while (s < attrib_end && is_whitespace(*s))
175 175 s++;
176 176
177 177 switch (attrib_num) {
178 178 case key_yp_map_flags:
179 179 if (t_mapping->usedns_flag != 0 ||
180 180 t_mapping->securemap_flag != 0) {
181 181 warn_duplicate_map(t_mapping->dbId,
182 182 attrib_num);
183 183 break;
184 184 }
185 185 while (is_whitespace(*s) && s < attrib_end)
186 186 s++;
187 187 while (s < attrib_end) {
188 188 if (s < attrib_end && *s == 'b')
189 189 t_mapping->usedns_flag = 1;
190 190 if (s < attrib_end && *s == 's')
191 191 t_mapping->securemap_flag = 1;
192 192 s++;
193 193 }
194 194 break;
195 195 case key_yp_comment_char:
196 196 if (t_mapping->commentChar !=
197 197 DEFAULT_COMMENT_CHAR) {
198 198 warn_duplicate_map(t_mapping->dbId, attrib_num);
199 199 break;
200 200 }
201 201 while (is_whitespace(*s) && s < attrib_end)
202 202 s++;
203 203 if (s < attrib_end && (s+1) < attrib_end &&
204 204 (s+2) <= attrib_end) {
205 205 while (is_whitespace(attrib_end[-1]))
206 206 attrib_end--;
207 207 while (*s != SINGLE_QUOTE_CHAR)
208 208 s++;
209 209 if (*s == SINGLE_QUOTE_CHAR &&
210 210 *(s+2) == SINGLE_QUOTE_CHAR) {
211 211 t_mapping->commentChar = *(s+1);
212 212 } else if (*s == SINGLE_QUOTE_CHAR &&
213 213 *(s+1) == SINGLE_QUOTE_CHAR) {
214 214 t_mapping->commentChar = NULL;
215 215 } else {
216 216 /* anything else is an error */
217 217 p_error = parse_bad_yp_comment_error;
218 218 }
219 219 break;
220 220 } else {
221 221 p_error = parse_bad_yp_comment_error;
222 222 break;
223 223 }
224 224 case key_yp_repeated_field_separators:
225 225 while (s < attrib_end && is_whitespace(*s))
226 226 s++;
227 227 if (s < attrib_end) {
228 228 while (is_whitespace(attrib_end[-1]))
229 229 attrib_end--;
230 230 while (s < attrib_end &&
231 231 *s != DOUBLE_QUOTE_CHAR)
232 232 s++;
233 233 s++;
234 234 begin_token = s;
235 235 while (s < attrib_end &&
236 236 *s != DOUBLE_QUOTE_CHAR) {
237 237 if (*s == ESCAPE_CHAR)
238 238 s++;
239 239 s++;
240 240 }
241 241 t_mapping->separatorStr =
242 242 s_strndup(begin_token, s - begin_token);
243 243 if (t_mapping->separatorStr == NULL)
244 244 break;
245 245 } else {
246 246 p_error = parse_bad_field_separator_error;
247 247 }
248 248 break;
249 249 case key_yp_name_fields:
250 250 case key_yp_split_field:
251 251 if (t_mapping->e || t_mapping->numSplits > 0) {
252 252 warn_duplicate_map(t_mapping->dbId,
253 253 attrib_num);
254 254 break;
255 255 }
256 256 if (parse_name_fields(s, attrib_end, t_mapping)) {
257 257 p_error = parse_bad_name_field;
258 258 }
259 259 break;
260 260 case key_yp_db_id_map:
261 261 case key_db_id_map:
262 262 if (t_mapping->objName != NULL) {
263 263 warn_duplicate_map(t_mapping->dbId, attrib_num);
264 264 break;
265 265 }
266 266
267 267 if (s < attrib_end && *s == OPEN_BRACKET) {
268 268 index_string = getIndex(&s, attrib_end);
269 269 if (index_string == NULL)
270 270 break;
271 271 (void) parse_index(index_string,
272 272 index_string + strlen(index_string),
273 273 &t_mapping->index);
274 274 free(index_string);
275 275 if (p_error != no_parse_error)
276 276 break;
277 277 }
278 278 while (is_whitespace(*s) && s < attrib_end)
279 279 s++;
280 280 if (s < attrib_end) {
281 281 while (is_whitespace(attrib_end[-1]))
282 282 attrib_end--;
283 283 t_mapping->objName =
284 284 s_strndup_esc(s, attrib_end - s);
285 285 } else {
286 286 if (yp2ldap) {
287 287 p_error = parse_bad_map_error;
288 288 } else {
289 289 t_mapping->objName = s_strndup(s, 0);
290 290 }
291 291 }
292 292 break;
293 293
294 294 case key_yp_entry_ttl:
295 295 case key_entry_ttl:
296 296 if (t_mapping->initTtlLo != (time_t)NO_VALUE_SET) {
297 297 warn_duplicate_map(t_mapping->dbId, attrib_num);
298 298 break;
299 299 }
300 300
301 301 if (!get_ttls(s, attrib_end, t_mapping))
302 302 p_error = parse_bad_ttl_format_error;
303 303 break;
304 304
305 305 case key_yp_ldap_object_dn:
306 306 case key_ldap_object_dn:
307 307 if (t_mapping->objectDN != NULL) {
308 308 warn_duplicate_map(t_mapping->dbId, attrib_num);
309 309 break;
310 310 }
311 311 objectDN = parse_object_dn(s, attrib_end);
312 312 if (objectDN == NULL)
313 313 break;
314 314 t_mapping->objectDN = objectDN;
315 315 t_mapping->seq_num = seq_num++;
316 316 break;
317 317
318 318 case key_nis_to_ldap_map:
319 319 case key_nisplus_to_ldap_map:
320 320 if (t_mapping->ruleToLDAP != 0) {
321 321 warn_duplicate_map(t_mapping->dbId, attrib_num);
322 322 break;
323 323 }
324 324
325 325 get_mapping_rule(s, attrib_end - s, t_mapping, TRUE);
326 326 break;
327 327
328 328 case key_ldap_to_nis_map:
329 329 case key_ldap_to_nisplus_map:
330 330 if (t_mapping->ruleFromLDAP != NULL) {
331 331 warn_duplicate_map(t_mapping->dbId, attrib_num);
332 332 break;
333 333 }
334 334
335 335 get_mapping_rule(s, attrib_end - s, t_mapping, FALSE);
336 336 break;
337 337
338 338 default:
339 339 p_error = parse_internal_error;
340 340 break;
341 341 }
342 342 if (p_error == no_parse_error) {
343 343 if (new_mapping) {
344 344 if (*table_mapping == NULL)
345 345 *table_mapping = t_mapping;
346 346 else {
347 347 for (t = *table_mapping; t->next != NULL;
348 348 t = t->next)
349 349 ;
350 350 t->next = t_mapping;
351 351 }
352 352 }
353 353 } else {
354 354 if (new_mapping)
355 355 free_table_mapping(t_mapping);
356 356 }
357 357 return (p_error == no_parse_error ? 0 : -1);
358 358 }
359 359
360 360 /*
361 361 * FUNCTION: add_ypdomains_attribute
362 362 *
363 363 * Adds the yp domains information to the __yp_domain_context_t
364 364 * structure.
365 365 *
366 366 * RETURN: 0 on success, -1 on failure
367 367 *
368 368 * INPUT: attribute number and value
369 369 */
370 370
↓ open down ↓ |
264 lines elided |
↑ open up ↑ |
371 371 int
372 372 add_ypdomains_attribute(
373 373 config_key attrib_num,
374 374 const char *attrib_val,
375 375 int attrib_len,
376 376 __yp_domain_context_t *ypDomains)
377 377 {
378 378 const char *s;
379 379 const char *attrib_end;
380 380 int numDomains = 0;
381 - int i;
382 - char *tmp_str;
383 - int ret = 0;
384 381
385 382 attrib_end = attrib_val + attrib_len;
386 383 for (s = attrib_val; s < attrib_end; s++) {
387 384 if (*s == COLON_CHAR) {
388 385 break;
389 386 }
390 387 }
391 388 while (s > attrib_val && is_whitespace(s[-1]))
392 389 s--;
393 390
394 391 if (s == attrib_val) {
395 392 p_error = parse_unexpected_data_end_rule;
396 393 return (-1);
397 394 }
398 395
399 396 if (ypDomains == NULL) {
400 397 /*
401 398 * No point allocating. We cant return the resulting structure,
402 399 * so just return failure. Should not ever happen because we
403 400 * are always called with a pointer to the global ypDomains
404 401 * structure.
405 402 */
406 403 return (-1);
407 404 }
408 405
409 406 switch (attrib_num) {
410 407 case key_yp_domain_context:
411 408 numDomains = ypDomains->numDomains;
412 409 ypDomains->domainLabels =
413 410 (char **)s_realloc(ypDomains->domainLabels,
414 411 (numDomains + 1) *
415 412 sizeof (ypDomains->domainLabels[0]));
416 413 if (ypDomains->domainLabels == NULL) {
417 414 p_error = parse_no_mem_error;
418 415 free_yp_domain_context(ypDomains);
419 416 break;
420 417 }
421 418 ypDomains->domainLabels[numDomains] =
422 419 s_strndup(attrib_val, s - attrib_val);
423 420 if (ypDomains->domainLabels[numDomains] == NULL) {
424 421 p_error = parse_no_mem_error;
425 422 free_yp_domain_context(ypDomains);
426 423 break;
427 424 }
428 425 ypDomains->numDomains = numDomains + 1;
429 426 while (s < attrib_end && is_whitespace(*s))
430 427 s++;
431 428 if (*s == COLON_CHAR)
432 429 s++;
433 430 while (s < attrib_end && is_whitespace(*s))
434 431 s++;
435 432 ypDomains->domains =
436 433 (char **)s_realloc(ypDomains->domains,
437 434 (numDomains + 1) *
438 435 sizeof (ypDomains->domains[0]));
439 436 if (ypDomains->domains == NULL) {
440 437 p_error = parse_no_mem_error;
441 438 free_yp_domain_context(ypDomains);
442 439 break;
443 440 }
444 441
445 442 if (s < attrib_end) {
446 443 while (is_whitespace(attrib_end[-1]))
447 444 attrib_end--;
448 445 ypDomains->domains[numDomains] =
449 446 s_strndup_esc(s, attrib_end - s);
450 447 if (ypDomains->domains[numDomains] == NULL) {
451 448 p_error = parse_no_mem_error;
452 449 free_yp_domain_context(ypDomains);
453 450 break;
454 451 }
455 452 } else {
456 453 p_error = parse_unexpected_yp_domain_end_error;
457 454 free(ypDomains->domainLabels[numDomains]);
458 455 ypDomains->domainLabels[numDomains] = NULL;
459 456 ypDomains->numDomains--;
460 457 free_yp_domain_context(ypDomains);
461 458 }
462 459 break;
463 460 case key_yppasswdd_domains:
464 461 ypDomains->yppasswddDomainLabels =
465 462 (char **)s_realloc(
466 463 ypDomains->yppasswddDomainLabels,
467 464 (ypDomains->numYppasswdd + 1) *
468 465 sizeof (ypDomains->yppasswddDomainLabels[0]));
469 466 if (ypDomains->yppasswddDomainLabels == NULL) {
470 467 p_error = parse_no_mem_error;
471 468 break;
472 469 }
473 470 ypDomains->yppasswddDomainLabels
474 471 [ypDomains->numYppasswdd] =
475 472 s_strndup(attrib_val, s - attrib_val);
476 473 if (ypDomains->yppasswddDomainLabels
477 474 [ypDomains->numYppasswdd] == NULL) {
478 475 p_error = parse_no_mem_error;
479 476 }
480 477 ypDomains->numYppasswdd++;
481 478 break;
482 479 }
483 480
484 481 return (p_error == no_parse_error ? 0 : -1);
485 482 }
486 483
487 484 /*
488 485 * FUNCTION: get_ttls
489 486 *
490 487 * Parse time to live attribute
491 488 *
492 489 * RETURN VALUE: TRUE on success, FALSE on failure
493 490 *
494 491 * INPUT: the attribute value
495 492 */
496 493
497 494 static bool_t
498 495 get_ttls(
499 496 const char *s,
500 497 const char *s_end,
501 498 __nis_table_mapping_t *t_mapping)
502 499 {
503 500 time_t initTtlHi = 0;
504 501 time_t initTtlLo = 0;
505 502 time_t ttl = 0;
506 503 time_t digit;
507 504
508 505 /*
509 506 * attribute should be of the form
510 507 * initialTTLlo ":" initialTTLhi ":" runningTTL
511 508 */
512 509
513 510 if (s == s_end) {
514 511 p_error = parse_bad_ttl_format_error;
515 512 return (FALSE);
516 513 }
517 514
518 515 if (isdigit(*s)) {
519 516 while (s < s_end && isdigit(*s)) {
520 517 digit = (*s++) - '0';
521 518 if (WILL_OVERFLOW_TIME(initTtlLo, digit))
522 519 initTtlLo = TIME_MAX;
523 520 else
524 521 initTtlLo = initTtlLo * 10 + digit;
525 522 }
526 523 } else {
527 524 initTtlLo = ONE_HOUR;
528 525 }
529 526
530 527 while (s < s_end && is_whitespace(*s))
531 528 s++;
532 529 if (s + 1 >= s_end || *s++ != COLON_CHAR) {
533 530 p_error = parse_bad_ttl_format_error;
534 531 return (FALSE);
535 532 }
536 533
537 534 while (s < s_end && is_whitespace(*s))
538 535 s++;
539 536 if (isdigit(*s)) {
540 537 while (s < s_end && isdigit(*s)) {
541 538 digit = (*s++) - '0';
542 539 if (WILL_OVERFLOW_TIME(initTtlHi, digit))
543 540 initTtlHi = TIME_MAX;
544 541 else
545 542 initTtlHi = initTtlHi * 10 + digit;
546 543 }
547 544 } else {
548 545 initTtlHi = initTtlLo;
549 546 }
550 547
551 548 while (s < s_end && is_whitespace(*s))
552 549 s++;
553 550 if (s >= s_end || *s++ != COLON_CHAR) {
554 551 p_error = parse_bad_ttl_format_error;
555 552 return (FALSE);
556 553 }
557 554
558 555 while (s < s_end && is_whitespace(*s))
559 556 s++;
560 557 if (isdigit(*s)) {
561 558 while (s < s_end && isdigit(*s)) {
562 559 digit = (*s++) - '0';
563 560 if (WILL_OVERFLOW_TIME(ttl, digit))
564 561 ttl = TIME_MAX;
565 562 else
566 563 ttl = ttl * 10 + digit;
567 564 }
568 565 } else {
569 566 ttl = ONE_HOUR;
570 567 }
571 568 while (s < s_end && is_whitespace(*s))
572 569 s++;
573 570 if (s != s_end) {
574 571 p_error = parse_bad_ttl_format_error;
575 572 return (FALSE);
576 573 }
577 574
578 575 t_mapping->initTtlLo = initTtlLo;
579 576 t_mapping->initTtlHi = initTtlHi;
580 577 t_mapping->ttl = ttl;
581 578 return (TRUE);
582 579 }
583 580
584 581 /*
585 582 * FUNCTION: parse_name_fields
586 583 *
587 584 * Parse yp name fields
588 585 *
589 586 * RETURN VALUE: 0 on success, non-zero on failure
590 587 *
591 588 * INPUTS: attrib_value and attribute_end pointers.
592 589 */
593 590
594 591 static int
595 592 parse_name_fields(const char *name_s,
596 593 const char *name_s_end,
597 594 __nis_table_mapping_t *t_map)
598 595 {
599 596 int i, n = 0;
600 597 int nElements = 0;
601 598 int numSplits = 0;
602 599 int parse_next_line = 1;
603 600 int itm_count = 0;
604 601 const char *begin_fmt;
605 602 const char *end_fmt;
606 603 const char *begin_token;
607 604 const char *end_token;
608 605 char *fmt_string = NULL;
609 606 __nis_mapping_format_t *base = NULL;
610 607 __nis_mapping_item_t *item = NULL;
611 608 __nis_mapping_element_t *elmnt = NULL;
612 609 __nis_mapping_item_type_t item_type = mit_nisplus;
613 610 token_type token;
614 611
615 612 t_map->numColumns = 0;
616 613
617 614 for (; parse_next_line > 0; parse_next_line--) {
618 615 nElements = 0;
619 616 item = NULL;
620 617 base = NULL;
621 618 while (name_s < name_s_end && *name_s != OPEN_PAREN_CHAR)
622 619 name_s++;
623 620 if (name_s == name_s_end) {
624 621 p_error = parse_unexpected_data_end_rule;
625 622 return (1);
626 623 }
627 624 while (name_s < name_s_end && *name_s != DOUBLE_QUOTE_CHAR)
628 625 name_s++;
629 626 if (name_s == name_s_end) {
630 627 p_error = parse_unexpected_data_end_rule;
631 628 return (1);
632 629 }
633 630 begin_fmt = ++name_s; /* start of format string */
634 631 while (name_s < name_s_end && *name_s != DOUBLE_QUOTE_CHAR)
635 632 name_s++;
636 633 if (name_s == name_s_end) {
637 634 p_error = parse_unexpected_data_end_rule;
638 635 return (1);
639 636 }
640 637 end_fmt = name_s;
641 638 fmt_string = s_strndup(begin_fmt, end_fmt - begin_fmt);
642 639 if (fmt_string == NULL) {
643 640 p_error = parse_no_mem_error;
644 641 return (2);
645 642 }
646 643 if (!get_mapping_format(fmt_string, &base, &n, NULL, FALSE)) {
647 644 p_error = parse_internal_error;
648 645 free(fmt_string);
649 646 fmt_string = NULL;
650 647 return (3);
651 648 }
652 649 free(fmt_string);
653 650 fmt_string = NULL;
654 651 for (n = 0; base[n].type != mmt_end; n++) {
655 652 if (base[n].type != mmt_item && base[n].type
656 653 != mmt_berstring) {
657 654 if (base[n].type == mmt_berstring_null)
658 655 base[n].type = mmt_berstring;
659 656 continue;
660 657 }
661 658 while (name_s < name_s_end && *name_s != COMMA_CHAR)
662 659 name_s++;
663 660 name_s++; /* now at comma char */
664 661 while (name_s < name_s_end && is_whitespace(*name_s))
665 662 name_s++;
666 663 begin_token = name_s++;
667 664 end_token = name_s_end;
668 665 name_s = get_next_token(
669 666 &begin_token, &end_token, &token);
670 667 if (name_s == NULL) {
671 668 p_error = parse_item_expected_error;
672 669 return (4);
673 670 }
674 671 if (token != string_token) {
675 672 p_error = parse_item_expected_error;
676 673 return (5);
677 674 }
678 675 item = (__nis_mapping_item_t *)s_realloc(item,
679 676 (nElements + 1) *
680 677 sizeof (__nis_mapping_item_t));
681 678 if (item == NULL) {
682 679 p_error = parse_no_mem_error;
683 680 return (2);
684 681 }
685 682 name_s = get_mapping_item(begin_token, name_s_end,
686 683 &item[nElements], item_type);
687 684 if (name_s == NULL) {
688 685 p_error = parse_unmatched_escape;
689 686 for (n = 0; n < (nElements + 1); n++)
690 687 free_mapping_item(&item[n]);
691 688 free_mapping_format(base);
692 689 return (4);
693 690 }
694 691 nElements++;
695 692 }
696 693 if (p_error != no_parse_error) {
697 694 for (n = 0; n < (nElements + 1); n++)
698 695 free_mapping_item(&item[n]);
699 696 free_mapping_format(base);
700 697 return (6);
701 698 }
702 699 name_s = skip_token(name_s, name_s_end, close_paren_token);
703 700 if (name_s == NULL) {
704 701 p_error = parse_close_paren_expected_error;
705 702 for (n = 0; n < (nElements + 1); n++)
706 703 free_mapping_item(&item[n]);
707 704 free_mapping_format(base);
708 705 return (4);
709 706 }
710 707 while (name_s < name_s_end && is_whitespace(*name_s))
711 708 name_s++;
712 709 if (*name_s == COMMA_CHAR)
713 710 parse_next_line++;
714 711
715 712 if (nElements == 0) {
716 713 p_error = parse_no_match_item;
717 714 for (n = 0; n < (nElements + 1); n++)
718 715 free_mapping_item(&item[n]);
719 716 free_mapping_format(base);
720 717 return (7);
721 718 }
722 719 elmnt = (__nis_mapping_element_t *)s_realloc(elmnt,
723 720 (numSplits + 1) *
724 721 sizeof (__nis_mapping_element_t));
725 722 if (elmnt == NULL) {
726 723 for (n = 0; n < (nElements + 1); n++)
727 724 free_mapping_item(&item[n]);
728 725 free_mapping_format(base);
729 726 p_error = parse_no_mem_error;
730 727 return (2);
731 728 }
732 729 elmnt[numSplits].type = me_match;
733 730 elmnt[numSplits].element.match.numItems = nElements;
734 731 elmnt[numSplits].element.match.item = item;
735 732 elmnt[numSplits].element.match.fmt = base;
736 733 item = NULL;
737 734 base = NULL;
738 735
739 736 t_map->e = elmnt;
740 737 t_map->numSplits = numSplits;
741 738 n = t_map->numColumns;
742 739
743 740 for (i = n, itm_count = 0; i < n + nElements; i++) {
744 741 if (t_map->e[numSplits].element.
745 742 match.item[itm_count].name) {
746 743 if (!add_column(t_map,
747 744 t_map->e[numSplits].element.
748 745 match.item[itm_count].name))
749 746 return (1);
750 747 itm_count++;
751 748 } else {
752 749 p_error = parse_internal_error;
753 750 for (n = 0; n < (nElements + 1); n++)
754 751 free_mapping_item(&item[n]);
755 752 free_mapping_format(base);
756 753 free_mapping_element(elmnt);
757 754 return (1);
758 755 }
759 756 }
760 757 numSplits++;
761 758 }
762 759 elmnt = NULL;
763 760
764 761 if (item != NULL) {
765 762 for (n = 0; n < t_map->numColumns; n++) {
766 763 free_mapping_item(&item[n]);
767 764 }
768 765 free(item);
769 766 }
770 767 if (elmnt != NULL)
771 768 free_mapping_element(elmnt);
772 769 if (base != NULL)
773 770 free_mapping_format(base);
774 771
775 772 return (p_error == no_parse_error ? 0 : -1);
776 773 }
777 774
778 775 /*
779 776 * FUNCTION: parse_object_dn
780 777 *
781 778 * Parse object dn attribute
782 779 *
783 780 * RETURN VALUE: __nis_object_dn_t on success
784 781 * NULL on failure
785 782 *
786 783 * INPUT: the attribute value
787 784 */
788 785
789 786 static __nis_object_dn_t *
790 787 parse_object_dn(const char *s, const char *end)
791 788 {
792 789 const char *s_begin;
793 790 const char *s_end;
794 791 object_dn_token token;
795 792 parse_object_dn_state dn_state = dn_begin_parse;
796 793 __nis_object_dn_t *obj_dn = NULL;
797 794 __nis_object_dn_t *next = NULL;
798 795 __nis_object_dn_t *last = NULL;
799 796
800 797 /*
801 798 * The attribute should be of form
802 799 * objectDN *( ";" objectDN )
803 800 * objectDN = readObjectSpec [":"[writeObjectSpec]]
804 801 * readObjectSpec = [baseAndScope [filterAttrValList]]
805 802 * writeObjectSpec = [baseAndScope [attrValList [":" deleteDisp]]]
806 803 */
807 804
808 805 while (s < end) {
809 806 s_begin = s;
810 807 s_end = end;
811 808 s = get_next_object_dn_token(&s_begin, &s_end, &token);
812 809 if (s == NULL)
813 810 break;
814 811
815 812 if (token == dn_no_token || token == dn_semi_token) {
816 813 if (obj_dn == NULL)
817 814 obj_dn = next;
818 815 else
819 816 last->next = next;
820 817 last = next;
821 818 next = NULL;
822 819 if (token == dn_no_token)
823 820 break;
824 821 dn_state = dn_begin_parse;
825 822 }
826 823 if (next == NULL) {
827 824 next = (__nis_object_dn_t *)
828 825 s_calloc(1, sizeof (__nis_object_dn_t));
829 826 if (next == NULL)
830 827 break;
831 828 next->read.scope = LDAP_SCOPE_ONELEVEL;
832 829 next->write.scope = LDAP_SCOPE_UNKNOWN;
833 830 next->delDisp = dd_always;
834 831 }
835 832 if (token == dn_semi_token)
836 833 continue;
837 834
838 835 switch (dn_state) {
839 836 case dn_begin_parse:
840 837 if (token == dn_ques_token)
841 838 dn_state = dn_got_read_q_scope;
842 839 else if (token == dn_colon_token) {
843 840 dn_state = dn_got_write_colon;
844 841 next->write.scope = LDAP_SCOPE_ONELEVEL;
845 842 } else {
846 843 if (!validate_dn(s_begin, s_end - s_begin))
847 844 break;
848 845 next->read.base =
849 846 s_strndup_esc(s_begin, s_end - s_begin);
850 847 dn_state = dn_got_read_dn;
851 848 }
852 849 break;
853 850 case dn_got_read_dn:
854 851 if (token == dn_ques_token)
855 852 dn_state = dn_got_read_q_scope;
856 853 else if (token == dn_colon_token) {
857 854 dn_state = dn_got_write_colon;
858 855 next->write.scope = LDAP_SCOPE_ONELEVEL;
859 856 } else
860 857 p_error = parse_object_dn_syntax_error;
861 858 break;
862 859 case dn_got_read_q_scope:
863 860 if (token == dn_ques_token)
864 861 dn_state = dn_got_read_q_filter;
865 862 else if (token == dn_colon_token) {
866 863 dn_state = dn_got_write_colon;
867 864 next->write.scope = LDAP_SCOPE_ONELEVEL;
868 865 } else if (token == dn_base_token) {
869 866 next->read.scope = LDAP_SCOPE_BASE;
870 867 dn_state = dn_got_read_scope;
871 868 } else if (token == dn_one_token) {
872 869 next->read.scope = LDAP_SCOPE_ONELEVEL;
873 870 dn_state = dn_got_read_scope;
874 871 } else if (token == dn_sub_token) {
875 872 next->read.scope = LDAP_SCOPE_SUBTREE;
876 873 dn_state = dn_got_read_scope;
877 874 } else {
878 875 p_error = parse_invalid_scope;
879 876 }
880 877 break;
881 878 case dn_got_read_scope:
882 879 if (token == dn_ques_token)
883 880 dn_state = dn_got_read_q_filter;
884 881 else if (token == dn_colon_token) {
885 882 dn_state = dn_got_write_colon;
886 883 next->write.scope = LDAP_SCOPE_ONELEVEL;
887 884 } else
888 885 p_error = parse_object_dn_syntax_error;
889 886 break;
890 887 case dn_got_read_q_filter:
891 888 if (token == dn_ques_token) {
892 889 p_error = parse_object_dn_syntax_error;
893 890 } else if (token == dn_colon_token) {
894 891 dn_state = dn_got_write_colon;
895 892 next->write.scope = LDAP_SCOPE_ONELEVEL;
896 893 } else {
897 894 if (!validate_ldap_filter(s_begin, s_end))
898 895 break;
899 896 next->read.attrs =
900 897 s_strndup_esc(s_begin, s_end - s_begin);
901 898 dn_state = dn_got_read_filter;
902 899 }
903 900 break;
904 901 case dn_got_read_filter:
905 902 if (token == dn_ques_token) {
906 903 p_error = parse_object_dn_syntax_error;
907 904 } else if (token == dn_colon_token) {
908 905 dn_state = dn_got_write_colon;
909 906 next->write.scope = LDAP_SCOPE_ONELEVEL;
910 907 } else
911 908 p_error = parse_object_dn_syntax_error;
912 909 break;
913 910 case dn_got_write_colon:
914 911 if (token == dn_ques_token)
915 912 dn_state = dn_got_write_q_scope;
916 913 else if (token == dn_colon_token) {
917 914 dn_state = dn_got_delete_colon;
918 915 } else {
919 916 if (!validate_dn(s_begin, s_end - s_begin))
920 917 break;
921 918 next->write.base =
922 919 s_strndup_esc(s_begin, s_end - s_begin);
923 920 dn_state = dn_got_write_dn;
924 921 }
925 922 break;
926 923 case dn_got_write_dn:
927 924 if (token == dn_ques_token)
928 925 dn_state = dn_got_write_q_scope;
929 926 else if (token == dn_colon_token) {
930 927 dn_state = dn_got_delete_colon;
931 928 } else
932 929 p_error = parse_object_dn_syntax_error;
933 930 break;
934 931 case dn_got_write_q_scope:
935 932 if (token == dn_ques_token)
936 933 dn_state = dn_got_write_q_filter;
937 934 else if (token == dn_colon_token) {
938 935 dn_state = dn_got_delete_colon;
939 936 } else if (token == dn_base_token) {
940 937 next->write.scope = LDAP_SCOPE_BASE;
941 938 dn_state = dn_got_write_scope;
942 939 } else if (token == dn_one_token) {
943 940 next->write.scope = LDAP_SCOPE_ONELEVEL;
944 941 dn_state = dn_got_write_scope;
945 942 } else if (token == dn_sub_token) {
946 943 next->write.scope = LDAP_SCOPE_SUBTREE;
947 944 dn_state = dn_got_write_scope;
948 945 } else {
949 946 p_error = parse_invalid_scope;
950 947 }
951 948 break;
952 949 case dn_got_write_scope:
953 950 if (token == dn_ques_token)
954 951 dn_state = dn_got_write_q_filter;
955 952 else if (token == dn_colon_token) {
956 953 dn_state = dn_got_delete_colon;
957 954 } else
958 955 p_error = parse_object_dn_syntax_error;
959 956 break;
960 957 case dn_got_write_q_filter:
961 958 if (token == dn_ques_token) {
962 959 p_error = parse_object_dn_syntax_error;
963 960 } else if (token == dn_colon_token) {
964 961 dn_state = dn_got_delete_colon;
965 962 } else {
966 963 if (!validate_ldap_filter(s_begin, s_end))
967 964 break;
968 965 next->write.attrs =
969 966 s_strndup_esc(s_begin, s_end - s_begin);
970 967 dn_state = dn_got_write_filter;
971 968 }
972 969 break;
973 970 case dn_got_write_filter:
974 971 if (token == dn_ques_token) {
975 972 p_error = parse_object_dn_syntax_error;
976 973 } else if (token == dn_colon_token) {
977 974 dn_state = dn_got_delete_colon;
978 975
979 976 } else
980 977 p_error = parse_semi_expected_error;
981 978 break;
982 979 case dn_got_delete_colon:
983 980 if (token == dn_ques_token) {
984 981 p_error = parse_object_dn_syntax_error;
985 982 } else if (token == dn_colon_token) {
986 983 p_error = parse_object_dn_syntax_error;
987 984 } else {
988 985 if (!get_deleteDisp(s_begin, s_end, next))
989 986 break;
990 987 dn_state = dn_got_delete_dsp;
991 988 }
992 989 break;
993 990 case dn_got_delete_dsp:
994 991 p_error = parse_object_dn_syntax_error;
995 992 break;
996 993 }
997 994
998 995 if (p_error != no_parse_error)
999 996 break;
1000 997 }
1001 998 if (p_error != no_parse_error) {
1002 999 if (obj_dn != NULL)
1003 1000 free_object_dn(obj_dn);
1004 1001 if (next != NULL)
1005 1002 free_object_dn(next);
1006 1003 obj_dn = NULL;
1007 1004 } else if (next != NULL) {
1008 1005 if (obj_dn == NULL)
1009 1006 obj_dn = next;
1010 1007 else
1011 1008 last->next = next;
1012 1009 } else if (obj_dn == NULL)
1013 1010 obj_dn = (__nis_object_dn_t *)
1014 1011 s_calloc(1, sizeof (__nis_object_dn_t));
1015 1012
1016 1013 return (obj_dn);
1017 1014 }
1018 1015
1019 1016 /*
1020 1017 * FUNCTION: get_mapping_rule
1021 1018 *
1022 1019 * Parse mapping rule attributes
1023 1020 *
1024 1021 * RETURN VALUE: None. Errors determined by p_error
1025 1022 *
1026 1023 * INPUT: the attribute value and mapping rule type
1027 1024 */
1028 1025
1029 1026 static void
1030 1027 get_mapping_rule(
1031 1028 const char *s,
1032 1029 int len,
1033 1030 __nis_table_mapping_t *tbl,
1034 1031 bool_t to_ldap)
1035 1032 {
1036 1033 const char *end_s = s + len;
1037 1034 const char *begin_token;
1038 1035 const char *end_token;
1039 1036 __nis_mapping_rule_t **rule = NULL;
1040 1037 __nis_mapping_rule_t *next = NULL;
1041 1038 /* __nis_mapping_rule_t **r; */
1042 1039 token_type t;
1043 1040 int nRules = 0;
1044 1041 const char *s1;
1045 1042 int i;
1046 1043
1047 1044 /*
1048 1045 * The attribute value is of the form
1049 1046 * colattrspec *("," colattrspec)
1050 1047 * colattrspec = lhs "=" rhs
1051 1048 * lhs = lval | namespeclist
1052 1049 * rhs = rval | [namespec]
1053 1050 */
1054 1051
1055 1052 for (;;) {
1056 1053 if ((next = (__nis_mapping_rule_t *)
1057 1054 s_calloc(1, sizeof (__nis_mapping_rule_t))) == NULL)
1058 1055 break;
1059 1056
1060 1057 s = get_lhs(s, end_s, &next->lhs,
1061 1058 to_ldap ? mit_ldap : mit_nisplus);
1062 1059 if (s == NULL)
1063 1060 break;
1064 1061
1065 1062 begin_token = s;
1066 1063 end_token = end_s;
1067 1064 s1 = get_next_token(&begin_token, &end_token, &t);
1068 1065 if (s1 == NULL)
1069 1066 break;
1070 1067 if (!(to_ldap && (t == comma_token || t == no_token))) {
1071 1068 s = get_rhs(s, end_s, &next->rhs,
1072 1069 to_ldap ? mit_nisplus : mit_ldap);
1073 1070 if (s == NULL)
1074 1071 break;
1075 1072 }
1076 1073
1077 1074 if (next->lhs.numElements > 1 &&
1078 1075 (next->rhs.numElements != 1 ||
1079 1076 next->rhs.element[0].type != me_split)) {
1080 1077 p_error = parse_lhs_rhs_type_mismatch;
1081 1078 break;
1082 1079 }
1083 1080 if (rule == NULL) {
1084 1081 rule = (__nis_mapping_rule_t **)
1085 1082 malloc(sizeof (__nis_mapping_rule_t *));
1086 1083 if (rule == NULL)
1087 1084 break;
1088 1085 } else {
1089 1086 rule = (__nis_mapping_rule_t **)s_realloc(rule,
1090 1087 (nRules + 1) *
1091 1088 sizeof (__nis_mapping_rule_t *));
1092 1089 if (rule == NULL)
1093 1090 break;
1094 1091 }
1095 1092
1096 1093 rule[nRules++] = next;
1097 1094 next = NULL;
1098 1095
1099 1096 begin_token = s;
1100 1097 end_token = end_s;
1101 1098 s = get_next_token(&begin_token, &end_token, &t);
1102 1099 if (s == NULL)
1103 1100 break;
1104 1101 if (t == comma_token)
1105 1102 continue;
1106 1103 if (t != no_token) {
1107 1104 p_error = parse_unexpected_data_end_rule;
1108 1105 break;
1109 1106 }
1110 1107 if (to_ldap) {
1111 1108 tbl->numRulesToLDAP = nRules;
1112 1109 tbl->ruleToLDAP = rule;
1113 1110 } else {
1114 1111 tbl->numRulesFromLDAP = nRules;
1115 1112 tbl->ruleFromLDAP = rule;
1116 1113 }
1117 1114 return;
1118 1115 }
1119 1116
1120 1117 if (rule) {
1121 1118 for (i = 0; i < nRules; i++)
1122 1119 free_mapping_rule(rule[i]);
1123 1120 free(rule);
1124 1121 }
1125 1122 if (next)
1126 1123 free_mapping_rule(next);
1127 1124 }
1128 1125
1129 1126 /*
1130 1127 * FUNCTION: get_lhs
1131 1128 *
1132 1129 * Parse left hand side of mapping rule attribute
1133 1130 *
1134 1131 * RETURN VALUE: NULL if error
1135 1132 * position of beginning rhs
1136 1133 *
1137 1134 * INPUT: the attribute value and mapping rule type
1138 1135 */
1139 1136
1140 1137 static const char *
1141 1138 get_lhs(const char *s,
1142 1139 const char *end_s,
1143 1140 __nis_mapping_rlhs_t *lhs,
1144 1141 __nis_mapping_item_type_t item_type)
1145 1142 {
1146 1143 token_type t;
1147 1144 const char *begin_token;
1148 1145 const char *end_token;
1149 1146 const char *sav_s;
1150 1147 __nis_mapping_element_t *e = NULL;
1151 1148
1152 1149 /*
1153 1150 * lhs can be expressed as:
1154 1151 * item
1155 1152 * (item)
1156 1153 * (item list)
1157 1154 * (fmt, item list)
1158 1155 *
1159 1156 * lhs = lval | namespeclist
1160 1157 * lval = "(" formatspec "," namespec *("," namespec) ")"
1161 1158 * namespeclist = namespec | "(" namespec *("," namespec) ")"
1162 1159 */
1163 1160
1164 1161 for (; p_error == no_parse_error; ) {
1165 1162 begin_token = s;
1166 1163 end_token = end_s;
1167 1164 s = get_next_token(&begin_token, &end_token, &t);
1168 1165 if (s == NULL)
1169 1166 break;
1170 1167 if (t == no_token) {
1171 1168 p_error = parse_unexpected_data_end_rule;
1172 1169 break;
1173 1170 }
1174 1171
1175 1172 e = (__nis_mapping_element_t *)
1176 1173 s_calloc(1, sizeof (__nis_mapping_element_t));
1177 1174 if (e == NULL)
1178 1175 break;
1179 1176
1180 1177 if (t == open_paren_token) {
1181 1178 free(e);
1182 1179 e = NULL;
1183 1180
1184 1181 begin_token = s;
1185 1182 end_token = end_s;
1186 1183 sav_s = s;
1187 1184 s = get_next_token(&begin_token, &end_token, &t);
1188 1185 if (s == NULL)
1189 1186 break;
1190 1187
1191 1188 if (t == quoted_string_token) {
1192 1189 s = get_lhs_match(sav_s, end_s, lhs, item_type);
1193 1190 if (s == NULL)
1194 1191 break;
1195 1192 } else if (t == string_token) {
1196 1193 s = get_lhs_paren_item(sav_s, end_s, lhs,
1197 1194 item_type);
1198 1195 if (s == NULL)
1199 1196 break;
1200 1197 } else {
1201 1198 p_error = parse_bad_lhs_format_error;
1202 1199 break;
1203 1200 }
1204 1201 } else if (t == string_token) {
1205 1202 s = get_mapping_item(begin_token, end_s,
1206 1203 &e->element.item, item_type);
1207 1204 if (s == NULL)
1208 1205 break;
1209 1206 e->type = me_item;
1210 1207 if (!add_element(e, lhs))
1211 1208 break;
1212 1209 e = NULL;
1213 1210 } else {
1214 1211 p_error = parse_bad_lhs_format_error;
1215 1212 break;
1216 1213 }
1217 1214
1218 1215 s = skip_token(s, end_s, equal_token);
1219 1216 if (s == NULL)
1220 1217 break;
1221 1218 if (p_error == no_parse_error)
1222 1219 return (s);
1223 1220 }
1224 1221 if (e != NULL)
1225 1222 free_mapping_element(e);
1226 1223
1227 1224 return (NULL);
1228 1225 }
1229 1226
1230 1227 /*
1231 1228 * FUNCTION: get_lhs_match
1232 1229 *
1233 1230 * Parse left hand side of mapping rule attribute in case of
1234 1231 * matching rule
1235 1232 *
1236 1233 * RETURN VALUE: NULL if error
1237 1234 * position of beginning rhs
1238 1235 *
1239 1236 * INPUT: the attribute value and mapping rule type
1240 1237 */
1241 1238
1242 1239 static const char *
1243 1240 get_lhs_match(
1244 1241 const char *s,
1245 1242 const char *end_s,
1246 1243 __nis_mapping_rlhs_t *lhs,
1247 1244 __nis_mapping_item_type_t item_type)
1248 1245 {
1249 1246 token_type t;
1250 1247 const char *begin_token;
1251 1248 const char *end_token;
1252 1249 int n = 0;
1253 1250 int nElements = 0;
1254 1251 char *fmt_string = NULL;
1255 1252 __nis_mapping_format_t *base = NULL;
1256 1253 __nis_mapping_item_t *item = NULL;
1257 1254 __nis_mapping_item_t *itm;
1258 1255 __nis_mapping_element_t *e;
1259 1256
1260 1257 /*
1261 1258 * lval = "(" formatspec "," namespec *("," namespec) ")"
1262 1259 */
1263 1260
1264 1261 for (; p_error == no_parse_error; ) {
1265 1262 begin_token = s;
1266 1263 end_token = end_s;
1267 1264 s = get_next_token(&begin_token, &end_token, &t);
1268 1265 if (s == NULL || t != quoted_string_token) {
1269 1266 p_error = parse_internal_error;
1270 1267 break;
1271 1268 }
1272 1269
1273 1270
1274 1271 fmt_string = s_strndup(begin_token, end_token - begin_token);
1275 1272 if (fmt_string == NULL)
1276 1273 break;
1277 1274
1278 1275 if (!get_mapping_format(fmt_string, &base, &n, NULL, FALSE))
1279 1276 break;
1280 1277
1281 1278 for (n = 0; base[n].type != mmt_end; n++) {
1282 1279 if (base[n].type != mmt_item &&
1283 1280 base[n].type != mmt_berstring) {
1284 1281 if (base[n].type == mmt_berstring_null)
1285 1282 base[n].type = mmt_berstring;
1286 1283 continue;
1287 1284 }
1288 1285 s = skip_token(s, end_s, comma_token);
1289 1286 if (s == NULL) {
1290 1287 p_error = parse_not_enough_extract_items;
1291 1288 break;
1292 1289 }
1293 1290 begin_token = s;
1294 1291 end_token = end_s;
1295 1292 s = get_next_token(&begin_token, &end_token, &t);
1296 1293 if (s == NULL)
1297 1294 break;
1298 1295 if (t != string_token) {
1299 1296 p_error = parse_item_expected_error;
1300 1297 break;
1301 1298 }
1302 1299 itm = (__nis_mapping_item_t *)
1303 1300 s_realloc(item, (nElements + 1) *
1304 1301 sizeof (__nis_mapping_item_t));
1305 1302 if (itm == NULL)
1306 1303 break;
1307 1304 item = itm;
1308 1305
1309 1306 s = get_mapping_item(begin_token, end_s,
1310 1307 &item[nElements], item_type);
1311 1308 if (s == NULL)
1312 1309 break;
1313 1310 nElements++;
1314 1311 }
1315 1312 if (p_error != no_parse_error)
1316 1313 break;
1317 1314
1318 1315 s = skip_token(s, end_s, close_paren_token);
1319 1316 if (s == NULL)
1320 1317 break;
1321 1318 free(fmt_string);
1322 1319 fmt_string = NULL;
1323 1320
1324 1321 if (nElements == 0) {
1325 1322 p_error = parse_no_match_item;
1326 1323 break;
1327 1324 }
1328 1325 e = (__nis_mapping_element_t *)s_calloc(1,
1329 1326 sizeof (__nis_mapping_element_t));
1330 1327 if (e == NULL)
1331 1328 break;
1332 1329 e->type = me_match;
1333 1330 e->element.match.numItems = nElements;
1334 1331 e->element.match.item = item;
1335 1332 e->element.match.fmt = base;
1336 1333 lhs->numElements = 1;
1337 1334 lhs->element = e;
1338 1335
1339 1336 if (p_error == no_parse_error)
1340 1337 return (s);
1341 1338 }
1342 1339 if (item == NULL) {
1343 1340 for (n = 0; n < nElements; n++)
1344 1341 free_mapping_item(&item[n]);
1345 1342 free(item);
1346 1343 }
1347 1344 if (fmt_string != NULL)
1348 1345 free(fmt_string);
1349 1346 if (base != NULL)
1350 1347 free_mapping_format(base);
1351 1348
1352 1349 return (NULL);
1353 1350 }
1354 1351
1355 1352 /*
1356 1353 * FUNCTION: get_lhs_paren_item
1357 1354 *
1358 1355 * Parse left hand side of mapping rule attribute in case of
1359 1356 * (item1, ..., item-n)
1360 1357 *
1361 1358 * RETURN VALUE: NULL if error
1362 1359 * position of beginning rhs
1363 1360 *
1364 1361 * INPUT: the attribute value and mapping rule type
1365 1362 */
1366 1363
1367 1364 static const char *
1368 1365 get_lhs_paren_item(
1369 1366 const char *s,
1370 1367 const char *end_s,
1371 1368 __nis_mapping_rlhs_t *lhs,
1372 1369 __nis_mapping_item_type_t item_type)
1373 1370 {
1374 1371 token_type t;
1375 1372 const char *begin_token;
1376 1373 const char *end_token;
1377 1374 __nis_mapping_element_t *e = NULL;
1378 1375 int n = 0;
1379 1376 int i;
1380 1377
1381 1378 /*
1382 1379 * "(" namespec *("," namespec) ")"
1383 1380 */
1384 1381
1385 1382 for (;;) {
1386 1383 e = (__nis_mapping_element_t *)s_realloc(e, (n + 1) *
1387 1384 sizeof (__nis_mapping_element_t));
1388 1385 if (e == NULL)
1389 1386 break;
1390 1387
1391 1388 s = get_mapping_item(s, end_s, &e[n].element.item,
1392 1389 item_type);
1393 1390 if (s == NULL)
1394 1391 break;
1395 1392 e[n].type = me_item;
1396 1393 n++;
1397 1394
1398 1395 begin_token = s;
1399 1396 end_token = end_s;
1400 1397 s = get_next_token(&begin_token, &end_token, &t);
1401 1398 if (s != NULL && t == close_paren_token) {
1402 1399 lhs->numElements = n;
1403 1400 if (n == 1)
1404 1401 e[0].element.item.repeat = TRUE;
1405 1402 lhs->element = e;
1406 1403 return (s);
1407 1404 }
1408 1405 if (s == NULL || t != comma_token) {
1409 1406 p_error = parse_comma_expected_error;
1410 1407 break;
1411 1408 }
1412 1409 }
1413 1410 for (i = 0; i < n; i++)
1414 1411 free_mapping_element(&e[i]);
1415 1412 if (e != NULL)
1416 1413 free(e);
1417 1414 return (NULL);
1418 1415 }
1419 1416
1420 1417 /*
1421 1418 * FUNCTION: get_rhs
1422 1419 *
1423 1420 * Parse right hand side of mapping rule attribute
1424 1421 *
1425 1422 * RETURN VALUE: NULL if error
1426 1423 * position of beginning next mapping rule
1427 1424 *
1428 1425 * INPUT: the attribute value and mapping rule type
1429 1426 */
1430 1427
1431 1428 static const char *
1432 1429 get_rhs(
1433 1430 const char *s,
1434 1431 const char *end_s,
1435 1432 __nis_mapping_rlhs_t *rhs,
1436 1433 __nis_mapping_item_type_t item_type)
1437 1434 {
1438 1435 /*
1439 1436 * This handles the following cases:
1440 1437 * name me_item
1441 1438 * (name) me_item
1442 1439 * (fmt, name-list) me_print
1443 1440 * (item, fmt) me_extract
1444 1441 */
1445 1442
1446 1443 token_type t;
1447 1444 const char *begin_token;
1448 1445 const char *end_token;
1449 1446 char *str = NULL;
1450 1447 __nis_mapping_format_t *fmt = NULL;
1451 1448 __nis_mapping_element_t *e = NULL;
1452 1449 __nis_mapping_item_t item;
1453 1450 int n;
1454 1451
1455 1452 (void) memset(&item, 0, sizeof (item));
1456 1453
1457 1454 for (; p_error == no_parse_error; ) {
1458 1455 begin_token = s;
1459 1456 end_token = end_s;
1460 1457 s = get_next_token(&begin_token, &end_token, &t);
1461 1458 if (s == NULL)
1462 1459 break;
1463 1460
1464 1461 e = (__nis_mapping_element_t *)
1465 1462 s_calloc(1, sizeof (__nis_mapping_element_t));
1466 1463 if (e == NULL)
1467 1464 break;
1468 1465
1469 1466 if (t == string_token) {
1470 1467 s = get_mapping_item(begin_token, end_s,
1471 1468 &e->element.item, item_type);
1472 1469 } else if (t == open_paren_token) {
1473 1470 begin_token = s;
1474 1471 end_token = end_s;
1475 1472 s = get_next_token(&begin_token, &end_token, &t);
1476 1473 if (s == NULL)
1477 1474 break;
1478 1475 if (t == string_token) {
1479 1476 /* (item, fmt) - me_extract */
1480 1477 /* (item, "c") - me_split */
1481 1478 s = get_mapping_item(begin_token, end_s,
1482 1479 &item, item_type);
1483 1480 if (s == NULL)
1484 1481 break;
1485 1482 begin_token = s;
1486 1483 end_token = end_s;
1487 1484 s = get_next_token(&begin_token, &end_token,
1488 1485 &t);
1489 1486 if (s == NULL)
1490 1487 break;
1491 1488 else if (t == close_paren_token) {
1492 1489 item.repeat = TRUE;
1493 1490 e->element.item = item;
1494 1491 e->type = me_item;
1495 1492 rhs->numElements = 1;
1496 1493 rhs->element = e;
1497 1494 return (s);
1498 1495 } else if (t != comma_token) {
1499 1496 p_error = parse_comma_expected_error;
1500 1497 break;
1501 1498 }
1502 1499
1503 1500 begin_token = s;
↓ open down ↓ |
1110 lines elided |
↑ open up ↑ |
1504 1501 end_token = end_s;
1505 1502 s = get_next_token(&begin_token, &end_token,
1506 1503 &t);
1507 1504 if (s == NULL || t != quoted_string_token) {
1508 1505 p_error =
1509 1506 parse_format_string_expected_error;
1510 1507 break;
1511 1508 }
1512 1509
1513 1510 if (end_token == begin_token + 1 ||
1514 - *begin_token == ESCAPE_CHAR &&
1515 - end_token == begin_token + 2) {
1511 + (*begin_token == ESCAPE_CHAR &&
1512 + end_token == begin_token + 2)) {
1516 1513 e->type = me_split;
1517 1514 e->element.split.item = item;
1518 1515 e->element.split.delim = *begin_token;
1519 1516 } else {
1520 1517 str = s_strndup(begin_token,
1521 1518 end_token - begin_token);
1522 1519 if (str == NULL)
1523 1520 break;
1524 1521 if (!get_mapping_format(str, &fmt,
1525 1522 NULL, &n, FALSE))
1526 1523 break;
1527 1524 free(str);
1528 1525 str = NULL;
1529 1526 if (n != 1) {
1530 1527 p_error =
1531 1528 parse_bad_extract_format_spec;
1532 1529 break;
1533 1530 }
1534 1531 e->type = me_extract;
1535 1532 e->element.extract.item = item;
1536 1533 e->element.extract.fmt = fmt;
1537 1534 }
1538 1535 s = skip_token(s, end_s, close_paren_token);
1539 1536 } else if (t == quoted_string_token) {
1540 1537 /* (fmt, name-list) - me_print */
1541 1538 str = s_strndup(begin_token,
1542 1539 end_token - begin_token);
1543 1540 if (str == NULL)
1544 1541 break;
1545 1542
1546 1543 s = get_print_mapping_element(s, end_s,
1547 1544 str, e, item_type);
1548 1545 free(str);
1549 1546 str = NULL;
1550 1547 } else {
1551 1548 p_error = parse_start_rhs_unrecognized;
1552 1549 break;
1553 1550 }
1554 1551 } else {
1555 1552 p_error = parse_start_rhs_unrecognized;
1556 1553 break;
1557 1554 }
1558 1555 if (s == NULL)
1559 1556 break;
1560 1557 rhs->numElements = 1;
1561 1558 rhs->element = e;
1562 1559 if (p_error == no_parse_error)
1563 1560 return (s);
1564 1561 }
1565 1562 if (str)
1566 1563 free(str);
1567 1564 if (fmt != NULL)
1568 1565 free_mapping_format(fmt);
1569 1566 if (e != NULL)
1570 1567 free_mapping_element(e);
1571 1568 free_mapping_item(&item);
1572 1569
1573 1570 return (NULL);
1574 1571 }
1575 1572
1576 1573 /*
1577 1574 * FUNCTION: get_print_mapping_element
1578 1575 *
1579 1576 * Parse a print mapping rule attribute in case of the form
1580 1577 * (fmt, name-list)
1581 1578 *
1582 1579 * RETURN VALUE: NULL if error
1583 1580 * position of beginning next mapping rule
1584 1581 *
1585 1582 * INPUT: the attribute value and mapping rule type
1586 1583 */
1587 1584
1588 1585 static const char *
1589 1586 get_print_mapping_element(
1590 1587 const char *s,
1591 1588 const char *end_s,
1592 1589 char *fmt_string,
1593 1590 __nis_mapping_element_t *e,
1594 1591 __nis_mapping_item_type_t item_type)
1595 1592 {
1596 1593 token_type t;
1597 1594 const char *begin_token;
1598 1595 const char *end_token;
1599 1596 char elide;
1600 1597 bool_t doElide;
1601 1598 __nis_mapping_format_t *base = NULL;
1602 1599 __nis_mapping_sub_element_t *subElement = NULL;
1603 1600 int n = 0;
1604 1601 int nSub = 0;
1605 1602 int numSubElements;
1606 1603
1607 1604 for (; p_error == no_parse_error; ) {
1608 1605 if (!get_mapping_format(fmt_string, &base, &n,
1609 1606 &numSubElements, TRUE))
1610 1607 break;
1611 1608 subElement = (__nis_mapping_sub_element_t *)
1612 1609 s_calloc(numSubElements,
1613 1610 sizeof (__nis_mapping_sub_element_t));
1614 1611 if (subElement == NULL)
1615 1612 break;
1616 1613 for (n = 0; base[n].type != mmt_end; n++) {
1617 1614 if (base[n].type != mmt_item &&
1618 1615 base[n].type != mmt_berstring) {
1619 1616 if (base[n].type == mmt_berstring_null)
1620 1617 base[n].type = mmt_berstring;
1621 1618 continue;
1622 1619 }
1623 1620 if (nSub < numSubElements) {
1624 1621 s = skip_token(s, end_s, comma_token);
1625 1622 if (s == NULL) {
1626 1623 p_error = parse_bad_print_format;
1627 1624 break;
1628 1625 }
1629 1626 }
1630 1627
1631 1628 /* namelist may have parens around it */
1632 1629 s = get_subElement(s, end_s, &subElement[nSub],
1633 1630 item_type);
1634 1631 if (s == NULL)
1635 1632 break;
1636 1633 nSub++;
1637 1634 }
1638 1635 if (p_error != no_parse_error)
1639 1636 break;
1640 1637
1641 1638 begin_token = s;
1642 1639 end_token = end_s;
1643 1640 s = get_next_token(&begin_token, &end_token, &t);
1644 1641 if (s == NULL || t == no_token) {
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
1645 1642 p_error = parse_unexpected_data_end_rule;
1646 1643 break;
1647 1644 } else if (t == close_paren_token) {
1648 1645 doElide = FALSE;
1649 1646 elide = '\0';
1650 1647 } else if (t == comma_token) {
1651 1648 begin_token = s;
1652 1649 end_token = end_s;
1653 1650 s = get_next_token(&begin_token, &end_token, &t);
1654 1651 if (s != NULL && t == quoted_string_token &&
1655 - (end_token == begin_token + 1 ||
1656 - *begin_token == ESCAPE_CHAR &&
1657 - end_token == begin_token + 2)) {
1652 + (end_token == begin_token + 1 ||
1653 + (*begin_token == ESCAPE_CHAR &&
1654 + end_token == begin_token + 2))) {
1658 1655 if (numSubElements != 1 ||
1659 1656 subElement->type == me_extract ||
1660 1657 subElement->type == me_split) {
1661 1658 p_error = parse_cannot_elide;
1662 1659 break;
1663 1660 }
1664 1661 if (subElement->type == me_item &&
1665 1662 !subElement->element.item.repeat) {
1666 1663 p_error = parse_cannot_elide;
1667 1664 break;
1668 1665 }
1669 1666 elide = *begin_token;
1670 1667 doElide = TRUE;
1671 1668
1672 1669 } else {
1673 1670 p_error = parse_bad_elide_char;
1674 1671 break;
1675 1672 }
1676 1673 s = skip_token(s, end_s, close_paren_token);
1677 1674 if (s == NULL)
1678 1675 break;
1679 1676 }
1680 1677
1681 1678 e->type = me_print;
1682 1679 e->element.print.fmt = base;
1683 1680 e->element.print.numSubElements = numSubElements;
1684 1681 e->element.print.subElement = subElement;
1685 1682 e->element.print.elide = elide;
1686 1683 e->element.print.doElide = doElide;
1687 1684
1688 1685 if (p_error == no_parse_error)
1689 1686 return (s);
1690 1687 }
1691 1688 if (base)
1692 1689 free_mapping_format(base);
1693 1690 if (subElement != NULL) {
1694 1691 for (n = 0; n < numSubElements; n++)
1695 1692 free_mapping_sub_element(&subElement[n]);
1696 1693 free(subElement);
1697 1694 }
1698 1695
1699 1696 return (NULL);
1700 1697 }
1701 1698
1702 1699 /*
1703 1700 * FUNCTION: get_mapping_item
1704 1701 *
1705 1702 * Parse attribute string to get mapping item
1706 1703 *
1707 1704 * RETURN VALUE: NULL if error
1708 1705 * position of beginning next token after item
1709 1706 *
1710 1707 * INPUT: the attribute value and mapping rule type
1711 1708 */
1712 1709
1713 1710 static const char *
1714 1711 get_mapping_item(
1715 1712 const char *s,
1716 1713 const char *end_s,
1717 1714 __nis_mapping_item_t *item,
1718 1715 __nis_mapping_item_type_t type)
1719 1716 {
1720 1717 token_type t;
1721 1718 const char *begin_token;
1722 1719 const char *end_token;
1723 1720 char *name = NULL;
1724 1721 char *index_string;
1725 1722 const char *s_sav;
1726 1723 int len;
1727 1724
1728 1725 (void) memset(item, 0, sizeof (*item));
1729 1726
1730 1727 /*
1731 1728 * A namepec is defined as follows:
1732 1729 * namespec = ["ldap:"] attrspec [searchTriple] |
1733 1730 * ["nis+:"] colspec [objectspec]
1734 1731 *
1735 1732 * The form of the item is assumed to be as follows:
1736 1733 * ["ldap:"] attrspec [searchTriple]
1737 1734 * attrspec = attribute | "(" attribute ")"
1738 1735 * searchTriple = ":" [baseDN] ["?" [scope] ["?" [filter]]]
1739 1736 * baseDN = Base DN for search
1740 1737 * scope = "base" | "one" | "sub"
1741 1738 * filter = LDAP search filter
1742 1739 *
1743 1740 * The form of the objectspec is as follows:
1744 1741 * ["nis+:"] colspec [objectspec]
1745 1742 * objectspec = objectname | "[" indexlist "]" tablename
1746 1743 * objectname = The name of a NIS+ object
1747 1744 * tablename = The name of a NIS+ table
1748 1745 * indexlist = colspec ["," colspec]
1749 1746 * colspec = colname "=" colvalue
1750 1747 * colname = The name of a column in the table
1751 1748 * colvalue = colvaluestring | \" colvaluestring \"
1752 1749 */
1753 1750
1754 1751 for (; p_error == no_parse_error; ) {
1755 1752 while (s < end_s && is_whitespace(*s))
1756 1753 s++;
1757 1754 len = end_s - s;
1758 1755 if (yp2ldap) {
1759 1756 if ((begin_token = skip_string("ldap:", s,
1760 1757 len)) != NULL) {
1761 1758 item->type = mit_ldap;
1762 1759 } else if ((begin_token = skip_string("yp:", s,
1763 1760 len)) != NULL) {
1764 1761 item->type = mit_nisplus;
1765 1762 } else {
1766 1763 item->type = type;
1767 1764 begin_token = s;
1768 1765 }
1769 1766 } else {
1770 1767 if ((begin_token = skip_string("ldap:", s,
1771 1768 len)) != NULL) {
1772 1769 item->type = mit_ldap;
1773 1770 } else if ((begin_token = skip_string("nis+:", s,
1774 1771 len)) != NULL) {
1775 1772 item->type = mit_nisplus;
1776 1773 } else if ((begin_token = skip_string("nisplus:", s,
1777 1774 len)) != NULL) {
1778 1775 item->type = mit_nisplus;
1779 1776 } else {
1780 1777 item->type = type;
1781 1778 begin_token = s;
1782 1779 }
1783 1780 }
1784 1781
1785 1782 end_token = end_s;
1786 1783 s = get_next_token(&begin_token, &end_token, &t);
1787 1784 if (s == NULL || t != string_token) {
1788 1785 p_error = parse_bad_item_format;
1789 1786 break;
1790 1787 }
1791 1788
1792 1789 item->name = s_strndup_esc(begin_token,
1793 1790 end_token - begin_token);
1794 1791 if (item->name == NULL)
1795 1792 break;
1796 1793 if (item->type == mit_ldap) {
1797 1794 item->searchSpec.triple.scope = LDAP_SCOPE_UNKNOWN;
1798 1795 begin_token = s;
1799 1796 end_token = end_s;
1800 1797 s_sav = s;
1801 1798 s = get_next_token(&begin_token, &end_token, &t);
1802 1799 if (s != NULL && t == colon_token) {
1803 1800 s = get_search_triple(s, end_s,
1804 1801 &item->searchSpec.triple);
1805 1802 if (s == NULL)
1806 1803 break;
1807 1804 } else
1808 1805 s = s_sav;
1809 1806 } else if (item->type == mit_nisplus) {
1810 1807 while (s < end_s && is_whitespace(*s))
1811 1808 s++;
1812 1809
1813 1810 if (s < end_s && *s == OPEN_BRACKET) {
1814 1811 index_string = getIndex(&s, end_s);
1815 1812 if (index_string == NULL)
1816 1813 break;
1817 1814 (void) parse_index(index_string,
1818 1815 index_string + strlen(index_string),
1819 1816 &item->searchSpec.obj.index);
1820 1817 free(index_string);
1821 1818 if (p_error != no_parse_error)
1822 1819 break;
1823 1820 }
1824 1821 s_sav = s;
1825 1822 begin_token = s;
1826 1823 end_token = end_s;
1827 1824 s = get_next_token(&begin_token, &end_token, &t);
1828 1825 if (s != NULL && t == string_token) {
1829 1826 name = s_strndup_esc(begin_token,
1830 1827 end_token - begin_token);
1831 1828 if (name == NULL)
1832 1829 break;
1833 1830 item->searchSpec.obj.name = name;
1834 1831 } else
1835 1832 s = s_sav;
1836 1833 }
1837 1834 if (p_error == no_parse_error)
1838 1835 return (s);
1839 1836 }
1840 1837 free_mapping_item(item);
1841 1838 (void) memset(item, 0, sizeof (*item));
1842 1839 if (name == NULL)
1843 1840 free(name);
1844 1841 return (NULL);
1845 1842 }
1846 1843
1847 1844 static const char *
1848 1845 get_print_sub_element(const char *s,
1849 1846 const char *end_s,
1850 1847 __nis_mapping_item_type_t type,
1851 1848 __nis_mapping_sub_element_t *sub)
1852 1849 {
1853 1850
1854 1851 int k;
1855 1852 int n;
1856 1853 const char *begin_token;
1857 1854 const char *end_token;
1858 1855 token_type t;
1859 1856 __nis_mapping_format_t *base;
1860 1857 __nis_mapping_item_t *print_item;
1861 1858
1862 1859 k = 0;
1863 1860 base = sub->element.print.fmt;
1864 1861 print_item = sub->element.print.item;
1865 1862 sub->element.print.doElide = FALSE;
1866 1863 sub->element.print.elide = '\0';
1867 1864
1868 1865 for (n = 0; base[n].type != mmt_end; n++) {
1869 1866 if (base[n].type != mmt_item && base[n].type != mmt_berstring) {
1870 1867 if (base[n].type == mmt_berstring_null)
1871 1868 base[n].type = mmt_berstring;
1872 1869 continue;
1873 1870 }
1874 1871 s = skip_token(s, end_s, comma_token);
1875 1872 if (s == NULL) {
1876 1873 p_error = parse_bad_print_format;
1877 1874 break;
1878 1875 }
1879 1876
1880 1877 begin_token = s;
1881 1878 end_token = end_s;
1882 1879 s = get_next_token(&begin_token, &end_token, &t);
1883 1880 if (s == NULL)
1884 1881 break;
1885 1882 /*
1886 1883 * Determine if of the form
1887 1884 * ("fmt", (item), "delim") or
1888 1885 * ("fmt", item1, item2, ..., item n)
1889 1886 */
1890 1887 if (t == open_paren_token) {
1891 1888 if (sub->element.print.numItems != 1) {
1892 1889 p_error = parse_invalid_print_arg;
1893 1890 break;
1894 1891 }
1895 1892 s = get_mapping_item(s, end_s, &print_item[k++], type);
1896 1893 s = skip_token(s, end_s, close_paren_token);
1897 1894 s = skip_token(s, end_s, comma_token);
1898 1895 if (s == NULL) {
1899 1896 p_error = parse_bad_print_format;
1900 1897 break;
1901 1898 }
1902 1899 begin_token = s;
1903 1900 end_token = end_s;
1904 1901 s = get_next_token(&begin_token, &end_token, &t);
1905 1902 if (s == NULL)
1906 1903 break;
1907 1904 if (t != quoted_string_token ||
1908 1905 begin_token + 1 != end_token) {
1909 1906 p_error = parse_bad_elide_char;
1910 1907 break;
1911 1908 }
1912 1909 sub->element.print.elide = *begin_token;
1913 1910 sub->element.print.doElide = TRUE;
1914 1911 print_item[0].repeat = TRUE;
1915 1912 break;
1916 1913 }
1917 1914 s = get_mapping_item(begin_token, end_s,
1918 1915 &print_item[k++], type);
1919 1916 if (s == NULL)
1920 1917 break;
1921 1918
1922 1919 if (p_error != no_parse_error)
1923 1920 break;
1924 1921 }
1925 1922
1926 1923 return (p_error == no_parse_error ? s : NULL);
1927 1924 }
1928 1925
1929 1926 /*
1930 1927 * FUNCTION: get_subElement
1931 1928 *
1932 1929 * Parse attribute string to get sub element item
1933 1930 *
1934 1931 * RETURN VALUE: NULL if error
1935 1932 * position of beginning next token after item
1936 1933 *
1937 1934 * INPUT: the attribute value and mapping rule type
1938 1935 */
1939 1936
1940 1937 static const char *
1941 1938 get_subElement(
1942 1939 const char *s,
1943 1940 const char *end_s,
1944 1941 __nis_mapping_sub_element_t *subelement,
1945 1942 __nis_mapping_item_type_t type)
1946 1943 {
1947 1944 token_type t;
1948 1945 const char *begin_token;
1949 1946 const char *end_token;
1950 1947 char *fmt_string;
1951 1948 __nis_mapping_item_t item;
1952 1949 __nis_mapping_element_type_t e_type;
1953 1950 __nis_mapping_item_t *print_item = NULL;
1954 1951 __nis_mapping_format_t *base = NULL;
1955 1952 int n = 0;
1956 1953 int numItems = 0;
1957 1954 unsigned char delim;
1958 1955 __nis_mapping_sub_element_t sub;
1959 1956
1960 1957 /*
1961 1958 * What is the form of we are expecting here
1962 1959 * item me_item
1963 1960 * (item) me_item
1964 1961 * ("fmt", item1, item2, ..., item n) me_print
1965 1962 * ("fmt", (item), "elide") me_print
1966 1963 * (name, "delim") me_split
1967 1964 * (item, "fmt") me_extract
1968 1965 */
1969 1966 (void) memset(&item, 0, sizeof (item));
1970 1967
1971 1968 for (; p_error == no_parse_error; ) {
1972 1969 begin_token = s;
1973 1970 end_token = end_s;
1974 1971 s = get_next_token(&begin_token, &end_token, &t);
1975 1972 if (s == NULL)
1976 1973 break;
1977 1974 if (t == string_token) { /* me_item */
1978 1975 s = get_mapping_item(begin_token, end_s,
1979 1976 &subelement->element.item, type);
1980 1977 if (s == NULL)
1981 1978 break;
1982 1979 subelement->type = me_item;
1983 1980 return (s);
1984 1981 } else if (t != open_paren_token) {
1985 1982 p_error = parse_item_expected_error;
1986 1983 break;
1987 1984 }
1988 1985
1989 1986 begin_token = s;
1990 1987 end_token = end_s;
1991 1988 s = get_next_token(&begin_token, &end_token, &t);
1992 1989 if (s == NULL)
1993 1990 break;
1994 1991
1995 1992 if (t != string_token && t != quoted_string_token) {
1996 1993 p_error = parse_item_expected_error;
1997 1994 break;
1998 1995 }
1999 1996 e_type = me_print;
2000 1997 if (t == string_token) {
2001 1998 /* me_item, me_extract or me_split */
2002 1999 s = get_mapping_item(begin_token, end_s, &item, type);
2003 2000 if (s == NULL)
2004 2001 break;
2005 2002
2006 2003 begin_token = s;
2007 2004 end_token = end_s;
2008 2005 s = get_next_token(&begin_token, &end_token, &t);
2009 2006 if (s == NULL) {
2010 2007 p_error = parse_unexpected_data_end_rule;
2011 2008 break;
2012 2009 } else if (t == close_paren_token) {
2013 2010 subelement->type = me_item;
2014 2011 item.repeat = TRUE;
2015 2012 subelement->element.item = item;
2016 2013 if (yp2ldap) {
2017 2014 while (s < end_s && is_whitespace(*s))
2018 2015 s++;
2019 2016 if (s == end_s) {
2020 2017 p_error =
2021 2018 parse_unexpected_data_end_rule;
2022 2019 break;
2023 2020 }
2024 2021 if (*s == DASH_CHAR && s < end_s) {
2025 2022 s++;
2026 2023 while (s < end_s &&
2027 2024 is_whitespace(*s))
2028 2025 s++;
2029 2026 begin_token = s;
2030 2027 end_token = end_s;
2031 2028
2032 2029 subelement->element.item.exItem
2033 2030 =
2034 2031 (__nis_mapping_item_t *)
2035 2032 s_malloc(sizeof (__nis_mapping_item_t));
2036 2033 if (!subelement->
2037 2034 element.item.exItem)
2038 2035 break;
2039 2036 s = get_mapping_item(s, end_s,
2040 2037 subelement->
2041 2038 element.item.exItem,
2042 2039 type);
2043 2040 if (s == NULL) {
2044 2041 p_error =
2045 2042 parse_internal_error;
2046 2043 free_mapping_item(
2047 2044 subelement->
2048 2045 element.item.exItem);
2049 2046 subelement->
2050 2047 element.item.exItem =
2051 2048 NULL;
2052 2049 break;
2053 2050 }
2054 2051 }
2055 2052 }
2056 2053 return (s);
2057 2054 } else if (t != comma_token) {
2058 2055 p_error = parse_comma_expected_error;
2059 2056 break;
↓ open down ↓ |
392 lines elided |
↑ open up ↑ |
2060 2057 }
2061 2058
2062 2059 begin_token = s;
2063 2060 end_token = end_s;
2064 2061 s = get_next_token(&begin_token, &end_token, &t);
2065 2062 if (s == NULL || t != quoted_string_token) {
2066 2063 p_error = parse_format_string_expected_error;
2067 2064 break;
2068 2065 }
2069 2066 if (end_token == begin_token + 1 ||
2070 - *begin_token == ESCAPE_CHAR &&
2071 - end_token == begin_token + 2) {
2067 + (*begin_token == ESCAPE_CHAR &&
2068 + end_token == begin_token + 2)) {
2072 2069 /* me_split */
2073 2070 delim = (unsigned char)end_token[-1];
2074 2071 s = skip_token(s, end_s, close_paren_token);
2075 2072 if (s == NULL)
2076 2073 break;
2077 2074 subelement->element.split.item = item;
2078 2075 subelement->element.split.delim = delim;
2079 2076 subelement->type = me_split;
2080 2077 return (s);
2081 2078 }
2082 2079 e_type = me_extract;
2083 2080 }
2084 2081 fmt_string = s_strndup(begin_token, end_token - begin_token);
2085 2082 if (fmt_string == NULL)
2086 2083 break;
2087 2084 if (!get_mapping_format(fmt_string, &base, &n, &numItems,
2088 2085 e_type == me_print)) {
2089 2086 free(fmt_string);
2090 2087 break;
2091 2088 }
2092 2089 free(fmt_string);
2093 2090
2094 2091 if (numItems != 1 && e_type == me_extract) {
2095 2092 p_error = numItems == 0 ?
2096 2093 parse_not_enough_extract_items :
2097 2094 parse_too_many_extract_items;
2098 2095 break;
2099 2096 } else if (numItems > 0 && e_type == me_print) {
2100 2097 print_item = (__nis_mapping_item_t *)s_calloc(numItems,
2101 2098 sizeof (__nis_mapping_item_t));
2102 2099 if (print_item == NULL)
2103 2100 break;
2104 2101 }
2105 2102
2106 2103 if (e_type == me_print) {
2107 2104 sub.element.print.numItems = numItems;
2108 2105 sub.element.print.fmt = base;
2109 2106 sub.element.print.item = print_item;
2110 2107 s = get_print_sub_element(s, end_s, type, &sub);
2111 2108 if (s == NULL)
2112 2109 break;
2113 2110 }
2114 2111 s = skip_token(s, end_s, close_paren_token);
2115 2112 if (s == NULL)
2116 2113 break;
2117 2114
2118 2115 subelement->type = e_type;
2119 2116 if (e_type == me_extract) {
2120 2117 subelement->element.extract.fmt = base;
2121 2118 subelement->element.extract.item = item;
2122 2119 } else {
2123 2120 subelement->type = me_print;
2124 2121 subelement->element.print.fmt = base;
2125 2122 subelement->element.print.numItems = numItems;
2126 2123 subelement->element.print.item = print_item;
2127 2124 subelement->element.print.doElide =
2128 2125 sub.element.print.doElide;
2129 2126 subelement->element.print.elide =
2130 2127 sub.element.print.elide;
2131 2128 }
2132 2129 if (p_error == no_parse_error)
2133 2130 return (s);
2134 2131 }
2135 2132 free_mapping_item(&item);
2136 2133 if (base != NULL)
2137 2134 free_mapping_format(base);
2138 2135 if (print_item) {
2139 2136 for (n = 0; n < numItems; n++)
2140 2137 free_mapping_item(&print_item[n]);
2141 2138 free(print_item);
2142 2139 }
2143 2140
2144 2141 return (NULL);
2145 2142 }
2146 2143
2147 2144 /*
2148 2145 * FUNCTION: skip_get_dn
2149 2146 *
2150 2147 * Get first token after dn
2151 2148 *
2152 2149 * RETURN VALUE: NULL if error (not valid dn)
2153 2150 * position of beginning next token after dn
2154 2151 *
2155 2152 * INPUT: the attribute value
2156 2153 */
2157 2154
2158 2155 const char *
2159 2156 skip_get_dn(const char *dn, const char *end)
2160 2157 {
2161 2158 size_t len = 0;
2162 2159 bool_t in_quote = FALSE;
2163 2160 bool_t goteq = FALSE;
2164 2161 bool_t gotch = FALSE;
2165 2162 bool_t done = FALSE;
2166 2163 bool_t last_comma = FALSE;
2167 2164 const char *last_dn = dn;
2168 2165
2169 2166 while (!done) {
2170 2167 dn += len;
2171 2168 if (last_comma) {
2172 2169 last_dn = dn;
2173 2170 last_comma = FALSE;
2174 2171 }
2175 2172 if (dn >= end)
2176 2173 break;
2177 2174 len = 1;
2178 2175 switch (*dn) {
2179 2176 case ESCAPE_CHAR:
2180 2177 len = 2;
2181 2178 gotch = TRUE;
2182 2179 break;
2183 2180 case DOUBLE_QUOTE_CHAR:
2184 2181 in_quote = !in_quote;
2185 2182 break;
2186 2183 case QUESTION_MARK:
2187 2184 case CLOSE_PAREN_CHAR:
2188 2185 case COLON_CHAR:
2189 2186 done = !in_quote;
2190 2187 /* FALLTHRU */
2191 2188 case SEMI_COLON_CHAR:
2192 2189 case PLUS_SIGN:
2193 2190 case COMMA_CHAR:
2194 2191 if (!in_quote) {
2195 2192 if (!goteq || !gotch)
2196 2193 return (last_dn);
2197 2194 goteq = FALSE;
2198 2195 gotch = FALSE;
2199 2196 if (*dn != PLUS_SIGN)
2200 2197 last_dn = dn;
2201 2198 last_comma = *dn == COMMA_CHAR;
2202 2199 } else {
2203 2200 gotch = TRUE;
2204 2201 }
2205 2202 break;
2206 2203 case EQUAL_CHAR:
2207 2204 if (!in_quote) {
2208 2205 if (!gotch || goteq)
2209 2206 return (NULL);
2210 2207 goteq = TRUE;
2211 2208 gotch = FALSE;
2212 2209 } else {
2213 2210 gotch = TRUE;
2214 2211 }
2215 2212 break;
2216 2213 default:
2217 2214 if (!is_whitespace(*dn))
2218 2215 gotch = TRUE;
2219 2216 break;
2220 2217 }
2221 2218 }
2222 2219
2223 2220 if (dn == end) {
2224 2221 if (!in_quote && goteq && gotch)
2225 2222 last_dn = dn;
2226 2223 }
2227 2224
2228 2225 return (last_dn);
2229 2226 }
2230 2227
2231 2228 /*
2232 2229 * FUNCTION: get_ldap_filter_element
2233 2230 *
2234 2231 * Get an ldap filter element for a given string
2235 2232 *
2236 2233 * RETURN VALUE: NULL if error
2237 2234 * __nis_mapping_element_t if success
2238 2235 *
2239 2236 * INPUT: the string to parse
2240 2237 */
2241 2238
2242 2239 static __nis_mapping_element_t *
2243 2240 get_ldap_filter_element(
2244 2241 const char *s,
2245 2242 const char *end_s
2246 2243 )
2247 2244 {
2248 2245 token_type t;
2249 2246 const char *begin_token;
2250 2247 const char *end_token;
2251 2248 char *format_str;
2252 2249 __nis_mapping_element_t *e = NULL;
2253 2250
2254 2251 begin_token = s;
2255 2252 end_token = end_s;
2256 2253 s = get_next_token(&begin_token, &end_token, &t);
2257 2254 if (s == NULL || t != open_paren_token)
2258 2255 return (NULL);
2259 2256
2260 2257 begin_token = s;
2261 2258 end_token = end_s;
2262 2259 s = get_next_token(&begin_token, &end_token, &t);
2263 2260 if (s == NULL || t != quoted_string_token)
2264 2261 return (NULL);
2265 2262
2266 2263 format_str = s_strndup(begin_token, end_token - begin_token);
2267 2264 if (format_str == NULL)
2268 2265 return (NULL);
2269 2266 e = (__nis_mapping_element_t *)
2270 2267 s_calloc(1, sizeof (__nis_mapping_element_t));
2271 2268 if (e != NULL) {
2272 2269 (void) get_print_mapping_element(s, end_s,
2273 2270 format_str, e, mit_nisplus);
2274 2271 if (p_error != no_parse_error) {
2275 2272 free_mapping_element(e);
2276 2273 e = NULL;
2277 2274 }
2278 2275 }
2279 2276 free(format_str);
2280 2277 return (e);
2281 2278 }
2282 2279
2283 2280 /*
2284 2281 * FUNCTION: get_search_triple
2285 2282 *
2286 2283 * Get the search triple or if NULL determine if valid
2287 2284 *
2288 2285 * RETURN VALUE: NULL if error
2289 2286 * position of beginning next token after
2290 2287 * search triple
2291 2288 *
2292 2289 * INPUT: the attribute value
2293 2290 */
2294 2291
2295 2292 const char *
2296 2293 get_search_triple(
2297 2294 const char *s,
2298 2295 const char *end_s,
2299 2296 __nis_search_triple_t *triple
2300 2297 )
2301 2298 {
2302 2299 const char *begin_token;
2303 2300 const char *end_token;
2304 2301 char *search_base = NULL;
2305 2302 int scope = LDAP_SCOPE_ONELEVEL;
2306 2303 char *filter = NULL;
2307 2304 const char *s1;
2308 2305 __nis_mapping_element_t
2309 2306 *element = NULL;
2310 2307
2311 2308 /*
2312 2309 * The form of the searchTriple is assumed to be as follows:
2313 2310 * searchTriple = [baseDN] ["?" [scope] ["?" [filter]]]
2314 2311 * baseDN = Base DN for search
2315 2312 * scope = "base" | "one" | "sub"
2316 2313 * filter = LDAP search filter
2317 2314 */
2318 2315 for (; p_error == no_parse_error; ) {
2319 2316 while (s < end_s && is_whitespace(*s))
2320 2317 s++;
2321 2318 if (s == end_s)
2322 2319 break;
2323 2320
2324 2321 if (!IS_TERMINAL_CHAR(*s)) {
2325 2322 begin_token = s;
2326 2323 s = skip_get_dn(begin_token, end_s);
2327 2324 if (s == NULL) {
2328 2325 p_error = parse_invalid_dn;
2329 2326 break;
2330 2327 }
2331 2328 if (triple != NULL) {
2332 2329 search_base = s_strndup(begin_token,
2333 2330 s - begin_token);
2334 2331 if (search_base == NULL)
2335 2332 break;
2336 2333 }
2337 2334 while (s < end_s && is_whitespace(*s))
2338 2335 s++;
2339 2336 if (s == end_s)
2340 2337 break;
2341 2338 }
2342 2339
2343 2340 if (!IS_TERMINAL_CHAR(*s)) {
2344 2341 p_error = parse_bad_ldap_item_format;
2345 2342 break;
2346 2343 }
2347 2344 if (*s != QUESTION_MARK)
2348 2345 break;
2349 2346
2350 2347 s++;
2351 2348 while (s < end_s && is_whitespace(*s))
2352 2349 s++;
2353 2350 if (s == end_s)
2354 2351 break;
2355 2352
2356 2353 /* base, one, or sub, or empty value */
2357 2354 if (!IS_TERMINAL_CHAR(*s)) {
2358 2355 if ((s1 = skip_string("base", s, end_s - s)) != NULL) {
2359 2356 scope = LDAP_SCOPE_BASE;
2360 2357 } else if ((s1 = skip_string("one", s, end_s - s)) !=
2361 2358 NULL) {
2362 2359 scope = LDAP_SCOPE_ONELEVEL;
2363 2360 } else if ((s1 = skip_string("sub", s, end_s - s)) !=
2364 2361 NULL) {
2365 2362 scope = LDAP_SCOPE_SUBTREE;
2366 2363 } else if (s + 1 < end_s && *s != QUESTION_MARK) {
2367 2364 p_error = parse_invalid_scope;
2368 2365 break;
2369 2366 }
2370 2367 if (s1 != NULL)
2371 2368 s = s1;
2372 2369 while (s < end_s && is_whitespace(*s))
2373 2370 s++;
2374 2371 }
2375 2372
2376 2373 if (s == end_s)
2377 2374 break;
2378 2375 if (*s != QUESTION_MARK)
2379 2376 break;
2380 2377 s++;
2381 2378 while (s < end_s && is_whitespace(*s))
2382 2379 s++;
2383 2380 if (s == end_s || IS_TERMINAL_CHAR(*s))
2384 2381 break;
2385 2382
2386 2383 /* LDAP search filter */
2387 2384 if (*s == OPEN_PAREN_CHAR) {
2388 2385 begin_token = s;
2389 2386 end_token = end_s;
2390 2387 s = get_ldap_filter(&begin_token, &end_token);
2391 2388 if (s == NULL)
2392 2389 break;
2393 2390 s = end_token;
2394 2391 element = get_ldap_filter_element(begin_token, end_token);
2395 2392 if (element != NULL)
2396 2393 break;
2397 2394 } else {
2398 2395 begin_token = s;
2399 2396 end_token = end_s;
2400 2397 s = get_ava_list(&begin_token, &end_token, TRUE);
2401 2398 if (s == NULL)
2402 2399 break;
2403 2400 s = end_token;
2404 2401 }
2405 2402 if (triple != NULL)
2406 2403 filter = s_strndup(begin_token, s - begin_token);
2407 2404 if (p_error == no_parse_error)
2408 2405 break;
2409 2406 }
2410 2407 if (p_error == no_parse_error && triple != NULL) {
2411 2408 triple->base = search_base;
2412 2409 triple->scope = scope;
2413 2410 triple->attrs = filter;
2414 2411 triple->element = element;
2415 2412 element = NULL;
2416 2413 filter = NULL;
2417 2414 search_base = NULL;
2418 2415 }
2419 2416
2420 2417 if (search_base != NULL)
2421 2418 free(search_base);
2422 2419 if (filter != NULL)
2423 2420 free(filter);
2424 2421 if (element != NULL) {
2425 2422 free_mapping_element(element);
2426 2423 free(element);
2427 2424 }
2428 2425 return (p_error == no_parse_error ? s : NULL);
2429 2426 }
2430 2427
2431 2428 /*
2432 2429 * FUNCTION: get_mapping_format
2433 2430 *
2434 2431 * Get the __nis_mapping_format_t from the string
2435 2432 *
2436 2433 * RETURN VALUE: FALSE if error
2437 2434 * TRUE if __nis_mapping_format_t returned
2438 2435 *
2439 2436 * INPUT: the format string
2440 2437 */
2441 2438
2442 2439 static bool_t
2443 2440 get_mapping_format(
2444 2441 const char *fmt_string,
2445 2442 __nis_mapping_format_t **fmt,
2446 2443 int *nfmt,
2447 2444 int *numItems,
2448 2445 bool_t print_mapping)
2449 2446 {
2450 2447 const char *f = fmt_string;
2451 2448 const char *ef;
2452 2449 __nis_mapping_format_t *b;
2453 2450 __nis_mapping_format_t *base = NULL;
2454 2451 int n = 0;
2455 2452 int nItems = 0;
2456 2453
2457 2454 f = fmt_string;
2458 2455 ef = f + strlen(f);
2459 2456 base = (__nis_mapping_format_t *)
2460 2457 s_calloc(1, sizeof (__nis_mapping_format_t));
2461 2458
2462 2459 if (base == NULL)
2463 2460 return (FALSE);
2464 2461 base->type = mmt_begin;
2465 2462 n++;
2466 2463
2467 2464 for (;;) {
2468 2465 b = (__nis_mapping_format_t *)s_realloc(
2469 2466 base, (n + 1) * sizeof (__nis_mapping_format_t));
2470 2467
2471 2468 if (b == NULL)
2472 2469 break;
2473 2470 base = b;
2474 2471 base[n].type = mmt_end;
2475 2472 if (f == ef) {
2476 2473 if (nfmt)
2477 2474 *nfmt = n + 1;
2478 2475 *fmt = base;
2479 2476 if (numItems)
2480 2477 *numItems = nItems;
2481 2478 return (TRUE);
2482 2479 }
2483 2480 if (print_mapping)
2484 2481 f = get_next_print_format_item(f, ef, &base[n]);
2485 2482 else
2486 2483 f = get_next_extract_format_item(f, ef, &base[n]);
2487 2484
2488 2485
2489 2486 if (f == NULL)
2490 2487 break;
2491 2488 if (base[n].type == mmt_item ||
2492 2489 base[n].type == mmt_berstring)
2493 2490 nItems++;
2494 2491 n++;
2495 2492 }
2496 2493 if (base != NULL)
2497 2494 free_mapping_format(base);
2498 2495 return (FALSE);
2499 2496 }
2500 2497
2501 2498 /*
2502 2499 * FUNCTION: getIndex
2503 2500 *
2504 2501 * Returns a string containing the index
2505 2502 *
2506 2503 * RETURN VALUE: NULL if error
2507 2504 * a string containing the index
2508 2505 *
2509 2506 * INPUT: attribute containing the index
2510 2507 */
2511 2508
2512 2509 static char *
2513 2510 getIndex(const char **s_cur, const char *s_end)
2514 2511 {
2515 2512 const char *s = *s_cur + 1;
2516 2513 const char *s1;
2517 2514 char *s_index;
2518 2515 char *s_index1;
2519 2516 char *s_index_end;
2520 2517 int n_brackets = 1;
2521 2518 bool_t in_quotes = FALSE;
2522 2519 char *index = NULL;
2523 2520
2524 2521 while (s < s_end && is_whitespace(*s))
2525 2522 s++;
2526 2523 for (s1 = s; s1 < s_end; s1++) {
2527 2524 if (*s1 == ESCAPE_CHAR)
2528 2525 s1++;
2529 2526 else if (*s1 == DOUBLE_QUOTE_CHAR) {
2530 2527 in_quotes = !in_quotes;
2531 2528 } else if (in_quotes)
2532 2529 ;
2533 2530 else if (*s1 == CLOSE_BRACKET) {
2534 2531 if (--n_brackets == 0)
2535 2532 break;
2536 2533 } else if (*s1 == OPEN_BRACKET)
2537 2534 n_brackets++;
2538 2535 }
2539 2536
2540 2537 if (n_brackets == 0) {
2541 2538 index = s_strndup(s, s1 - s);
2542 2539 if (index != NULL) {
2543 2540 s_index_end = index + (s1 - s);
2544 2541 s_index1 = index;
2545 2542 for (s_index = index; s_index < s_index_end;
2546 2543 s_index++) {
2547 2544 if (*s_index == ESCAPE_CHAR) {
2548 2545 *s_index1++ = *s_index++;
2549 2546 } else if (*s_index == DOUBLE_QUOTE_CHAR) {
2550 2547 in_quotes = !in_quotes;
2551 2548 } else if (!in_quotes &&
2552 2549 is_whitespace(*s_index)) {
2553 2550 continue;
2554 2551 }
2555 2552 *s_index1++ = *s_index;
2556 2553 }
2557 2554 *s_index1 = *s_index;
2558 2555
2559 2556 s = s1 + 1;
2560 2557
2561 2558 while (s < s_end && is_whitespace(*s))
2562 2559 s++;
2563 2560 *s_cur = s;
2564 2561 }
2565 2562 } else
2566 2563 p_error = parse_mismatched_brackets;
2567 2564
2568 2565 return (index);
2569 2566 }
2570 2567
2571 2568 /*
2572 2569 * FUNCTION: parse_index
2573 2570 *
2574 2571 * Parse attribute string to get __nis_index_t
2575 2572 *
2576 2573 * RETURN VALUE: FALSE if error
2577 2574 * TRUE if __nis_index_t returned
2578 2575 *
2579 2576 * INPUT: the attribute value to parse
2580 2577 */
2581 2578
2582 2579 bool_t
2583 2580 parse_index(const char *s, const char *end_s, __nis_index_t *index)
2584 2581 {
2585 2582 const char *begin_token;
2586 2583 const char *end_token;
2587 2584 char *name_str = NULL;
2588 2585 char **name;
2589 2586 char *fmt_string = NULL;
2590 2587 __nis_mapping_format_t *v = NULL;
2591 2588 __nis_mapping_format_t **value;
2592 2589 token_type t;
2593 2590 int n = 0;
2594 2591
2595 2592 if (index != NULL)
2596 2593 (void) memset(index, 0, sizeof (*index));
2597 2594
2598 2595 while (s < end_s) {
2599 2596 if (n > 0) {
2600 2597 s = skip_token(s, end_s, comma_token);
2601 2598 if (s == NULL) {
2602 2599 p_error = parse_bad_index_format;
2603 2600 break;
2604 2601 }
2605 2602 }
2606 2603 begin_token = s;
2607 2604 end_token = end_s;
2608 2605 s = get_next_token(&begin_token, &end_token, &t);
2609 2606 if (s == NULL)
2610 2607 break;
2611 2608 if (t != string_token) {
2612 2609 p_error = parse_bad_index_format;
2613 2610 break;
2614 2611 }
2615 2612 s = skip_token(s, end_s, equal_token);
2616 2613 if (s == NULL) {
2617 2614 p_error = parse_bad_index_format;
2618 2615 break;
2619 2616 }
2620 2617 if (index != NULL) {
2621 2618 name_str = s_strndup_esc(begin_token,
2622 2619 end_token - begin_token);
2623 2620 if (name_str == NULL)
2624 2621 break;
2625 2622 }
2626 2623 begin_token = s;
2627 2624 end_token = end_s;
2628 2625 s = get_next_token(&begin_token, &end_token, &t);
2629 2626 if (s == NULL)
2630 2627 break;
2631 2628 if (t != string_token && t != quoted_string_token) {
2632 2629 p_error = parse_bad_index_format;
2633 2630 break;
2634 2631 }
2635 2632 fmt_string = s_strndup(begin_token, end_token - begin_token);
2636 2633 if (fmt_string == NULL)
2637 2634 break;
2638 2635 if (!get_mapping_format(fmt_string, &v, NULL, NULL, FALSE))
2639 2636 break;
2640 2637 free(fmt_string);
2641 2638 fmt_string = NULL;
2642 2639 if (index != NULL) {
2643 2640 name = s_realloc(index->name,
2644 2641 (n + 1) * sizeof (char *));
2645 2642 if (name == NULL)
2646 2643 break;
2647 2644 value = s_realloc(index->value,
2648 2645 (n + 1) * sizeof (__nis_mapping_format_t *));
2649 2646 if (value == NULL)
2650 2647 break;
2651 2648 name[n] = name_str;
2652 2649 name_str = NULL;
2653 2650 value[n] = v;
2654 2651 v = NULL;
2655 2652 index->numIndexes = ++n;
2656 2653 index->name = name;
2657 2654 index->value = value;
2658 2655 } else if (v != NULL) {
2659 2656 free_mapping_format(v);
2660 2657 v = NULL;
2661 2658 }
2662 2659 }
2663 2660 if (p_error != no_parse_error) {
2664 2661 if (name_str != NULL)
2665 2662 free(name_str);
2666 2663 if (v != NULL)
2667 2664 free_mapping_format(v);
2668 2665 if (fmt_string != NULL)
2669 2666 free(fmt_string);
2670 2667 if (index != NULL)
2671 2668 free_index(index);
2672 2669 }
2673 2670 return (p_error != no_parse_error);
2674 2671 }
2675 2672
2676 2673 /*
2677 2674 * FUNCTION: get_deleteDisp
2678 2675 *
2679 2676 * Parse deleteDisp. Sets p_error if an error occurred.
2680 2677 *
2681 2678 * RETURN VALUE: TRUE on success
2682 2679 * FAILURE on failure
2683 2680 *
2684 2681 * INPUT: begin and end of string and __nis_object_dn_t
2685 2682 */
2686 2683
2687 2684 static bool_t
2688 2685 get_deleteDisp(const char *s_begin, const char *s_end,
2689 2686 __nis_object_dn_t *obj_dn)
2690 2687 {
2691 2688 /*
2692 2689 * deleteDisp: "always" | perDbId | "never"
2693 2690 * perDbId: "dbid" "=" delDatabaseId
2694 2691 */
2695 2692
2696 2693 if (same_string("always", s_begin, s_end - s_begin)) {
2697 2694 obj_dn->delDisp = dd_always;
2698 2695 } else if (same_string("never", s_begin, s_end - s_begin)) {
2699 2696 obj_dn->delDisp = dd_never;
2700 2697 } else if ((s_begin = skip_string("dbid", s_begin, s_end - s_begin))
2701 2698 != NULL) {
2702 2699 obj_dn->delDisp = dd_perDbId;
2703 2700 while (s_begin < s_end && is_whitespace(*s_begin))
2704 2701 s_begin++;
2705 2702 if (s_begin == s_end || *s_begin != EQUAL_CHAR) {
2706 2703 p_error = parse_object_dn_syntax_error;
2707 2704 } else {
2708 2705 s_begin++;
2709 2706 while (s_begin < s_end && is_whitespace(*s_begin))
2710 2707 s_begin++;
2711 2708 while (s_begin < s_end && is_whitespace(s_end[-1]))
2712 2709 s_end--;
2713 2710 if (s_begin == s_end) {
2714 2711 p_error = parse_object_dn_syntax_error;
2715 2712 } else {
2716 2713 obj_dn->dbIdName =
2717 2714 s_strndup(s_begin, s_end - s_begin);
2718 2715 }
2719 2716 }
2720 2717 } else {
2721 2718 p_error = parse_object_dn_syntax_error;
2722 2719 }
2723 2720 return (p_error == no_parse_error);
2724 2721 }
↓ open down ↓ |
643 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX