confndc.c revision fca5f81ad69098ea8abba130c7f841c951ef91c2
/*
* Copyright (C) 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* $Id: confndc.c,v 1.9 2000/04/12 19:07:12 halley Exp $ */
/*
** options {
** [ default-server server_name; ]
** [ default-key key_name; ]
** };
**
** server server_name {
** key key_name;
** [ host name_or_addr; ]
** };
**
** key key_name {
** algorithm string;
** secret string;
** };
**
*/
#include <config.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <syslog.h>
#include <isc/assertions.h>
#include <dns/rdatatype.h>
#include <dns/rdataclass.h>
/* Type keys for symtab lookup */
#define KEYWORD_SYM_TYPE 0x1
#define CLASS_SYM_TYPE 0x2
#define ACL_SYM_TYPE 0x3
#define CONF_MAX_IDENT 1024
typedef struct {
int errors;
int warnings;
char tokstr[CONF_MAX_IDENT];
char prevtokstr[CONF_MAX_IDENT];
} ndcpcontext;
struct keywordtoken {
char *token;
int yaccval;
};
/*
* DATA
*/
#define L_ALGORITHM 1
#define L_DEFAULT_KEY 3
#define L_DEFAULT_SERVER 4
#define L_END_INCLUDE 5
#define L_END_INPUT 6
#define L_EOS 7
#define L_HOST 8
#define L_IP4ADDR 9
#define L_IP6ADDR 10
#define L_KEY 11
#define L_LBRACE 12
#define L_OPTIONS 13
#define L_QSTRING 14
#define L_QUOTE 15
#define L_RBRACE 16
#define L_SECRET 17
#define L_SERVER 18
#define L_STRING 20
#define L_INTEGER 21
static struct keywordtoken keyword_tokens [] = {
{ "{", L_LBRACE },
{ "}", L_RBRACE },
{ ";", L_EOS },
{ "default-server", L_DEFAULT_SERVER },
{ "default-key", L_DEFAULT_KEY },
{ "key", L_KEY },
{ "host", L_HOST },
{ "algorithm", L_ALGORITHM },
{ "secret", L_SECRET },
{ "options", L_OPTIONS },
{ "server", L_SERVER },
{ NULL, 0 }
};
/* This table contains all the L_* values that are not stored in any other
* keywordtoken table.
*/
static struct keywordtoken misc_tokens[] = {
{ "<end-of-include>", L_END_INCLUDE },
{ "<end-of-input>", L_END_INPUT },
{ "<ip4 address>", L_IP4ADDR },
{ "<ip6 address>", L_IP6ADDR },
{ "<quoted string>", L_QSTRING },
{ "<quote character>", L_QUOTE },
{ "<string>", L_STRING },
};
const char *filename);
const char *fmt, ...);
const char *fmt, ...);
/* *********************************************************************** */
/* PUBLIC DATA STRUCTURE FUNCTIONS */
/* *********************************************************************** */
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
return (ISC_R_SUCCESS);
}
void
}
void
}
void
}
}
void
}
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS)
return (result);
}
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
server = p;
}
return (ISC_R_SUCCESS);
}
}
}
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
dns_c_ndcopts_t *o;
o = *opts;
o->magic = 0;
isc_mem_put(mem, o, sizeof *o);
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
} else
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
} else
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
}
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
} else
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
} else
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOMEMORY);
} else
if (existed)
return (ISC_R_EXISTS);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
return (ISC_R_NOTFOUND);
else
return (ISC_R_SUCCESS);
}
/* *********************************************************************** */
/* PUBLIC PARSING ROUTINE */
/* *********************************************************************** */
{
if (result != ISC_R_SUCCESS)
goto done;
done:
return (result);
}
/* *********************************************************************** */
/* PRIVATE PARSING ROUTINES */
/* *********************************************************************** */
static isc_result_t
if (result != ISC_R_SUCCESS)
return (result);
while (!done) {
case L_END_INPUT:
break;
default:
if (result != ISC_R_SUCCESS) {
break;
}
}
}
return (result);
}
static isc_result_t
{
case L_OPTIONS:
if (result == ISC_R_SUCCESS) {
if (result == ISC_R_EXISTS) {
"redefining `options'");
}
}
break;
case L_SERVER:
if (result == ISC_R_SUCCESS)
break;
case L_KEY:
if (result == ISC_R_NOTFOUND) {
if (result != ISC_R_SUCCESS)
return (result);
}
break;
default:
break;
}
if (result == ISC_R_SUCCESS)
return (result);
}
static isc_result_t
return (ISC_R_FAILURE);
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_FAILURE);
switch (option) {
case L_DEFAULT_SERVER:
if (!looking_at_anystring(pctx))
return (result);
if (result == ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS)
return (result);
break;
case L_DEFAULT_KEY:
if (!looking_at_anystring(pctx))
return (result);
if (result == ISC_R_SUCCESS)
if (result != ISC_R_SUCCESS)
return (result);
break;
default:
break;
}
if (result == ISC_R_EXISTS) {
}
if (result == ISC_R_SUCCESS)
else
return (result);
}
static isc_result_t
char *servername = NULL;
return (ISC_R_FAILURE);
if (!looking_at_anystring(pctx))
return (result);
"zero-length server name is illegal");
return (ISC_R_FAILURE);
}
if (servername == NULL) {
goto done;
}
goto done;
}
goto done;
}
switch (field) {
case L_KEY:
if (!looking_at_anystring(pctx)) {
goto done;
}
"multiple `key' definitions");
}
if (result == ISC_R_SUCCESS)
break;
case L_HOST:
if (!looking_at_anystring(pctx)) {
goto done;
}
"multiple `host' definitions");
}
if (result == ISC_R_SUCCESS)
break;
default:
goto done;
}
if (result != ISC_R_SUCCESS)
goto done;
goto done;
}
}
goto done;
}
"server statement requiresult a key value");
goto done;
}
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
goto done;
done:
if (servername != NULL)
return (result);
}
static isc_result_t
return (ISC_R_FAILURE);
if (!looking_at_anystring(pctx))
return (result);
"zero length key names are illegal.");
return (ISC_R_FAILURE);
}
if (result != ISC_R_SUCCESS)
goto done;
goto done;
}
goto done;
}
switch (field) {
case L_ALGORITHM:
if (!looking_at_anystring(pctx)) {
goto done;
}
"multiple `algorithm' values.");
}
if (result == ISC_R_SUCCESS)
break;
case L_SECRET:
if (!looking_at_anystring(pctx)) {
goto done;
}
"multiple `secret' values.");
}
if (result == ISC_R_SUCCESS)
break;
default:
break;
}
goto done;
}
}
goto done;
}
} else if (*algorithm == '\0') {
}
} else if (*secret == '\0') {
}
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
goto done;
if (result != ISC_R_SUCCESS)
goto done;
done:
return (result);
}
static const char *
int i;
return (keyword_tokens[i].token);
return (misc_tokens[i].token);
return ("<UNKNOWN KEYWORD VALUE>");
}
static isc_boolean_t
return (rval);
}
static isc_boolean_t
keyword2str(token));
}
return (rval);
}
static isc_boolean_t
return (ISC_FALSE);
}
return (ISC_TRUE);
}
static isc_boolean_t
}
static isc_boolean_t
}
static isc_boolean_t
}
/* ************************************************** */
/* ************* PRIVATE STUFF ************ */
/* ************************************************** */
static isc_result_t
{
struct keywordtoken *tok;
if (result != ISC_R_SUCCESS) {
"%s: Error creating lexer",
"dns_c_parse_namedconf");
return (ISC_R_FAILURE);
}
if (result != ISC_R_SUCCESS) {
"%s: Error opening file %s.",
"dns_c_parse_namedconf", filename);
return (result);
}
/*
* 97 == buckey size: higest prime < 100
*/
&pctx->thekeywords);
if (result != ISC_R_SUCCESS) {
"%s: Error creating symtab",
"dns_c_parse_namedconf", filename);
return (result);
}
/*
* Stick all the keywords into the main symbol table.
*/
if (result != ISC_R_SUCCESS) {
"%s: Error installing keyword.",
"dns_c_parse_namedconf");
return (result);
}
}
return (ISC_R_SUCCESS);
}
static void
{
static char message[2048];
int level = ISC_LOG_CRITICAL;
/*
* We can't get a trace of the include files we may be nested in
* (lex.c has the structuresult hidden). So we only report the current
* file.
*/
filename = "(none)";
if (is_warning)
if (print_last_token) {
else
} else {
else
}
}
/*
* For reporting items that are semantic, but not syntactic errors
*/
static void
{
}
static void
}
/*
* Conversion Routines
*/
static isc_boolean_t
return (ISC_FALSE);
return (ISC_TRUE);
}
static isc_boolean_t
const char *p = string;
int dots = 0;
char dot = '.';
while (*p) {
return (ISC_FALSE);
else if (!isdigit(*p & 0xff))
dots++;
p++;
}
if (dots > 3)
return (ISC_FALSE);
else if (dots < 3) {
if (dots == 1) {
} else
return (ISC_FALSE);
} else if (dots == 2) {
} else
return (ISC_FALSE);
}
else
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
}
static isc_result_t
int options = (ISC_LEXOPT_EOF |
switch(result) {
case ISC_R_SUCCESS:
case isc_tokentype_unknown:
if (pctx->debug_lexer)
break;
case isc_tokentype_special:
case isc_tokentype_string: {
} else {
}
if (pctx->debug_lexer)
"special" : "string"),
tokstr);
&keywordtok);
if (result != ISC_R_SUCCESS) {
} else
break;
}
case isc_tokentype_number:
if(pctx->debug_lexer)
break;
case isc_tokentype_qstring:
if (pctx->debug_lexer)
"lexer token: qstring : \"%s\"\n",
break;
case isc_tokentype_eof:
result == ISC_R_SUCCESS);
/*
* The only way to tell that we closed the
* main file and not an included file.
*/
if (pctx->debug_lexer)
} else {
if (pctx->debug_lexer)
"lexer token: EOF (main)\n");
}
break;
case isc_tokentype_initialws:
if (pctx->debug_lexer)
break;
case isc_tokentype_eol:
if (pctx->debug_lexer)
break;
case isc_tokentype_nomore:
if (pctx->debug_lexer)
break;
}
break;
case ISC_R_EOF:
break;
case ISC_R_UNBALANCED:
break;
case ISC_R_NOSPACE:
break;
case ISC_R_UNEXPECTEDEND:
break;
default:
break;
}
return (result);
}
static void
}