/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2015 Gary Mills
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <locale.h>
#include <lber.h>
#include <ldap.h>
#include <syslog.h>
#include <dlfcn.h> /* for dynamic loading only */
#include "ldap_parse.h"
#include "nis_parse_ldap_conf.h"
#include "nis_parse_ldap_err.h"
#include "ldap_util.h"
#include "ldap_util.h"
void append_dot(char **str);
void append_comma(char **str);
char *get_default_ldap_base(const char *domain);
bool_t is_string_ok(char *, int);
/*
* FUNCTION: free_parse_structs
*
* Release the resources in parse results
*
*/
void
{
}
}
/*
* FUNCTION: initialize_parse_structs
*
* Initialize fields to unset values
*
* INPUT: __nis_ldap_proxy_info, __nis_config_t
* and __nisdb_table_mapping_t structures
*/
void
{
}
/*
* FUNCTION: free_mapping_rule
*
* Frees __nis_mapping_rule_t
*
* INPUT: __nis_mapping_rule_t
*/
void
{
int i;
for (i = 0; i < r->numElements; i++)
free_mapping_element(&r->element[i]);
for (i = 0; i < r->numElements; i++)
free_mapping_element(&r->element[i]);
}
}
/*
* FUNCTION: free_mapping_element
*
* Frees __nis_mapping_element_t
*
* INPUT: __nis_mapping_element_t
*/
void
{
int i;
if (e == NULL)
return;
switch (e->type) {
case me_item:
break;
case me_print:
break;
case me_split:
break;
case me_match:
break;
case me_extract:
break;
}
e = NULL;
}
/*
* FUNCTION: free_table_mapping
*
* Frees __nis_table_mapping_t
*
* INPUT: __nis_table_mapping_t
*/
/*
* free_table_mapping does not remove the table mapping from
* its hashed list
*/
void
{
int i;
return;
}
for (i = 0; i < mapping->numColumns; i++) {
}
mapping->numColumns = 0;
}
for (i = 0; i < mapping->numRulesFromLDAP; i++) {
}
mapping->numRulesFromLDAP = 0;
for (i = 0; i < mapping->numRulesToLDAP; i++) {
if (mapping->ruleToLDAP[i])
/*
* Normally mapping->ruleToLDAP[i] should
* always be non-null if
* mapping->numRulesToLDAP is > 0.
* However it is possible to have data
* corruption where numRulesToLDAP gets
* some integer value even though no real
* data is present in mapping->ruleToLDAP.
*/
}
mapping->numRulesToLDAP = 0;
/* Similar logic as in above comment applies. */
free_mapping_element(&mapping->e[i]);
}
}
}
/*
* FUNCTION: free_config_info
*
* Frees __nis_config_info_t
*
* INPUT: __nis_config_info_t
*/
void
{
}
/*
* FUNCTION: free_proxy_info
*
* Frees __nis_ldap_proxy_info
*
* INPUT: __nis_ldap_proxy_info
*/
void
{
}
/*
* FUNCTION: free_object_dn
*
* Frees __nis_object_dn_t
*
* INPUT: __nis_object_dn_t
*/
void
{
int i;
t = obj_dn;
free(t);
}
}
/*
* FUNCTION: free_index
*
* Frees __nis_index_t
*
* INPUT: __nis_index_t
*/
void
{
int i;
for (i = 0; i < index->numIndexes; i++) {
}
index->numIndexes = 0;
}
/*
* FUNCTION: free_mapping_item
*
* Frees __nis_mapping_item_t
*
* INPUT: __nis_mapping_item_t
*/
void
{
return;
}
}
}
}
/*
* FUNCTION: free_mapping_format
*
* Frees __nis_mapping_format_t
*
* INPUT: __nis_mapping_format_t
*/
void
{
__nis_mapping_format_t *f = fmt;
case mmt_item:
break;
case mmt_string:
break;
case mmt_single:
break;
case mmt_limit:
break;
case mmt_any:
break;
case mmt_berstring:
case mmt_berstring_null:
break;
case mmt_begin:
break;
case mmt_end:
break;
}
fmt++;
}
free(f);
}
/*
* FUNCTION: free_mapping_sub_element
*
* Frees __nis_mapping_sub_element_t
*
* INPUT: __nis_mapping_sub_element_t
*/
void
{
int i;
case me_item:
break;
case me_print:
break;
case me_split:
break;
case me_extract:
break;
}
}
/*
* FUNCTION: read_line
*
* Gets next line in buffer - using '\' at end of line
* to indicate continuation. Lines beginning with # are
* ignored. start_line_num and start_line_num are
* maintained to track the line number currently being
* parsed.
*
* RETURN VALUE: The number of characters read. 0 for
* eof, -1 for error
*
* INPUT: file descriptor, buffer, and buffer size
*/
int
{
int linelen;
int rc;
char c;
for (; p_error == no_parse_error; ) {
linelen = 0;
if (1 == rc) {
if (c == '\n' || c == '\r') {
if (c == '\n') {
if (prev_cr) {
continue;
} else {
if (linelen == 0)
else {
if (
linelen)) {
(void) memset(
buffer, 0,
linelen);
linelen = 0;
cur_line_num++;
TRUE;
continue;
}
}
cur_line_num++;
}
} else {
if (linelen == 0)
cur_line_num++;
}
if (skip_line) {
if (linelen == 0)
} else if (linelen > 0 &&
== ESCAPE_CHAR) {
--linelen;
} else if (linelen > 0) {
return (linelen);
}
begin_line = TRUE;
} else {
if (begin_line)
skip_line = c == POUND_SIGN;
begin_line = FALSE;
if (!skip_line)
}
} else {
if (linelen > 0 &&
/* continuation on last line */
return (-1);
} else {
return (linelen);
}
}
}
}
return (-1);
}
/*
* FUNCTION: finish_parse
*
* Adds any elements not configured, fully qualifies
* names
*
* RETURN VALUE: 0 on success, -1 on failure
*/
int
{
int i;
int j;
int k;
char *s;
int errnum;
/* set to default those values yet set */
if (proxy_info->auth_method ==
return (-1);
}
return (-1);
}
return (-1);
}
}
if ((errnum = ldapssl_client_init(
return (-1);
}
}
/* convert a relative dn to a fullly qualified dn */
if (p_error != no_parse_error) {
return (-1);
}
/*
* Create a list of potential delete mappings
* those have NULL objectDNs, but badly also rules
* that are missing object dn's will be included.
* We will use the ttl field to determine if the
* delete rule is actually used
*/
*table_mapping = t1;
else
t_del = t;
t->ttl = 0;
} else
t2 = t;
}
return (-1);
t1->numRulesToLDAP == 0 ||
t1->numRulesFromLDAP != 0) {
return (-1);
}
t1->numRulesToLDAP);
break;
}
}
}
}
if (t->ttl == 0) {
}
}
if (p_error != no_parse_error)
return (-1);
/* set to default those table mapping values yet set */
if (t->objName == 0) {
return (-1);
}
if (!yp2ldap) {
if (!add_domain(&t->objName,
return (-1);
}
}
t->initTtlHi = DEFAULT_TTL_HIGH;
t->initTtlLo = DEFAULT_TTL_LOW;
t->ttl = DEFAULT_TTL;
/* fixup relative dn's */
if (!yp2ldap) {
break;
}
break;
break;
}
}
}
if (p_error != no_parse_error) {
return (-1);
}
/* Check for ruleToLDAP with no rhs */
for (i = 0; i < t->numRulesToLDAP; i++) {
return (-1);
}
}
/* populate cols field */
if (!yp2ldap) {
for (i = 0; i < t->numRulesFromLDAP; i++) {
for (j = 0; j < lhs->numElements; j++) {
switch (e->type) {
case me_item:
if (!add_column(t,
return (-1);
}
break;
case me_match:
for (k = 0;
k++)
if (!add_column(t,
return (-1);
}
break;
}
}
}
}
}
return (0);
}
/*
* FUNCTION: set_default_values
*
* Sets unconfigured values to their default value
*/
void
{
switch (config_info->initialUpdate) {
break;
break;
break;
}
if (config_info->threadCreationError ==
if (config_info->dumpError ==
if (config_info->resyncService ==
if (config_info->updateBatching ==
if (table_info->retrieveError ==
if (table_info->storeError ==
if (table_info->refreshError ==
if (table_info->matchFetch ==
}
{
break;
return (t);
}
void
{
char *s = *str;
if (s != NULL) {
s[len] = PERIOD_CHAR;
*str = s;
}
}
}
void
{
char *s = *str;
if (s != NULL) {
s[len] = COMMA_CHAR;
*str = s;
}
}
}
/*
* FUNCTION: make_full_dn
*
* Appends the base dn if a relative ldap dn
* (invoked only for LDAP write cycle)
*
* RETURN VALUE: FALSE if error
* TRUE if __nis_index_t returned
*
* INPUT: the relative dn and ldap base
*/
{
int len;
int len1;
} else {
}
}
}
/*
* FUNCTION: make_fqdn
*
* Appends the base dn if a relative ldap dn
* (invoked only for LDAP read cycle)
*
* RETURN VALUE: FALSE if error
* TRUE if success
*
* INPUT: the relative dn and ldap base
*/
{
int len;
int len1;
return (FALSE);
} else {
else
return (FALSE);
}
}
}
return (TRUE);
}
/*
* FUNCTION: get_default_ldap_base
*
* Gets the default LDAP search base from the
* nis+ default domain
*
* RETURN VALUE: NULL if error
* the default base
*
* INPUT: the nis domain
*/
char *
{
int i;
char *base;
for (i = 0; i < len - 1; i++)
if (domain[i] == PERIOD_CHAR)
count += 4;
} else {
count = 3;
for (i = 0; i < len - 1; i++) {
if (domain[i] == PERIOD_CHAR) {
count += 4;
} else {
}
}
}
return (base);
}
/*
* FUNCTION: add_domain
*
* Appends the base domain if a relative object name
*
* RETURN VALUE: FALSE if error
* TRUE if OK
*
* INPUT: the relative object name and base domain
* name
*/
{
int len;
int len1;
char *obj_name;
return (FALSE);
}
0 : 1;
if (trailing_dot != 0) {
}
}
}
}
{
int i;
int j;
return (FALSE);
return (FALSE);
}
for (i = 0; i < in->numIndexes; i++) {
break;
break;
}
if (i < in->numIndexes) {
for (j = 0; j <= i; j++) {
}
} else {
}
return (i == in->numIndexes);
}
{
if (!ret)
return (ret);
return (FALSE);
} else
return (FALSE);
} else
return (FALSE);
} else
return (FALSE);
} else
}
return (FALSE);
} else
(sizeof (__nis_mapping_item_t));
return (FALSE);
else {
(void) memset
if (!dup_mapping_item
}
} else
return (p_error == no_parse_error);
}
{
int i;
i = 0;
i++;
i + 1, sizeof (__nis_mapping_format_t));
for (i = 0; !got_end; i++) {
case mmt_item:
break;
case mmt_string:
break;
case mmt_single:
break;
break;
break;
case mmt_limit:
break;
case mmt_any:
break;
case mmt_berstring:
break;
case mmt_begin:
break;
case mmt_end:
break;
default:
}
if (p_error != no_parse_error)
break;
}
if (p_error != no_parse_error) {
}
}
return (out);
}
{
int i;
case me_item:
break;
case me_print:
break;
sizeof (__nis_mapping_item_t));
break;
if (!dup_mapping_item(
break;
break;
break;
case me_split:
break;
case me_extract:
break;
break;
default:
}
return (ret);
}
{
int i;
return (ret);
case me_item:
break;
case me_print:
break;
sizeof (__nis_mapping_sub_element_t));
break;
if (!dup_mapping_sub_element(
break;
break;
break;
case me_split:
break;
case me_match:
break;
sizeof (__nis_mapping_item_t));
break;
if (!dup_mapping_item(
break;
break;
break;
case me_extract:
break;
break;
default:
}
return (ret);
}
{
int i;
out = (__nis_mapping_rule_t *)
return (NULL);
}
for (i = 0; i < r_in->numElements; i++) {
break;
}
if (i < r_in->numElements) {
return (NULL);
}
return (NULL);
}
for (i = 0; i < r_in->numElements; i++) {
break;
}
if (i < r_in->numElements) {
return (NULL);
}
}
return (out);
}
{
int i, j;
__nis_mapping_rule_t **r;
sizeof (__nis_mapping_rule_t *));
if (r != NULL) {
for (i = 0; i < n_rules; i++) {
r[i] = dup_mapping_rule(rules[i]);
if (r[i] == NULL) {
for (j = 0; j < i; j++)
free_mapping_rule(r[j]);
free(r);
r = NULL;
break;
}
}
}
return (r);
}
/*
* FUNCTION: add_column
*
* Adds a column name to the column list in __nis_table_mapping_t
*
* RETURN VALUE: FALSE if error
* TRUE if __nis_index_t returned
*
* INPUT: the __nis_table_mapping_t and column name
*/
{
int i;
if (!yp2ldap) {
for (i = 0; i < t->numColumns; i++) {
return (TRUE);
}
}
sizeof (char *));
return (FALSE);
return (FALSE);
t->numColumns++;
return (TRUE);
}
/*
* FUNCTION: add_element
*
* Adds a __nis_mapping_element_t to __nis_mapping_rlhs_t
*
* RETURN VALUE: FALSE if error
* TRUE if __nis_index_t returned
*
* INPUT: the __nis_mapping_element_t and
* __nis_mapping_rlhs_t
*/
{
int i;
int n = m->numElements;
(n + 1) * sizeof (__nis_mapping_element_t));
for (i = 0; i < n; i++)
m->numElements = 0;
} else {
e1[m->numElements++] = *e;
free(e);
}
}
/*
* FUNCTION: get_next_object_dn_token
*
* Get the next token in parsing object_dn
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* token
*
* INPUT: the attribute value
*/
const char *
const char **begin_ret,
const char **end_ret,
{
const char *s = *begin_ret;
const char *begin;
const char *s1;
while (s < end && is_whitespace(*s))
s++;
if (s >= end) {
/* EMPTY */
} else if (*s == SEMI_COLON_CHAR) {
t = dn_semi_token;
s++;
} else if (*s == QUESTION_MARK) {
t = dn_ques_token;
s++;
} else if (*s == COLON_CHAR) {
t = dn_colon_token;
s++;
} else if (*s == OPEN_PAREN_CHAR) {
begin = s;
if (s != NULL) {
t = dn_text_token;
}
} else {
begin = s;
while (s < end) {
if (*s == ESCAPE_CHAR) {
if (s + 2 > end) {
s = NULL;
break;
}
s++;
} else if (*s == DOUBLE_QUOTE_CHAR) {
} else if (in_quotes)
;
else if (*s == SEMI_COLON_CHAR ||
*s == QUESTION_MARK ||
*s == COLON_CHAR)
break;
s++;
}
if (s != NULL) {
s1 = s - 1;
while (is_whitespace(*s1))
s1--;
s1++;
t = dn_base_token;
t = dn_one_token;
t = dn_sub_token;
else
t = dn_text_token;
}
}
*token = t;
return (s);
}
/*
* FUNCTION: get_next_token
*
* Get the next token in parsing mapping attribute
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* token
*
* INPUT: the attribute value
*/
const char *
{
const char *s = *begin_token;
const char *s_begin;
while (s < end_s && is_whitespace(*s))
s++;
if (s == end_s) {
*t = no_token;
return (s);
}
s_begin = s;
if (*s == OPEN_PAREN_CHAR) {
*begin_token = s;
s++;
*end_token = s;
while (s < end_s && is_whitespace(*s))
s++;
*t = open_paren_token;
} else if (*s == DOUBLE_QUOTE_CHAR) {
s++;
while (s < end_s) {
if (*s == ESCAPE_CHAR)
s += 2;
else if (*s == DOUBLE_QUOTE_CHAR)
break;
else
s++;
}
if (s >= end_s) {
return (NULL);
}
*t = quoted_string_token;
*end_token = s++;
} else if (*s == EQUAL_CHAR || *s == COMMA_CHAR ||
*s == CLOSE_PAREN_CHAR || *s == COLON_CHAR) {
if (*s == EQUAL_CHAR)
*t = equal_token;
else if (*s == COMMA_CHAR)
*t = comma_token;
else if (*s == CLOSE_PAREN_CHAR)
*t = close_paren_token;
else
*t = colon_token;
*begin_token = s;
*end_token = ++s;
} else {
s_begin = s;
while (s < end_s && !is_whitespace(*s)) {
if (*s == ESCAPE_CHAR)
s += 2;
else if (*s == EQUAL_CHAR || *s == CLOSE_PAREN_CHAR ||
*s == OPEN_PAREN_CHAR || *s == COMMA_CHAR ||
*s == COLON_CHAR || *s == OPEN_BRACKET ||
*s == CLOSE_BRACKET)
break;
else
s++;
}
if (s > end_s) {
return (NULL);
}
*t = string_token;
*end_token = s;
*begin_token = s_begin;
}
if (s) {
while (s < end_s && is_whitespace(*s))
s++;
}
return (s);
}
/*
* FUNCTION: skip_token
*
* Skip over the specified token - An error is set if
* next token does not match expected token
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* token
*
* INPUT: the attribute value
*/
const char *
{
char c = 0;
if (s == NULL)
return (s);
while (s < end_s && is_whitespace(*s))
s++;
c = (s == end_s) ? 0 : *s;
switch (t) {
case equal_token:
match = c == EQUAL_CHAR;
if (!match)
break;
case comma_token:
match = c == COMMA_CHAR;
if (!match)
break;
case close_paren_token:
match = c == CLOSE_PAREN_CHAR;
if (!match)
break;
default:
break;
}
if (match) {
s++;
while (s < end_s && is_whitespace(*s))
s++;
} else {
s = NULL;
}
return (s);
}
/*
* FUNCTION: get_next_extract_format_item
*
* Get the next format token from the string. Note that
* get_next_extract_format_item may change the input string.
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* token
*
* INPUT: the format string
*/
const char *
const char *begin_fmt,
const char *end_fmt,
{
const char *s = begin_fmt;
int numRange;
for (; p_error == no_parse_error; ) {
if (s >= s_end)
break;
if (*s == PERCENT_SIGN) {
s++;
/*
* If the format is %s, it is interpreted
* as a string.
*/
if (s >= s_end) {
break;
}
switch (*s) {
case 's':
break;
case 'n': /* null */
case 'x': /* skip the next element */
/* FALLTHRU */
case 'b': /* boolean */
case 'e': /* enumerated */
case 'i': /* int */
case 'o': /* octet string */
case 'B': /* bit string */
break;
case 'a': /* octet string */
if (yp2ldap) {
s_strndup(s, 1);
break;
} /* else FALLTHRU */
case '{': /* begin sequence */
case '[': /* begin set */
case '}': /* end sequence */
case ']': /* end set */
case 'l': /* length of next item */
case 'O': /* octet string */
case 't': /* tag of next item */
case 'T': /* skip tag of next item */
case 'v': /* seq of strings */
case 'V': /* seq of strings + lengths */
default:
break;
}
s++;
} else if (*s == ASTERIX_CHAR) {
s++;
while (s < s_end && *s == ASTERIX_CHAR)
s++;
} else if (*s == OPEN_BRACKET) {
numRange = 0;
s++;
for (; s < s_end; s++) {
if (escape) {
} else if (*s == DASH_CHAR) {
break;
}
continue;
} else if (*s == CLOSE_BRACKET) {
if (in_range) {
}
break;
} else if (*s == ESCAPE_CHAR) {
continue;
}
if (in_range) {
} else {
break;
numRange++;
}
}
if (p_error != no_parse_error) {
break;
} else if (!done) {
break;
}
s++;
} else {
/* go to next key symbol - copy escaped key symbols */
while (s < s_end) {
if (escape)
else {
switch (*s) {
case OPEN_BRACKET:
case ASTERIX_CHAR:
case PERCENT_SIGN:
break;
case ESCAPE_CHAR:
break;
default:
break;
}
}
if (done)
break;
s++;
}
if (escape) {
break;
}
break;
}
if (p_error == no_parse_error)
return (s);
}
return (NULL);
}
/*
* FUNCTION: get_next_print_format_item
*
* Get the next format token from the string
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* token
*
* INPUT: the format string
*/
const char *
const char *begin_fmt,
const char *end_fmt,
{
const char *s = begin_fmt;
for (; p_error == no_parse_error; ) {
if (s >= s_end) {
break;
}
if (*s == PERCENT_SIGN) {
s++;
if (s >= s_end) {
break;
}
/*
* If the format is %s, it is interpretted
* as a string.
*/
switch (*s) {
case 's':
break;
case 'n': /* null */
case 'x': /* skip the next element */
/* FALLTHRU */
case 'b': /* boolean */
case 'e': /* enumerated */
case 'i': /* int */
case 'o': /* octet string */
case 'B': /* bit string */
break;
case '{': /* begin sequence */
case '[': /* begin set */
case '}': /* end sequence */
case ']': /* end set */
case 'a': /* octet string */
case 'l': /* length of next item */
case 'O': /* octet string */
case 't': /* tag of next item */
case 'T': /* skip tag of next item */
case 'v': /* seq of strings */
case 'V': /* seq of strings + lengths */
default:
break;
}
s++;
} else {
while (s < s_end) {
if (*s == PERCENT_SIGN)
break;
else if (*s == ESCAPE_CHAR)
s++;
s++;
}
if (s > s_end) {
break;
}
break;
}
if (p_error == no_parse_error)
return (s);
}
return (NULL);
}
/*
* FUNCTION: get_ldap_filter
*
* Gets an LDAP filter - see RFC 2254. Note that this does not
* determine if the ldap filter is valid. This only determines
* that the parentheses are balanced.
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* filter
*
* INPUT: the begin and end of string
*
* OUTPUT: the begin and end of LDAP filter
*
*/
const char *
{
const char *s = *begin;
const char *s_begin;
int nParen;
for (; p_error == no_parse_error; ) {
while (s < s_end && is_whitespace(*s))
s++;
if (s == s_end) {
s = NULL;
break;
}
s_begin = s;
if (*s == OPEN_PAREN_CHAR) {
nParen = 1;
s++;
if (*s == ESCAPE_CHAR)
s++;
else if (*s == OPEN_PAREN_CHAR)
nParen++;
else if (*s == CLOSE_PAREN_CHAR)
nParen--;
s++;
}
if (nParen == 0) {
*end = s;
while (s < s_end && is_whitespace(*s))
s++;
} else
s = NULL;
} else
s = NULL;
if (p_error == no_parse_error)
break;
}
if (s == NULL)
return (s);
}
/*
* FUNCTION: get_ava_list
*
* Gets an attribute value assertion list
*
* RETURN VALUE: NULL if error
* position of beginning next token after
* after attribute assertion
*
* INPUT: the begin and end of string
* Indicator if ava list is part of a nisplus
* item
*
* OUTPUT: the begin and end of LDAP filter
*
*/
const char *
{
const char *s = *begin;
const char *s_begin;
for (; p_error == no_parse_error; ) {
while (s < s_end && is_whitespace(*s))
s++;
if (s == s_end) {
s = NULL;
break;
}
s_begin = s;
while (s < s_end) {
if (*s == ESCAPE_CHAR) {
s++;
} else if (*s == DOUBLE_QUOTE_CHAR) {
} else if (in_quote)
;
else if (*s == EQUAL_CHAR) {
break;
break;
}
} else if (*s == COMMA_CHAR) {
break;
} else if (is_whitespace(*s))
;
else
s++;
}
s = NULL;
else {
*end = s;
while (s < s_end && is_whitespace(*s))
s++;
}
if (p_error == no_parse_error)
break;
}
if (s == NULL)
return (s);
}
/* Utility functions */
{
if (!valid)
return (valid);
}
{
const char *s_begin;
const char *s_end;
s_begin = s;
if (*s == OPEN_PAREN_CHAR) {
} else {
/* Assume an attribute value list */
}
return (p_error == no_parse_error);
}
char *
s_strndup(const char *s, int n)
{
char *d = (char *)malloc(n + 1);
if (d != NULL) {
(void) memcpy(d, s, n);
d[n] = '\0';
} else {
}
return (d);
}
char *
s_strndup_esc(const char *s, int n)
{
char *d = (char *)malloc(n + 1);
int i;
int j;
if (d != NULL) {
for (i = 0, j = 0; i < n; i++) {
if (s[i] == ESCAPE_CHAR)
i++;
d[j++] = s[i];
}
d[j] = '\0';
} else {
}
return (d);
}
void *
{
if (d == NULL) {
}
return (d);
}
void *
{
if (d == NULL)
return (d);
}
void *
{
if (s == NULL)
return (s);
}
char *
s_strdup(const char *s)
{
}
is_whitespace(int c)
{
return (c == ' ' || c == '\t');
}
{
int i;
return (FALSE);
for (i = 0; i < buflen; i++) {
if (!is_whitespace(buffer[i])) {
if (buffer[i] == POUND_SIGN)
return (TRUE);
else
return (FALSE);
}
}
return (TRUE);
}
/*
* Returns true if the first string is contained at the beginning of the
* second string. Otherwise returns false.
*/
{
}
/*
* Returns the next character position in the second string, if the first
* string is contained at the beginning of the second string. Otherwise
* returns NULL.
*/
const char *
{
else
return (NULL);
}
/*
* The second string is not necessarily null terminated.
* same_string returns true if the second string matches the first.
* Otherwise returns false.
*/
{
}
void
{
int pos = 0;
if (command_line_source != NULL) {
} else if (file_source != NULL) {
} else if (ldap_source != NULL) {
}
if (start_line_num != 0) {
}
"for attribute %s: ", attr);
}
} else {
}
}
void
const char *str1,
const char *str2)
{
} else {
}
}
void
conn_error e,
const char *str1,
const char *str2)
{
"%s\n", conn_error_msg[e]);
} else {
conn_error_msg[e],
}
}
void
const char *str,
const char *arg)
{
} else
}