Home | History | Annotate | Download | only in libnisdb
      1 /*
      2  * CDDL HEADER START
      3  *
      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
      7  * with the License.
      8  *
      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.
     13  *
     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]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <stdlib.h>
     32 #include <ctype.h>
     33 #include <fcntl.h>
     34 #include <unistd.h>
     35 #include <errno.h>
     36 #include <locale.h>
     37 #include <lber.h>
     38 #include <ldap.h>
     39 #include <syslog.h>
     40 #include <dlfcn.h>	/* for dynamic loading only */
     41 
     42 #include "ldap_parse.h"
     43 #include "nis_parse_ldap_conf.h"
     44 #include "nis_parse_ldap_err.h"
     45 #include "ldap_util.h"
     46 #include "ldap_util.h"
     47 
     48 void append_dot(char **str);
     49 void	append_comma(char **str);
     50 bool_t make_full_dn(char **dn, const char *base);
     51 bool_t make_fqdn(__nis_object_dn_t *dn, const char *base);
     52 char *get_default_ldap_base(const char *domain);
     53 bool_t add_domain(char **objName, const char *domain);
     54 bool_t add_column(__nis_table_mapping_t *t, const char *col_name);
     55 __nis_mapping_rule_t **dup_mapping_rules(
     56 	__nis_mapping_rule_t **rules, int n_rules);
     57 __nis_mapping_rule_t *dup_mapping_rule(
     58 	__nis_mapping_rule_t *in);
     59 void *s_malloc(size_t size);
     60 __nis_mapping_format_t *dup_format_mapping(
     61 	__nis_mapping_format_t *in);
     62 bool_t dup_mapping_element(__nis_mapping_element_t *in,
     63 	__nis_mapping_element_t *out);
     64 
     65 extern FILE *cons;
     66 
     67 /*
     68  * FUNCTION:	free_parse_structs
     69  *
     70  *	Release the resources in parse results
     71  *
     72  */
     73 
     74 void
     75 free_parse_structs()
     76 {
     77 	__nis_table_mapping_t	*t;
     78 	__nis_table_mapping_t	*t1;
     79 
     80 	free_proxy_info(&proxyInfo);
     81 	for (t = ldapTableMapping; t != NULL; t = t1) {
     82 		t1 = t->next;
     83 		free_table_mapping(t);
     84 	}
     85 	ldapTableMapping = NULL;
     86 }
     87 
     88 /*
     89  * FUNCTION:	initialize_parse_structs
     90  *
     91  *	Initialize fields to unset values
     92  *
     93  * INPUT:		__nis_ldap_proxy_info, __nis_config_t
     94  * 			and __nisdb_table_mapping_t structures
     95  */
     96 
     97 void
     98 initialize_parse_structs(
     99 	__nis_ldap_proxy_info	*proxy_info,
    100 	__nis_config_t		*config_info,
    101 	__nisdb_table_mapping_t	*table_info)
    102 {
    103 	proxy_info->default_servers = NULL;
    104 	proxy_info->auth_method = (auth_method_t)NO_VALUE_SET;
    105 	proxy_info->tls_method = (tls_method_t)NO_VALUE_SET;
    106 	proxy_info->tls_cert_db = NULL;
    107 	proxy_info->default_search_base = NULL;
    108 	proxy_info->proxy_dn = NULL;
    109 	proxy_info->proxy_passwd = NULL;
    110 	proxy_info->default_nis_domain = NULL;
    111 	proxy_info->bind_timeout.tv_sec = (time_t)NO_VALUE_SET;
    112 	proxy_info->bind_timeout.tv_usec = 0;
    113 	proxy_info->search_timeout.tv_sec = (time_t)NO_VALUE_SET;
    114 	proxy_info->search_timeout.tv_usec = 0;
    115 	proxy_info->modify_timeout.tv_sec = (time_t)NO_VALUE_SET;
    116 	proxy_info->modify_timeout.tv_usec = 0;
    117 	proxy_info->add_timeout.tv_sec = (time_t)NO_VALUE_SET;
    118 	proxy_info->add_timeout.tv_usec = 0;
    119 	proxy_info->delete_timeout.tv_sec = (time_t)NO_VALUE_SET;
    120 	proxy_info->delete_timeout.tv_usec = 0;
    121 	proxy_info->search_time_limit = (int)NO_VALUE_SET;
    122 	proxy_info->search_size_limit = (int)NO_VALUE_SET;
    123 	proxy_info->follow_referral = (follow_referral_t)NO_VALUE_SET;
    124 
    125 
    126 	config_info->initialUpdate = (__nis_initial_update_t)NO_VALUE_SET;
    127 	config_info->threadCreationError =
    128 		(__nis_thread_creation_error_t)NO_VALUE_SET;
    129 	config_info->threadCreationErrorTimeout.attempts = NO_VALUE_SET;
    130 	config_info->threadCreationErrorTimeout.timeout = (time_t)NO_VALUE_SET;
    131 	config_info->dumpError = (__nis_dump_error_t)NO_VALUE_SET;
    132 	config_info->dumpErrorTimeout.attempts = NO_VALUE_SET;
    133 	config_info->dumpErrorTimeout.timeout = (time_t)NO_VALUE_SET;
    134 	config_info->resyncService = (__nis_resync_service_t)NO_VALUE_SET;
    135 	config_info->updateBatching = (__nis_update_batching_t)NO_VALUE_SET;
    136 	config_info->updateBatchingTimeout.timeout = (time_t)NO_VALUE_SET;
    137 	config_info->numberOfServiceThreads = (int)NO_VALUE_SET;
    138 	config_info->emulate_yp = (int)NO_VALUE_SET;
    139 	config_info->maxRPCRecordSize = (int)NO_VALUE_SET;
    140 
    141 	table_info->retrieveError = (__nis_retrieve_error_t)NO_VALUE_SET;
    142 	table_info->retrieveErrorRetry.attempts = NO_VALUE_SET;
    143 	table_info->retrieveErrorRetry.timeout = (time_t)NO_VALUE_SET;
    144 	table_info->storeError = (__nis_store_error_t)NO_VALUE_SET;
    145 	table_info->storeErrorRetry.attempts = NO_VALUE_SET;
    146 	table_info->storeErrorRetry.timeout = (time_t)NO_VALUE_SET;
    147 	table_info->refreshError = (__nis_refresh_error_t)NO_VALUE_SET;
    148 	table_info->refreshErrorRetry.attempts = NO_VALUE_SET;
    149 	table_info->refreshErrorRetry.timeout = (time_t)NO_VALUE_SET;
    150 	table_info->matchFetch = (__nis_match_fetch_t)NO_VALUE_SET;
    151 }
    152 
    153 /*
    154  * FUNCTION:	free_mapping_rule
    155  *
    156  *	Frees __nis_mapping_rule_t
    157  *
    158  * INPUT:		__nis_mapping_rule_t
    159  */
    160 
    161 void
    162 free_mapping_rule(__nis_mapping_rule_t	*rule)
    163 {
    164 	int			i;
    165 	__nis_mapping_rlhs_t	*r;
    166 
    167 	if (rule != NULL) {
    168 		r = &rule->lhs;
    169 		for (i = 0; i < r->numElements; i++)
    170 			free_mapping_element(&r->element[i]);
    171 		if (r->element != NULL)
    172 			free(r->element);
    173 
    174 		r = &rule->rhs;
    175 		for (i = 0; i < r->numElements; i++)
    176 			free_mapping_element(&r->element[i]);
    177 		if (r->element != NULL)
    178 			free(r->element);
    179 
    180 		free(rule);
    181 	}
    182 }
    183 
    184 /*
    185  * FUNCTION:	free_mapping_element
    186  *
    187  *	Frees __nis_mapping_element_t
    188  *
    189  * INPUT:		__nis_mapping_element_t
    190  */
    191 
    192 void
    193 free_mapping_element(__nis_mapping_element_t *e)
    194 {
    195 	int	i;
    196 
    197 	if (e == NULL)
    198 		return;
    199 
    200 	switch (e->type) {
    201 	    case me_item:
    202 		free_mapping_item(&e->element.item);
    203 		break;
    204 	    case me_print:
    205 		if (e->element.print.fmt != NULL)
    206 			free_mapping_format(e->element.print.fmt);
    207 		e->element.print.fmt = NULL;
    208 		for (i = 0; i < e->element.print.numSubElements; i++)
    209 			free_mapping_sub_element(
    210 				&e->element.print.subElement[i]);
    211 		e->element.print.numSubElements = 0;
    212 		if (e->element.print.subElement != NULL)
    213 			free(e->element.print.subElement);
    214 		e->element.print.subElement = NULL;
    215 		break;
    216 	    case me_split:
    217 		free_mapping_item(&e->element.split.item);
    218 		break;
    219 	    case me_match:
    220 		if (e->element.match.fmt != NULL)
    221 			free_mapping_format(e->element.match.fmt);
    222 		e->element.match.fmt = NULL;
    223 		for (i = 0; i < e->element.match.numItems; i++)
    224 			free_mapping_item(&e->element.match.item[i]);
    225 		e->element.match.numItems = 0;
    226 		if (e->element.match.item != NULL)
    227 		    free(e->element.match.item);
    228 		e->element.match.item = NULL;
    229 		break;
    230 	    case me_extract:
    231 		if (e->element.extract.fmt != NULL)
    232 			free_mapping_format(e->element.extract.fmt);
    233 		e->element.extract.fmt = NULL;
    234 		free_mapping_item(&e->element.extract.item);
    235 		break;
    236 	}
    237 	e = NULL;
    238 }
    239 
    240 /*
    241  * FUNCTION:	free_table_mapping
    242  *
    243  *	Frees __nis_table_mapping_t
    244  *
    245  * INPUT:		__nis_table_mapping_t
    246  */
    247 
    248 /*
    249  * free_table_mapping does not remove the table mapping from
    250  * its hashed list
    251  */
    252 
    253 void
    254 free_table_mapping(__nis_table_mapping_t *mapping)
    255 {
    256 	int	i;
    257 
    258 	if (mapping == NULL)
    259 		return;
    260 
    261 	if (mapping->dbId != NULL)
    262 		free(mapping->dbId);
    263 	mapping->dbId = NULL;
    264 
    265 	if (mapping->objName != NULL)
    266 		free(mapping->objName);
    267 	mapping->objName = NULL;
    268 
    269 	for (i = 0; i < mapping->index.numIndexes; i++) {
    270 		free(mapping->index.name[i]);
    271 		free_mapping_format(mapping->index.value[i]);
    272 	}
    273 
    274 	if (mapping->index.name != NULL)
    275 		free(mapping->index.name);
    276 	mapping->index.name = NULL;
    277 
    278 	if (mapping->index.value != NULL)
    279 		free(mapping->index.value);
    280 	mapping->index.value = NULL;
    281 
    282 	mapping->index.numIndexes = 0;
    283 
    284 	if (mapping->column != NULL) {
    285 		for (i = 0; i < mapping->numColumns; i++) {
    286 			free(mapping->column[i]);
    287 		}
    288 		mapping->numColumns = 0;
    289 		free(mapping->column);
    290 		mapping->column = NULL;
    291 	}
    292 
    293 	if (mapping->commentChar != NULL)
    294 		mapping->commentChar = NULL;
    295 
    296 	if (mapping->objectDN != NULL)
    297 		free_object_dn(mapping->objectDN);
    298 	mapping->objectDN = NULL;
    299 
    300 	if (mapping->separatorStr != NULL)
    301 		mapping->separatorStr = NULL;
    302 
    303 	for (i = 0; i < mapping->numRulesFromLDAP; i++) {
    304 		if (mapping->ruleFromLDAP[i]) /* See Comment below */
    305 			free_mapping_rule(mapping->ruleFromLDAP[i]);
    306 	}
    307 	mapping->numRulesFromLDAP = 0;
    308 
    309 	if (mapping->ruleFromLDAP != NULL)
    310 		free(mapping->ruleFromLDAP);
    311 	mapping->ruleFromLDAP = NULL;
    312 
    313 	for (i = 0; i < mapping->numRulesToLDAP; i++) {
    314 		if (mapping->ruleToLDAP[i])
    315 		/*
    316 		 * Normally mapping->ruleToLDAP[i] should
    317 		 * always be non-null if
    318 		 * mapping->numRulesToLDAP is > 0.
    319 		 * However it is possible to have data
    320 		 * corruption where numRulesToLDAP gets
    321 		 * some integer value even though no real
    322 		 * data is present in mapping->ruleToLDAP.
    323 		 */
    324 			free_mapping_rule(mapping->ruleToLDAP[i]);
    325 	}
    326 	mapping->numRulesToLDAP = 0;
    327 
    328 	if (mapping->ruleToLDAP != NULL)
    329 		free(mapping->ruleToLDAP);
    330 	mapping->ruleToLDAP = NULL;
    331 
    332 	if (mapping->e != NULL) {
    333 		/* Similar logic as in above comment applies. */
    334 		for (i = 0; i <= mapping->numSplits; i++) {
    335 			free_mapping_element(&mapping->e[i]);
    336 		}
    337 		free(mapping->e);
    338 	}
    339 	mapping->e = NULL;
    340 
    341 	mapping->numSplits = 0;
    342 
    343 	free(mapping);
    344 }
    345 
    346 /*
    347  * FUNCTION:	free_config_info
    348  *
    349  *	Frees __nis_config_info_t
    350  *
    351  * INPUT:		__nis_config_info_t
    352  */
    353 
    354 void
    355 free_config_info(__nis_config_info_t *config_info)
    356 {
    357 	if (config_info->config_dn != NULL)
    358 		free(config_info->config_dn);
    359 	config_info->config_dn = NULL;
    360 
    361 	if (config_info->default_servers != NULL)
    362 		free(config_info->default_servers);
    363 	config_info->default_servers = NULL;
    364 
    365 	if (config_info->proxy_dn != NULL)
    366 		free(config_info->proxy_dn);
    367 	config_info->proxy_dn = NULL;
    368 
    369 	if (config_info->proxy_passwd != NULL)
    370 		free(config_info->proxy_passwd);
    371 	config_info->proxy_passwd = NULL;
    372 
    373 	if (config_info->tls_cert_db != NULL)
    374 		free(config_info->tls_cert_db);
    375 	config_info->tls_cert_db = NULL;
    376 }
    377 
    378 /*
    379  * FUNCTION:	free_proxy_info
    380  *
    381  *	Frees __nis_ldap_proxy_info
    382  *
    383  * INPUT:		__nis_ldap_proxy_info
    384  */
    385 
    386 void
    387 free_proxy_info(__nis_ldap_proxy_info *proxy_info)
    388 {
    389 	if (proxy_info->tls_cert_db != NULL)
    390 		free(proxy_info->tls_cert_db);
    391 	proxy_info->tls_cert_db = NULL;
    392 
    393 	if (proxy_info->default_servers != NULL)
    394 		free(proxy_info->default_servers);
    395 	proxy_info->default_servers = NULL;
    396 
    397 	if (proxy_info->default_search_base != NULL)
    398 		free(proxy_info->default_search_base);
    399 	proxy_info->default_search_base = NULL;
    400 
    401 	if (proxy_info->proxy_dn != NULL)
    402 		free(proxy_info->proxy_dn);
    403 	proxy_info->proxy_dn = NULL;
    404 
    405 	if (proxy_info->proxy_passwd != NULL)
    406 		free(proxy_info->proxy_passwd);
    407 	proxy_info->proxy_passwd = NULL;
    408 
    409 	if (proxy_info->default_nis_domain != NULL)
    410 		free(proxy_info->default_nis_domain);
    411 	proxy_info->default_nis_domain = NULL;
    412 }
    413 
    414 /*
    415  * FUNCTION:	free_object_dn
    416  *
    417  *	Frees __nis_object_dn_t
    418  *
    419  * INPUT:		__nis_object_dn_t
    420  */
    421 
    422 void
    423 free_object_dn(__nis_object_dn_t *obj_dn)
    424 {
    425 	__nis_object_dn_t	*t;
    426 	int			i;
    427 
    428 	while (obj_dn != NULL) {
    429 		if (obj_dn->read.base != NULL)
    430 			free(obj_dn->read.base);
    431 		obj_dn->read.base = NULL;
    432 		if (obj_dn->read.attrs != NULL)
    433 			free(obj_dn->read.attrs);
    434 		obj_dn->read.attrs = NULL;
    435 		if (obj_dn->write.base != NULL)
    436 			free(obj_dn->write.base);
    437 		obj_dn->write.base = NULL;
    438 		if (obj_dn->write.attrs != NULL)
    439 			free(obj_dn->write.attrs);
    440 		obj_dn->write.attrs = NULL;
    441 		if (obj_dn->dbIdName != NULL)
    442 			free(obj_dn->dbIdName);
    443 		obj_dn->dbIdName = NULL;
    444 		for (i = 0; i < obj_dn->numDbIds; i++)
    445 			free_mapping_rule(obj_dn->dbId[i]);
    446 		obj_dn->numDbIds = 0;
    447 
    448 		if (obj_dn->dbId != NULL)
    449 			free(obj_dn->dbId);
    450 		obj_dn->dbId = NULL;
    451 
    452 		t = obj_dn;
    453 		obj_dn = obj_dn->next;
    454 		free(t);
    455 	}
    456 }
    457 
    458 /*
    459  * FUNCTION:	free_index
    460  *
    461  *	Frees __nis_index_t
    462  *
    463  * INPUT:		__nis_index_t
    464  */
    465 
    466 void
    467 free_index(__nis_index_t *index)
    468 {
    469 	int	i;
    470 	for (i = 0; i < index->numIndexes; i++) {
    471 		free(index->name[i]);
    472 		free_mapping_format(index->value[i]);
    473 	}
    474 	index->numIndexes = 0;
    475 	if (index->name != NULL)
    476 		free(index->name);
    477 	index->name = NULL;
    478 	if (index->value != NULL)
    479 		free(index->value);
    480 	index->value = NULL;
    481 }
    482 
    483 /*
    484  * FUNCTION:	free_mapping_item
    485  *
    486  *	Frees __nis_mapping_item_t
    487  *
    488  * INPUT:		__nis_mapping_item_t
    489  */
    490 
    491 void
    492 free_mapping_item(__nis_mapping_item_t	*item)
    493 {
    494 	if (item == NULL)
    495 		return;
    496 
    497 	if (item->name != NULL)
    498 		free(item->name);
    499 	item->name = NULL;
    500 	if (item->type == mit_nisplus) {
    501 		free_index(&item->searchSpec.obj.index);
    502 		if (item->searchSpec.obj.name != NULL)
    503 			free(item->searchSpec.obj.name);
    504 		item->searchSpec.obj.name = NULL;
    505 	} else if (item->type == mit_ldap) {
    506 		if (item->searchSpec.triple.base != NULL)
    507 			free(item->searchSpec.triple.base);
    508 		item->searchSpec.triple.base = NULL;
    509 		if (item->searchSpec.triple.attrs != NULL)
    510 			free(item->searchSpec.triple.attrs);
    511 		item->searchSpec.triple.attrs = NULL;
    512 		if (item->searchSpec.triple.element != NULL) {
    513 			free_mapping_element(
    514 				item->searchSpec.triple.element);
    515 			free(item->searchSpec.triple.element);
    516 		}
    517 		item->searchSpec.triple.element = NULL;
    518 	}
    519 	if (item->exItem != NULL) {
    520 		free_mapping_item(item->exItem);
    521 		free(item->exItem);
    522 		item->exItem = 0;
    523 	}
    524 }
    525 
    526 /*
    527  * FUNCTION:	free_mapping_format
    528  *
    529  *	Frees __nis_mapping_format_t
    530  *
    531  * INPUT:		__nis_mapping_format_t
    532  */
    533 
    534 void
    535 free_mapping_format(__nis_mapping_format_t *fmt)
    536 {
    537 	__nis_mapping_format_t *f = fmt;
    538 
    539 	while (fmt->type != mmt_end) {
    540 		switch (fmt->type) {
    541 		    case mmt_item:
    542 			break;
    543 		    case mmt_string:
    544 			if (fmt->match.string != NULL)
    545 				free(fmt->match.string);
    546 			fmt->match.string = NULL;
    547 			break;
    548 		    case mmt_single:
    549 			if (fmt->match.single.lo != NULL)
    550 				free(fmt->match.single.lo);
    551 			fmt->match.single.lo = NULL;
    552 			if (fmt->match.single.hi != NULL)
    553 				free(fmt->match.single.hi);
    554 			fmt->match.single.hi = NULL;
    555 			break;
    556 		    case mmt_limit:
    557 			break;
    558 		    case mmt_any:
    559 			break;
    560 		    case mmt_berstring:
    561 		    case mmt_berstring_null:
    562 			if (fmt->match.berString != NULL)
    563 				free(fmt->match.berString);
    564 			fmt->match.berString = NULL;
    565 			break;
    566 		    case mmt_begin:
    567 			break;
    568 		    case mmt_end:
    569 			break;
    570 		}
    571 		fmt++;
    572 	}
    573 	free(f);
    574 }
    575 
    576 /*
    577  * FUNCTION:	free_mapping_sub_element
    578  *
    579  *	Frees __nis_mapping_sub_element_t
    580  *
    581  * INPUT:		__nis_mapping_sub_element_t
    582  */
    583 
    584 void
    585 free_mapping_sub_element(__nis_mapping_sub_element_t *sub)
    586 {
    587 	int	i;
    588 
    589 	switch (sub->type) {
    590 	    case me_item:
    591 		free_mapping_item(&sub->element.item);
    592 		break;
    593 	    case me_print:
    594 		if (sub->element.print.fmt != NULL)
    595 			free_mapping_format(sub->element.print.fmt);
    596 		sub->element.print.fmt = NULL;
    597 		for (i = 0; i < sub->element.print.numItems; i++)
    598 			free_mapping_item(&sub->element.print.item[i]);
    599 		sub->element.print.numItems = 0;
    600 		if (sub->element.print.item != NULL)
    601 			free(sub->element.print.item);
    602 		sub->element.print.item = NULL;
    603 		break;
    604 	    case me_split:
    605 		free_mapping_item(&sub->element.split.item);
    606 		break;
    607 	    case me_extract:
    608 		if (sub->element.extract.fmt != NULL)
    609 			free_mapping_format(sub->element.extract.fmt);
    610 		sub->element.extract.fmt = NULL;
    611 		free_mapping_item(&sub->element.extract.item);
    612 		break;
    613 	}
    614 }
    615 
    616 /*
    617  * FUNCTION:	read_line
    618  *
    619  *	Gets next line in buffer - using '\' at end of line
    620  *  to indicate continuation. Lines beginning with # are
    621  *	ignored. start_line_num and start_line_num are
    622  *	maintained to track the line number currently being
    623  *	parsed.
    624  *
    625  * RETURN VALUE:	The number of characters read. 0 for
    626  *                      eof, -1 for error
    627  *
    628  * INPUT:		file descriptor, buffer, and buffer size
    629  */
    630 
    631 int
    632 read_line(int fd, char *buffer, int buflen)
    633 {
    634 	int		linelen;
    635 	int		rc;
    636 	char		c;
    637 	bool_t		skip_line	= FALSE;
    638 	bool_t		begin_line	= TRUE;
    639 	static bool_t	prev_cr		= FALSE;
    640 
    641 	start_line_num = cur_line_num;
    642 	(void) memset(buffer, 0, buflen);
    643 	for (; p_error == no_parse_error; ) {
    644 		linelen = 0;
    645 		while (linelen < buflen) {
    646 			rc = read(fd, &c, 1);
    647 			if (1 == rc) {
    648 				if (c == '\n' || c == '\r') {
    649 					if (c == '\n') {
    650 						if (prev_cr) {
    651 							prev_cr = FALSE;
    652 							continue;
    653 						} else {
    654 							if (linelen == 0)
    655 							    start_line_num =
    656 								cur_line_num;
    657 							else {
    658 								if (
    659 								is_string_ok(
    660 								buffer,
    661 								linelen)) {
    662 								(void) memset(
    663 								buffer, 0,
    664 								linelen);
    665 								linelen = 0;
    666 								cur_line_num++;
    667 								begin_line =
    668 									TRUE;
    669 								continue;
    670 								}
    671 							}
    672 							cur_line_num++;
    673 						}
    674 						prev_cr = FALSE;
    675 					} else {
    676 						prev_cr = TRUE;
    677 						if (linelen == 0)
    678 						    start_line_num =
    679 							cur_line_num;
    680 						cur_line_num++;
    681 					}
    682 					if (skip_line) {
    683 						skip_line = FALSE;
    684 						if (linelen == 0)
    685 						    start_line_num =
    686 							cur_line_num;
    687 					} else if (linelen > 0 &&
    688 					    buffer[linelen - 1]
    689 					    == ESCAPE_CHAR) {
    690 						--linelen;
    691 					} else if (linelen > 0) {
    692 						buffer[linelen] = '\0';
    693 						return (linelen);
    694 					}
    695 					begin_line = TRUE;
    696 				} else {
    697 					if (begin_line)
    698 						skip_line = c == POUND_SIGN;
    699 					begin_line = FALSE;
    700 					if (!skip_line)
    701 						buffer[linelen++] = c;
    702 				}
    703 			} else {
    704 				if (linelen > 0 &&
    705 				    buffer[linelen - 1] == ESCAPE_CHAR) {
    706 					/* continuation on last line */
    707 					p_error = parse_bad_continuation_error;
    708 					return (-1);
    709 				} else {
    710 					buffer[linelen] = '\0';
    711 					return (linelen);
    712 				}
    713 			}
    714 		}
    715 		p_error = parse_line_too_long;
    716 	}
    717 	return (-1);
    718 }
    719 
    720 /*
    721  * FUNCTION:	finish_parse
    722  *
    723  *	Adds any elements not configured, fully qualifies
    724  *      names
    725  *
    726  * RETURN VALUE:	0 on success, -1 on failure
    727  */
    728 
    729 int
    730 finish_parse(
    731 	__nis_ldap_proxy_info	*proxy_info,
    732 	__nis_table_mapping_t	**table_mapping)
    733 {
    734 	__nis_table_mapping_t	*t;
    735 	__nis_table_mapping_t	*t1;
    736 	__nis_table_mapping_t	*t2;
    737 	__nis_table_mapping_t	*t_del		= NULL;
    738 	int			i;
    739 	int			j;
    740 	int			k;
    741 	__nis_object_dn_t	*objectDN;
    742 	__nis_mapping_rlhs_t	*lhs;
    743 	__nis_mapping_element_t	*e;
    744 	char			*s;
    745 	int			errnum;
    746 
    747 	/* set to default those values yet set */
    748 	if (proxy_info->auth_method ==
    749 	    (auth_method_t)NO_VALUE_SET) {
    750 		p_error = parse_no_proxy_auth_error;
    751 		report_error(NULL, NULL);
    752 		return (-1);
    753 	}
    754 
    755 	if (proxy_info->default_servers == NULL) {
    756 		p_error = parse_no_ldap_server_error;
    757 		report_error(NULL, NULL);
    758 		return (-1);
    759 	}
    760 
    761 	if (proxy_info->tls_method == (tls_method_t)NO_VALUE_SET)
    762 		proxy_info->tls_method = no_tls;
    763 	else if (proxy_info->tls_method == ssl_tls &&
    764 			(proxy_info->tls_cert_db == NULL ||
    765 			*proxy_info->tls_cert_db == '\0')) {
    766 		p_error = parse_no_cert_db;
    767 		report_error(NULL, NULL);
    768 		return (-1);
    769 	}
    770 
    771 	if (proxy_info->default_nis_domain == NULL)
    772 		proxy_info->default_nis_domain =
    773 			s_strdup(__nis_rpc_domain());
    774 	else if (*proxy_info->default_nis_domain == '\0') {
    775 		free(proxy_info->default_nis_domain);
    776 		proxy_info->default_nis_domain =
    777 			s_strdup(__nis_rpc_domain());
    778 	}
    779 	if (proxy_info->default_nis_domain != NULL)
    780 		append_dot(&proxy_info->default_nis_domain);
    781 
    782 	if (proxy_info->tls_method == ssl_tls) {
    783 		if ((errnum = ldapssl_client_init(
    784 				proxy_info->tls_cert_db, NULL)) < 0) {
    785 			p_error = parse_ldapssl_client_init_error;
    786 			report_error(ldapssl_err2string(errnum), NULL);
    787 			return (-1);
    788 		}
    789 	}
    790 
    791 	if (proxy_info->default_search_base == NULL)
    792 	    proxy_info->default_search_base =
    793 		get_default_ldap_base(proxy_info->default_nis_domain);
    794 
    795 	/* convert a relative dn to a fullly qualified dn */
    796 	(void) make_full_dn(&proxy_info->proxy_dn,
    797 		proxy_info->default_search_base);
    798 
    799 	if (p_error != no_parse_error) {
    800 		report_error(NULL, NULL);
    801 		return (-1);
    802 	}
    803 
    804 	/*
    805 	 * Create a list of potential delete mappings
    806 	 * those have NULL objectDNs, but badly also rules
    807 	 * that are missing object dn's will be included.
    808 	 * We will use the ttl field to determine if the
    809 	 * delete rule is actually used
    810 	 */
    811 	t2 = NULL;
    812 	for (t = *table_mapping; t != NULL; t = t1) {
    813 		t1 = t->next;
    814 		if (t->objectDN == NULL) {
    815 			if (t2 == NULL)
    816 				*table_mapping = t1;
    817 			else
    818 				t2->next = t1;
    819 			t->next = t_del;
    820 			t_del = t;
    821 			t->ttl = 0;
    822 		} else
    823 			t2 = t;
    824 	}
    825 
    826 	for (t = *table_mapping; t != NULL; t = t->next) {
    827 	    objectDN = t->objectDN;
    828 	    while (objectDN != NULL) {
    829 		if (objectDN->dbIdName != NULL) {
    830 			s = objectDN->dbIdName;
    831 			t1 = find_table_mapping(s, strlen(s), t_del);
    832 			if (t1 == NULL) {
    833 				p_error = parse_no_db_del_mapping_rule;
    834 				report_error2(objectDN->dbIdName, t->dbId);
    835 				return (-1);
    836 			} else if (t1->objName != NULL ||
    837 			    t1->numRulesToLDAP == 0 ||
    838 			    t1->numRulesFromLDAP != 0) {
    839 				p_error = parse_invalid_db_del_mapping_rule;
    840 				report_error(t1->dbId, NULL);
    841 				return (-1);
    842 			}
    843 			objectDN->dbId =
    844 				dup_mapping_rules(t1->ruleToLDAP,
    845 					t1->numRulesToLDAP);
    846 			if (objectDN->dbId == NULL) {
    847 				break;
    848 			}
    849 			objectDN->numDbIds = t1->numRulesToLDAP;
    850 			t1->ttl++;
    851 		}
    852 		objectDN = objectDN->next;
    853 	    }
    854 	}
    855 
    856 	for (t = t_del; t != NULL; t = t1) {
    857 		t1 = t->next;
    858 		if (t->ttl == 0) {
    859 			p_error = parse_no_object_dn;
    860 			report_error(t->dbId, NULL);
    861 		}
    862 		free_table_mapping(t);
    863 	}
    864 
    865 	if (p_error != no_parse_error)
    866 		return (-1);
    867 
    868 	/* set to default those table mapping values yet set */
    869 	for (t = *table_mapping; t != NULL; t = t->next) {
    870 		if (t->objName == 0) {
    871 			p_error = parse_no_object_dn;
    872 			report_error(t->dbId, NULL);
    873 			return (-1);
    874 		}
    875 		if (!yp2ldap) {
    876 			if (!add_domain(&t->objName,
    877 					proxy_info->default_nis_domain)) {
    878 				report_error(NULL, NULL);
    879 				return (-1);
    880 			}
    881 		}
    882 		if (t->initTtlHi == (time_t)NO_VALUE_SET)
    883 			t->initTtlHi = DEFAULT_TTL_HIGH;
    884 		if (t->initTtlLo == (time_t)NO_VALUE_SET)
    885 			t->initTtlLo = DEFAULT_TTL_LOW;
    886 		if (t->ttl == (time_t)NO_VALUE_SET)
    887 			t->ttl = DEFAULT_TTL;
    888 		objectDN = t->objectDN;
    889 
    890 		/* fixup relative dn's */
    891 		while (objectDN != NULL) {
    892 			if (!yp2ldap) {
    893 				if (!make_full_dn(&objectDN->read.base,
    894 					proxy_info->default_search_base))
    895 						break;
    896 			}
    897 			if (objectDN->write.scope != LDAP_SCOPE_UNKNOWN) {
    898 				if (objectDN->write.base != NULL &&
    899 					!make_full_dn(&objectDN->write.base,
    900 					proxy_info->default_search_base))
    901 						break;
    902 				if (objectDN->write.base == NULL) {
    903 				    objectDN->write.base =
    904 					s_strdup(objectDN->read.base);
    905 				    if (objectDN->write.base == NULL)
    906 					break;
    907 				}
    908 			}
    909 			objectDN = objectDN->next;
    910 		}
    911 
    912 		if (p_error != no_parse_error) {
    913 			report_error(NULL, NULL);
    914 			return (-1);
    915 		}
    916 
    917 		/* Check for ruleToLDAP with no rhs */
    918 		for (i = 0; i < t->numRulesToLDAP; i++) {
    919 		    if (t->ruleToLDAP[i]->rhs.numElements == 0) {
    920 			p_error = parse_unexpected_data_end_rule;
    921 			report_error(t->dbId, NULL);
    922 			return (-1);
    923 		    }
    924 		}
    925 
    926 		/* populate cols field */
    927 		if (!yp2ldap) {
    928 			for (i = 0; i < t->numRulesFromLDAP; i++) {
    929 				lhs = &t->ruleFromLDAP[i]->lhs;
    930 				for (j = 0; j < lhs->numElements; j++) {
    931 					e = &lhs->element[j];
    932 					switch (e->type) {
    933 						case me_item:
    934 						if (!add_column(t,
    935 						e->element.item.name)) {
    936 							report_error(
    937 							NULL, NULL);
    938 							return (-1);
    939 						}
    940 						break;
    941 						case me_match:
    942 						for (k = 0;
    943 						k < e->element.match.numItems;
    944 						k++)
    945 							if (!add_column(t,
    946 					e->element.match.item[k].name)) {
    947 								report_error(
    948 								NULL, NULL);
    949 								return (-1);
    950 							}
    951 						break;
    952 					}
    953 				}
    954 			}
    955 		}
    956 	}
    957 	return (0);
    958 }
    959 
    960 /*
    961  * FUNCTION:	set_default_values
    962  *
    963  *	Sets unconfigured values to their default value
    964  */
    965 
    966 void
    967 set_default_values(__nis_ldap_proxy_info *proxy_info,
    968     __nis_config_t *config_info, __nisdb_table_mapping_t *table_info)
    969 {
    970 	if (proxy_info->bind_timeout.tv_sec == (time_t)NO_VALUE_SET)
    971 		proxy_info->bind_timeout.tv_sec = DEFAULT_BIND_TIMEOUT;
    972 	if (proxy_info->search_timeout.tv_sec == (time_t)NO_VALUE_SET)
    973 		proxy_info->search_timeout.tv_sec =
    974 			(yp2ldap)?DEFAULT_YP_SEARCH_TIMEOUT:
    975 				DEFAULT_SEARCH_TIMEOUT;
    976 	if (proxy_info->modify_timeout.tv_sec == (time_t)NO_VALUE_SET)
    977 		proxy_info->modify_timeout.tv_sec = DEFAULT_MODIFY_TIMEOUT;
    978 	if (proxy_info->add_timeout.tv_sec == (time_t)NO_VALUE_SET)
    979 		proxy_info->add_timeout.tv_sec = DEFAULT_ADD_TIMEOUT;
    980 	if (proxy_info->delete_timeout.tv_sec == (time_t)NO_VALUE_SET)
    981 		proxy_info->delete_timeout.tv_sec = DEFAULT_DELETE_TIMEOUT;
    982 
    983 	if (proxy_info->search_time_limit == (int)NO_VALUE_SET)
    984 		proxy_info->search_time_limit = DEFAULT_SEARCH_TIME_LIMIT;
    985 	if (proxy_info->search_size_limit == (int)NO_VALUE_SET)
    986 		proxy_info->search_size_limit = DEFAULT_SEARCH_SIZE_LIMIT;
    987 
    988 	if (proxy_info->follow_referral == (follow_referral_t)NO_VALUE_SET)
    989 		proxy_info->follow_referral = no_follow;
    990 
    991 	switch (config_info->initialUpdate) {
    992 		case (__nis_initial_update_t)NO_VALUE_SET:
    993 		case (__nis_initial_update_t)INITIAL_UPDATE_NO_ACTION:
    994 		case (__nis_initial_update_t)NO_INITIAL_UPDATE_NO_ACTION:
    995 			config_info->initialUpdate = ini_none;
    996 			break;
    997 		case (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE:
    998 			config_info->initialUpdate = from_ldap;
    999 			break;
   1000 		case (__nis_initial_update_t)TO_NO_INITIAL_UPDATE:
   1001 			config_info->initialUpdate = to_ldap;
   1002 			break;
   1003 	}
   1004 	if (config_info->threadCreationError ==
   1005 	    (__nis_thread_creation_error_t)NO_VALUE_SET)
   1006 		config_info->threadCreationError = pass_error;
   1007 	if (config_info->threadCreationErrorTimeout.attempts == NO_VALUE_SET)
   1008 		config_info->threadCreationErrorTimeout.attempts =
   1009 			DEFAULT_THREAD_ERROR_ATTEMPTS;
   1010 	if (config_info->threadCreationErrorTimeout.timeout ==
   1011 			(time_t)NO_VALUE_SET)
   1012 		config_info->threadCreationErrorTimeout.timeout =
   1013 			DEFAULT_THREAD_ERROR_TIME_OUT;
   1014