nscd_nswparse.c revision cb5caa98562cf06753163f558cbcfe30b8f4673a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#define __NSS_PRIVATE_INTERFACE
#include "nsswitch_priv.h"
/*
* The _nsw_getoneconfig_v1() in this file parses the switch policy
* configuration for a switch database, e.g.,
*
* hosts: nis [NOTFOUND=return] files
* or
* printers: user files nis
*/
/*
* Local routines
*/
static char *skip(char **, char);
static char *labelskip(char *);
static char *spaceskip(char *);
static void freeconf_v1(struct __nsw_switchconfig_v1 *);
static int alldigits(char *);
/*
*
* With the "lookup control" feature, the default criteria for NIS, NIS+,
* and any new services (e.g. ldap) will be:
* [SUCCESS=return NOTFOUND=continue UNAVAIL=continue TRYAGAIN=forever]
*
* For backward compat, NIS via NIS server in DNS forwarding mode will be:
* [SUCCESS=return NOTFOUND=continue UNAVAIL=continue TRYAGAIN=continue]
*
* And also for backward compat, the default criteria for DNS will be:
* [SUCCESS=return NOTFOUND=continue UNAVAIL=continue TRYAGAIN=continue]
*/
/*
* The BIND resolver normally will retry several times on server non-response.
* But now with the "lookup control" feature, we don't want the resolver doing
* many retries, rather we want it to return control (reasonably) quickly back
* to the switch engine. However, when TRYAGAIN=N or TRYAGAIN=forever is
* not explicitly set by the admin in the conf file, we want the old "resolver
* retry a few times" rather than no retries at all.
*/
static int dns_tryagain_retry = 3;
/*
* For backward compat (pre "lookup control"), the dns default behavior is
* soft lookup.
*/
static void
{
}
}
static void
{
if (cfp) {
}
}
}
}
/* give the next non-alpha character */
static char *
{
char *p = cur;
while (islabel(*p))
++p;
return (p);
}
/* give the next non-space character */
static char *
{
char *p = cur;
while (*p == ' ' || *p == '\t')
++p;
return (p);
}
/*
* terminate the *cur pointed string by null only if it is
* followed by "key" surrounded by zero or more spaces and
* return value is the same as the original *cur pointer and
* *cur pointer is advanced to the first non {space, key} char
* followed by the key. Otherwise, return NULL and keep
* *cur unchanged.
*/
static char *
{
char *p, *tmp;
char *q = *cur;
p = tmp;
if (found) {
*p++ = '\0'; /* overwrite the key */
p = spaceskip(p);
} else {
while (*p == ' ' || *p == '\t') {
if (tmpfound) {
/* null terminate the return token */
*tmp = '\0';
p++; /* skip the key */
}
}
}
if (!found)
return (NULL); /* *cur unchanged */
*cur = p;
return (q);
}
/* Return 1 if the string contains all digits, else return 0. */
static int
alldigits(char *s)
{
for (; *s; s++)
if (!isdigit(*s))
return (0);
return (1);
}
struct __nsw_switchconfig_v1 *
/* linep Nota Bene: not const char * */
/* errp Meanings are abused a bit */
{
struct __nsw_switchconfig_v1 *cfp;
int end_crit;
char *p, *tokenp;
== NULL) {
return (NULL);
}
/* linep points to a naming service name */
for (;;) {
int i;
/* white space following the last service */
return (cfp);
}
== NULL) {
return (NULL);
}
for (i = 0; i < __NSW_STD_ERRS_V1; i++)
if (i == __NSW_SUCCESS)
else if (i == __NSW_TRYAGAIN)
else
/* get criteria for the naming service */
/* premature end, illegal char following [ */
goto barf_line;
cfp->num_lookups++;
end_crit = 0;
/* linep points to a switch_err */
for (;;) {
int ntimes = 0; /* try again max N times */
int dns_continue = 0;
goto barf_line;
}
/* premature end, ill char following = */
goto barf_line;
/* linep points to the string following '=' */
if (*p == ']')
end_crit = 1;
else if (*p != ' ' && *p != '\t')
goto barf_line;
*p++ = '\0'; /* null terminate linep */
p = spaceskip(p);
if (!end_crit) {
if (*p == ']') {
end_crit = 1;
*p++ = '\0';
} else if (*p == '\0' || *p == '\n') {
return (cfp);
} else if (!islabel(*p))
/* p better be the next switch_err */
goto barf_line;
}
act = __NSW_RETURN;
else if (strcasecmp(linep,
__NSW_STR_CONTINUE) == 0) {
"dns") == 0 &&
== 0) {
/*
* Add one more condition
* so it retries only if it's
* "dns [TRYAGAIN=continue]"
*/
dns_continue = 1;
} else
} else if (strcasecmp(linep,
__NSW_STR_FOREVER) == 0)
ntimes = 0;
}
else
goto barf_line;
if (__NSW_SUCCESS_ACTION(act) &&
__NSW_STR_SUCCESS) == 0) {
} else if (__NSW_NOTFOUND_ACTION(act) &&
__NSW_STR_NOTFOUND) == 0) {
} else if (__NSW_UNAVAIL_ACTION(act) &&
__NSW_STR_UNAVAIL) == 0) {
} else if (__NSW_TRYAGAIN_ACTION(act) &&
__NSW_STR_TRYAGAIN) == 0) {
"nis") == 0)
= act;
if (act == __NSW_TRYAGAIN_NTIMES)
lkp->max_retries =
} else {
/*EMPTY*/
/*
* convert string tokenp to integer
* and put in long_errs
*/
}
if (end_crit) {
return (cfp);
break; /* process next naming service */
}
linep = p;
} /* end of while loop for a name service's criteria */
} else {
/*
* no criteria for this naming service.
* linep points to name service, but not null
* terminated.
*/
if (*p == '\0' || *p == '\n') {
*p = '\0';
cfp->num_lookups++;
return (cfp);
}
if (*p != ' ' && *p != '\t')
goto barf_line;
*p++ = '\0';
cfp->num_lookups++;
}
} /* end of while(1) loop for a name service */
return (NULL);
}
int
struct __nsw_switchconfig_v1 *conf)
{
return (0);
}