/***************************************************************** ** 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; }
/***************************************************************** ** ** lg_args (level, argc, argv[]) ** log all command line arguments (up to a length of 511 chars) ** with priority level ** *****************************************************************/ void lg_args (lg_lvl_t level, int argc, char * const argv[]) { char cmdline[511+1]; int len; int i; len = 0; for ( i = 0; i < argc && len < sizeof (cmdline); i++ ) len += snprintf (cmdline+len, sizeof (cmdline) - len, " %s", argv[i]); #if 1 lg_mesg (level, "------------------------------------------------------------"); #else lg_mesg (level, ""); #endif lg_mesg (level, "running%s ", cmdline); }
/***************************************************************** ** dyn_update_freeze () *****************************************************************/ int dyn_update_freeze (const char *domain, const zconf_t *z, int freeze) { char cmdline[254+1]; char str[254+1]; char *action; FILE *fp; assert (z != NULL); if ( freeze ) action = "freeze"; else action = "thaw"; 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: %s dynamic zone", str, action); verbmesg (1, z, "\t%s dynamic zone %s\n", action, str); if ( z->view ) snprintf (cmdline, sizeof (cmdline), "%s %s %s IN %s", RELOADCMD, action, domain, z->view); else snprintf (cmdline, sizeof (cmdline), "%s %s %s", RELOADCMD, action, domain); verbmesg (2, z, "\t Run cmd \"%s\"\n", cmdline); *str = '\0'; if ( z->noexec == 0 ) { if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) return -1; pclose (fp); } verbmesg (2, z, "\t rndc %s return: \"%s\"\n", action, str_chop (str, '\n')); return 0; }
int main (int argc, char *argv[]) { const char *levelstr; const char *newlevelstr; int level; int err; progname = *argv; if ( --argc ) levelstr = *++argv; else levelstr = "fatal"; level = lg_str2lvl (levelstr); newlevelstr = lg_lvl2str (level+1); dbg_val4 ("base level = %s(%d) newlevel = %s(%d)\n", levelstr, level, newlevelstr, level+1); if ( (err = lg_open (progname, #if 1 "user", #else "none", #endif levelstr, ".", #if 1 "test.log", #else NULL, #endif newlevelstr)) ) fprintf (stderr, "\topen error %d\n", err); else { lg_mesg (LG_DEBUG, "debug message"); lg_mesg (LG_INFO, "INFO message"); lg_mesg (LG_NOTICE, "Notice message"); lg_mesg (LG_WARNING, "Warning message"); lg_mesg (LG_ERROR, "Error message"); lg_mesg (LG_FATAL, "Fatal message "); } if ( (err = lg_close ()) < 0 ) fprintf (stderr, "\tclose error %d\n", err); return 0; }
/***************************************************************** ** distribute and reload a zone via "distribute_command" ** what is ** 1 for zone distribution and relaod ** 2 for key distribution (used by dynamic zoes) *****************************************************************/ int dist_and_reload (const zone_t *zp, int what) { char path[MAX_PATHSIZE+1]; char cmdline[254+1]; char zone[254+1]; char str[254+1]; char *view; FILE *fp; assert (zp != NULL); assert (zp->conf->dist_cmd != NULL); assert ( what == 1 || what == 2 ); if ( zp->conf->dist_cmd == NULL ) return 0; if ( !is_exec_ok (zp->conf->dist_cmd) ) { char *mesg; if ( getuid () == 0 ) mesg = "\tDistribution command %s not run as root\n"; else mesg = "\tDistribution command %s not run due to strange file mode settings\n"; verbmesg (1, zp->conf, mesg, zp->conf->dist_cmd); lg_mesg (LG_ERROR, "exec of distribution command %s disabled due to security reasons", zp->conf->dist_cmd); return -1; } view = ""; /* default is an empty view string */ if ( zp->conf->view ) { snprintf (zone, sizeof (zone), "\"%s\" in view \"%s\"", zp->zone, zp->conf->view); view = zp->conf->view; } else snprintf (zone, sizeof (zone), "\"%s\"", zp->zone); if ( what == 2 ) { lg_mesg (LG_NOTICE, "%s: key distribution triggered", zone); verbmesg (1, zp->conf, "\tDistribute keys for zone %s\n", zone); snprintf (cmdline, sizeof (cmdline), "%s distkeys %s %s %s", zp->conf->dist_cmd, zp->zone, path, view); *str = '\0'; if ( zp->conf->noexec == 0 ) { verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) return -2; pclose (fp); verbmesg (2, zp->conf, "\t %s distribute return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); } return 0; } pathname (path, sizeof (path), zp->dir, zp->sfile, NULL); lg_mesg (LG_NOTICE, "%s: distribution triggered", zone); verbmesg (1, zp->conf, "\tDistribute zone %s\n", zone); snprintf (cmdline, sizeof (cmdline), "%s distribute %s %s %s", zp->conf->dist_cmd, zp->zone, path, view); *str = '\0'; if ( zp->conf->noexec == 0 ) { verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) return -2; pclose (fp); verbmesg (2, zp->conf, "\t %s distribute return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); } lg_mesg (LG_NOTICE, "%s: reload triggered", zone); verbmesg (1, zp->conf, "\tReload zone %s\n", zone); snprintf (cmdline, sizeof (cmdline), "%s reload %s %s %s", zp->conf->dist_cmd, zp->zone, path, view); *str = '\0'; if ( zp->conf->noexec == 0 ) { verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) return -2; pclose (fp); verbmesg (2, zp->conf, "\t %s reload return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); } return 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; }