Esempio n. 1
0
/*****************************************************************
**
**	lg_mesg (level, fmt, ...)
**
**	Write a given message to the error log file and counts
**	all messages written with an level greater than LOG_ERR.
**
**	All messages will be on one line in the logfile, so it's
**	not necessary to add an '\n' to the message.
**
**	To call this function before an elog_open() is called is
**	useless!
**
*****************************************************************/
void	lg_mesg (int priority, char *fmt, ...)
{
	va_list ap;
	struct	timeval	tv;
	struct	tm	*t;
	char	format[256];

	assert (fmt != NULL);
	assert (priority >= LG_DEBUG && priority <= LG_FATAL);

	format[0] ='\0';

	dbg_val3 ("syslog = %d prio = %d >= sysmin = %d\n", lg_syslogging, priority, lg_minsyslevel);
	if ( lg_syslogging && priority >= lg_minsyslevel )
	{
#if defined (LOG_WITH_LEVEL) && LOG_WITH_LEVEL
		snprintf (format, sizeof (format), "%s: %s", lg_lvl2str(priority), fmt);
		fmt = format;
#endif
		va_start(ap, fmt);
		vsyslog (lg_lvl2syslog (priority), fmt, ap);
		va_end(ap);
	}

	dbg_val3 ("filelg = %d prio = %d >= filmin = %d\n", lg_fp!=NULL, priority, lg_minfilelevel);
	if ( lg_fp && priority >= lg_minfilelevel )
	{
#if defined (LOG_WITH_TIMESTAMP) && LOG_WITH_TIMESTAMP
		gettimeofday (&tv, NULL);
		t = localtime ((time_t *) &tv.tv_sec);
		fprintf (lg_fp, "%04d-%02d-%02d ",
			t->tm_year+1900, t->tm_mon+1, t->tm_mday);
		fprintf (lg_fp, "%02d:%02d:%02d.%03ld: ",
			t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
#endif
#if defined (LOG_WITH_PROGNAME) && LOG_WITH_PROGNAME
		if ( lg_progname )
			fprintf (lg_fp, "%s: ", lg_progname);
#endif
#if defined (LOG_WITH_LEVEL) && LOG_WITH_LEVEL
		if ( fmt != format )	/* level is not in fmt string */
			fprintf (lg_fp, "%s: ", lg_lvl2str(priority));
#endif
		va_start(ap, fmt);
		vfprintf (lg_fp, fmt, ap);
		va_end(ap);
		fprintf (lg_fp, "\n");
	}

	if ( priority >= LG_ERROR )
		lg_errcnt++;
}
Esempio n. 2
0
/*****************************************************************
**	reload a zone via "rndc"
*****************************************************************/
int	reload_zone (const char *domain, const zconf_t *z)
{
	char	cmdline[254+1];
	char	str[254+1];
	FILE	*fp;

	assert (z != NULL);
	dbg_val3 ("reload_zone %d :%s: :%s:\n", z->verbosity, domain, z->view);
	if ( z->view )
		snprintf (str, sizeof (str), "\"%s\" in view \"%s\"", domain, z->view);
	else
		snprintf (str, sizeof (str), "\"%s\"", domain);

	lg_mesg (LG_NOTICE, "%s: reload triggered", str);
	verbmesg (1, z, "\tReload zone %s\n", str);

	if ( z->view )
		snprintf (cmdline, sizeof (cmdline), "%s reload %s IN %s", RELOADCMD, domain, z->view);
	else
		snprintf (cmdline, sizeof (cmdline), "%s reload %s", RELOADCMD, domain);

	*str = '\0';
	if ( z->noexec == 0 )
	{
		verbmesg (2, z, "\t  Run cmd \"%s\"\n", cmdline);
		if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL )
			return -1;
		pclose (fp);
		verbmesg (2, z, "\t  rndc reload return: \"%s\"\n", str_chop (str, '\n'));
	}

	return 0;
}
Esempio n. 3
0
/*****************************************************************
**
**	parse_keyconf (const char *filename, dir, dirsize, int (*func) ())
**
**	Very dumb named.conf parser.
**	- For every key definition "func (keyname, algo, secret)" will be called
**
*****************************************************************/
static	int	parse_keyconf (const char *filename, char *dir, size_t dirsize, tsigkey_t *k, const char *lookup)
{
    FILE	*fp;
    int	ret;
    int	tok;
    char	path[511+1];
    char	strval[4095+1];
    char	key[255+1];
    char	alg[31+1];
    char	secret[255+1];

    dbg_val ("parse_keyconf: parsing file \"%s\" \n", filename);

    assert (filename != NULL);
    assert (dir != NULL && dirsize != 0);
    assert ( k != NULL);

    if ( (fp = fopen (filename, "r")) == NULL )
        return -1;

    ret = 0;
    while ( (tok = gettok (fp, strval, sizeof strval)) != EOF )
    {
        if ( tok > 0 && tok < 256 )
        {
            fprintf (stderr, "parse_keyconf: token found with value %-10d: %c\n", tok, tok);
        }
        else if ( tok == TOK_DIR )
        {
            if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
            {
                dbg_val2 ("parse_namedconf: directory found \"%s\" (dir is %s)\n", strval, dir);
                if ( *strval != '/' &&  *dir )
                    snprintf (path, sizeof (path), "%s/%s", dir, strval);
                else
                    snprintf (path, sizeof (path), "%s", strval);

                snprintf (dir, dirsize, "%s", path);
                dbg_val ("parse_namedconf: new dir \"%s\" \n", dir);
            }
        }
        else if ( tok == TOK_INCLUDE )
        {
            if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
            {
                if ( *strval != '/' && *dir )
                    snprintf (path, sizeof (path), "%s/%s", dir, strval);
                else
                    snprintf (path, sizeof (path), "%s", strval);
                if ( (ret = parse_keyconf (path, dir, dirsize, k, lookup)) != 0 )
                    return ret;
            }
            else
            {
                fprintf (stderr, "parse_keyconf: need a filename after \"include\"!\n");
            }
        }
        else if ( tok == TOK_KEY )
        {
            int	nrtok;

            dbg_val0 ("parse_keyconf: new key found \n");
            if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
                continue;
            snprintf (key, sizeof key, "%s", strval);	/* store the name of the key */
            dbg_val ("parse_keyconf: keyname \"%s\" \n", key);

            nrtok = 0;
            while ( nrtok < 2 && (tok = gettok (fp, strval, sizeof (strval))) )
            {
                if ( tok == TOK_ALG )
                {
                    switch ( gettok (fp, strval, sizeof (strval)) )
                    {
                    case TOK_HMAC_MD5:
                    case TOK_HMAC_SHA1:
                    case TOK_HMAC_SHA224:
                    case TOK_HMAC_SHA256:
                    case TOK_HMAC_SHA384:
                    case TOK_HMAC_SHA512:
                        snprintf (alg, sizeof alg, "%s", strval);	/* this is the algorithm */
                        break;
                    default:
                        *alg = '\0';
                        continue;
                    }
                }
                else if ( tok == TOK_SECRET )
                {
                    if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
                        break;
                    snprintf (secret, sizeof secret, "%s", strval);	/* this is the secret */
                }
                nrtok++;
            }

            dbg_val5 ("dir %s key %s alg %s secret %s lookup \"%s\"\n",
                      dir, key, alg, secret, lookup ? lookup: "NULL");
            if ( lookup == NULL || lookup[0] == '\0' || strcmp (key, lookup) == 0 )
            {
                snprintf (k->name, sizeof (k->name), "%s", key);
                snprintf (k->algo, sizeof (k->algo), "%s", alg);
                snprintf (k->secret, sizeof (k->secret), "%s", secret);
                ret = 1;
                break;
            }
        }
        else
            dbg_val3 ("%-10s(%d): %s\n", tok2str(tok), tok, strval);
    }
    fclose (fp);

    dbg_val2 ("parse_keyconf: leaving file \"%s\" ret = %d \n", filename, ret);

    return ret;
}
Esempio n. 4
0
/*****************************************************************
**	parsezonefile ()
**	parse the BIND zone file 'file' and store the minimum and
**	maximum ttl value in the corresponding parameter.
**	if keydbfile is set, check if this file is already include.
**	if inclfiles is not NULL store a list of included files names
**	in it.
**	return 0 if keydbfile is not included
**	return 1 if keydbfile is included
**	return -1 on error
*****************************************************************/
int	parsezonefile (const char *file, long *pminttl, long *pmaxttl, const char *keydbfile, char *inclfiles, size_t *plen)
{
	FILE	*infp;
	int	len;
	int	lnr;
	long	ttl;
	int	multi_line_rr;
	int	keydbfilefound;
	char	buf[1024];
	const	char	*p;

	assert (file != NULL);
	assert (pminttl != NULL);
	assert (pmaxttl != NULL);

	dbg_val4 ("parsezonefile (\"%s\", %ld, %ld, \"%s\")\n", file, *pminttl, *pmaxttl, keydbfile);

	if ( (infp = fopen (file, "r")) == NULL )
	{
		error ("parsezonefile: couldn't open file \"%s\" for input\n", file); 
		return -1;
	}

	lnr = 0;
	keydbfilefound = 0;
	multi_line_rr = 0;
	while ( fgets (buf, sizeof buf, infp) != NULL ) 
	{
		len = strlen (buf);
		if ( buf[len-1] != '\n' )	/* line too long ? */
			fprintf (stderr, "line too long\n");
		lnr++;

		p = buf;
		if ( multi_line_rr )	/* skip line if it's part of a multiline rr */
		{
			is_multiline_rr (&multi_line_rr, p);
			continue;
		}

		if ( *p == '$' )	/* special directive ? */
		{
			if ( strncmp (p+1, "TTL", 3) == 0 )	/* $TTL ? */
			{
				ttl = get_ttl (p+4);
				dbg_val3 ("%s:%d:ttl %ld\n", file, lnr, ttl);
				setminmax (pminttl, ttl, pmaxttl);
			}
			else if ( strncmp (p+1, "INCLUDE", 7) == 0 )	/* $INCLUDE ? */
			{
				char	fname[30+1];

				sscanf (p+9, "%30s", fname);
				dbg_val ("$INCLUDE directive for file \"%s\" found\n", fname);
				if ( strcmp (fname, keydbfile) == 0 )
					keydbfilefound = 1;
				else
				{
					if ( inclfiles && plen )
					{
						len = snprintf (inclfiles, *plen, ",%s", fname);
						if ( *plen <= len )	/* no space left in include file string */
							return keydbfilefound;
						inclfiles += len;
						*plen -= len;
					}
					int	ret = parsezonefile (fname, pminttl, pmaxttl, keydbfile, inclfiles, plen);
					if ( ret )	/* keydb found or read error ? */
						keydbfilefound = ret;
				}
			}
		}
		else if ( !isspace (*p) )	/* label ? */
			p = skiplabel (p);

		p = skipws (p);
		if ( *p == ';' )	/* skip line if it's  a comment line */
			continue;

			/* skip class (hesiod is not supported now) */
		if ( (toupper (*p) == 'I' && toupper (p[1]) == 'N') ||
		     (toupper (*p) == 'C' && toupper (p[1]) == 'H') )
			p += 2;
		p = skipws (p);

		if ( isdigit (*p) )	/* ttl ? */
		{
			ttl = get_ttl (p);
			dbg_val3 ("%s:%d:ttl %ld\n", file, lnr, ttl);
			setminmax (pminttl, ttl, pmaxttl);
		}

		/* check the rest of the line if it's the beginning of a multi_line_rr */
		is_multiline_rr (&multi_line_rr, p);
	}

	if ( file )
		fclose (infp);

	dbg_val5 ("parsezonefile (\"%s\", %ld, %ld, \"%s\") ==> %d\n",
			file, *pminttl, *pmaxttl, keydbfile, keydbfilefound);
	return keydbfilefound;
}
Esempio n. 5
0
/*****************************************************************
**
**	parse_namedconf (const char *filename, chroot_dir, dir, dirsize, int (*func) ())
**
**	Very dumb named.conf parser.
**	- In a zone declaration the _first_ keyword MUST be "type"
**	- For every master zone "func (directory, zone, filename)" will be called
**
*****************************************************************/
int	parse_namedconf (const char *filename, const char *chroot_dir, char *dir, size_t dirsize, int (*func) ())
{
	FILE	*fp;
	int	tok;
	char	path[511+1];
#if 1	/* this is potentialy too small for key data, but we don't need the keys... */
	char	strval[255+1];		
#else
	char	strval[4095+1];
#endif
	char	view[255+1];
	char	zone[255+1];
	char	zonefile[255+1];

	dbg_val ("parse_namedconf: parsing file \"%s\" \n", filename);

	assert (filename != NULL);
	assert (dir != NULL && dirsize != 0);
	assert (func != NULL);

	view[0] = '\0';
	if ( (fp = fopen (filename, "r")) == NULL )
		return 0;

	while ( (tok = gettok (fp, strval, sizeof strval)) != EOF )
	{
		if ( tok > 0 && tok < 256 )
		{
			error ("parse_namedconf: token found with value %-10d: %c\n", tok, tok);
			lg_mesg (LG_ERROR, "parse_namedconf: token found with value %-10d: %c", tok, tok);
		}
		else if ( tok == TOK_DIR )
		{
			if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
			{
				dbg_val2 ("parse_namedconf: directory found \"%s\" (dir is %s)\n",
										 strval, dir);
				if ( *strval != '/' &&  *dir )
					snprintf (path, sizeof (path), "%s/%s", dir, strval);
				else
					snprintf (path, sizeof (path), "%s", strval);

				/* prepend chroot directory (do it only once) */
				if ( chroot_dir && *chroot_dir )
				{
					snprintf (dir, dirsize, "%s%s%s", chroot_dir, *path == '/' ? "": "/", path);
					chroot_dir = NULL;
				}
				else
					snprintf (dir, dirsize, "%s", path);
				dbg_val ("parse_namedconf: new dir \"%s\" \n", dir);
			}	
		}	
		else if ( tok == TOK_INCLUDE )
		{
			if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
			{
				if ( *strval != '/' && *dir )
					snprintf (path, sizeof (path), "%s/%s", dir, strval);
				else
					snprintf (path, sizeof (path), "%s", strval);
				if ( !parse_namedconf (path, chroot_dir, dir, dirsize, func) )
					return 0;
			}
			else
			{
				error ("parse_namedconf: need a filename after \"include\"!\n");
				lg_mesg (LG_ERROR, "parse_namedconf: need a filename after \"include\"!");
			}
		}
		else if ( tok == TOK_VIEW )
		{
			if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
				continue;
			snprintf (view, sizeof view, "%s", strval);	/* store the name of the view */
		}
		else if ( tok == TOK_ZONE )
		{
			if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
				continue;
			snprintf (zone, sizeof zone, "%s", strval);	/* store the name of the zone */

			if ( gettok (fp, strval, sizeof (strval)) != TOK_MASTER )
				continue;
			if ( gettok (fp, strval, sizeof (strval)) != TOK_FILE )
				continue;
			if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
				continue;
			snprintf (zonefile, sizeof zonefile, "%s", strval);	/* this is the filename */

			dbg_val4 ("dir %s view %s zone %s file %s\n", dir, view, zone, zonefile);
			(*func) (dir, view, zone, zonefile);
		}
		else 
			dbg_val3 ("%-10s(%d): %s\n", tok2str(tok), tok, strval);
	}
	fclose (fp);

	return 1;
}