1/***************************************************************** 2** 3** @(#) nscomm.c (c) 2005 - 2009 Holger Zuleger hznet.de 4** 5** Copyright (c) 2005 - 2009, Holger Zuleger HZnet. All rights reserved. 6** 7** This software is open source. 8** 9** Redistribution and use in source and binary forms, with or without 10** modification, are permitted provided that the following conditions 11** are met: 12** 13** Redistributions of source code must retain the above copyright notice, 14** this list of conditions and the following disclaimer. 15** 16** Redistributions in binary form must reproduce the above copyright notice, 17** this list of conditions and the following disclaimer in the documentation 18** and/or other materials provided with the distribution. 19** 20** Neither the name of Holger Zuleger HZnet nor the names of its contributors may 21** be used to endorse or promote products derived from this software without 22** specific prior written permission. 23** 24** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 28** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34** POSSIBILITY OF SUCH DAMAGE. 35** 36*****************************************************************/ 37# include <stdio.h> 38 39#ifdef HAVE_CONFIG_H 40# include <config.h> 41#endif 42 43#include "config_zkt.h" 44#include "zconf.h" 45#define extern 46#include "nscomm.h" 47#undef extern 48 49 50/***************************************************************** 51** dyn_update_freeze () 52*****************************************************************/ 53int dyn_update_freeze (const char *domain, const zconf_t *z, int freeze) 54{ 55 char cmdline[254+1]; 56 char str[254+1]; 57 char *action; 58 FILE *fp; 59 60 assert (z != NULL); 61 if ( freeze ) 62 action = "freeze"; 63 else 64 action = "thaw"; 65 66 if ( z->view ) 67 snprintf (str, sizeof (str), "\"%s\" in view \"%s\"", domain, z->view); 68 else 69 snprintf (str, sizeof (str), "\"%s\"", domain); 70 71 lg_mesg (LG_NOTICE, "%s: %s dynamic zone", str, action); 72 verbmesg (1, z, "\t%s dynamic zone %s\n", action, str); 73 74 if ( z->view ) 75 snprintf (cmdline, sizeof (cmdline), "%s %s %s IN %s", RELOADCMD, action, domain, z->view); 76 else 77 snprintf (cmdline, sizeof (cmdline), "%s %s %s", RELOADCMD, action, domain); 78 79 verbmesg (2, z, "\t Run cmd \"%s\"\n", cmdline); 80 *str = '\0'; 81 if ( z->noexec == 0 ) 82 { 83 if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) 84 return -1; 85 pclose (fp); 86 } 87 88 verbmesg (2, z, "\t rndc %s return: \"%s\"\n", action, str_chop (str, '\n')); 89 90 return 0; 91} 92 93/***************************************************************** 94** distribute and reload a zone via "distribute_command" 95** what is 96** 1 for zone distribution and relaod 97** 2 for key distribution (used by dynamic zoes) 98*****************************************************************/ 99int dist_and_reload (const zone_t *zp, int what) 100{ 101 char path[MAX_PATHSIZE+1]; 102 char cmdline[254+1]; 103 char zone[254+1]; 104 char str[254+1]; 105 char *view; 106 FILE *fp; 107 108 assert (zp != NULL); 109 assert (zp->conf->dist_cmd != NULL); 110 assert ( what == 1 || what == 2 ); 111 112 if ( zp->conf->dist_cmd == NULL ) 113 return 0; 114 115 if ( !is_exec_ok (zp->conf->dist_cmd) ) 116 { 117 char *mesg; 118 119 if ( getuid () == 0 ) 120 mesg = "\tDistribution command %s not run as root\n"; 121 else 122 mesg = "\tDistribution command %s not run due to strange file mode settings\n"; 123 124 verbmesg (1, zp->conf, mesg, zp->conf->dist_cmd); 125 lg_mesg (LG_ERROR, "exec of distribution command %s disabled due to security reasons", zp->conf->dist_cmd); 126 127 return -1; 128 } 129 130 view = ""; /* default is an empty view string */ 131 if ( zp->conf->view ) 132 { 133 snprintf (zone, sizeof (zone), "\"%s\" in view \"%s\"", zp->zone, zp->conf->view); 134 view = zp->conf->view; 135 } 136 else 137 snprintf (zone, sizeof (zone), "\"%s\"", zp->zone); 138 139 140 if ( what == 2 ) 141 { 142 lg_mesg (LG_NOTICE, "%s: key distribution triggered", zone); 143 verbmesg (1, zp->conf, "\tDistribute keys for zone %s\n", zone); 144 snprintf (cmdline, sizeof (cmdline), "%s distkeys %s %s %s", 145 zp->conf->dist_cmd, zp->zone, path, view); 146 *str = '\0'; 147 if ( zp->conf->noexec == 0 ) 148 { 149 verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); 150 if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) 151 return -2; 152 pclose (fp); 153 verbmesg (2, zp->conf, "\t %s distribute return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); 154 } 155 156 return 0; 157 } 158 159 pathname (path, sizeof (path), zp->dir, zp->sfile, NULL); 160 161 lg_mesg (LG_NOTICE, "%s: distribution triggered", zone); 162 verbmesg (1, zp->conf, "\tDistribute zone %s\n", zone); 163 snprintf (cmdline, sizeof (cmdline), "%s distribute %s %s %s", zp->conf->dist_cmd, zp->zone, path, view); 164 165 *str = '\0'; 166 if ( zp->conf->noexec == 0 ) 167 { 168 verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); 169 if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) 170 return -2; 171 pclose (fp); 172 verbmesg (2, zp->conf, "\t %s distribute return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); 173 } 174 175 176 lg_mesg (LG_NOTICE, "%s: reload triggered", zone); 177 verbmesg (1, zp->conf, "\tReload zone %s\n", zone); 178 snprintf (cmdline, sizeof (cmdline), "%s reload %s %s %s", zp->conf->dist_cmd, zp->zone, path, view); 179 180 *str = '\0'; 181 if ( zp->conf->noexec == 0 ) 182 { 183 verbmesg (2, zp->conf, "\t Run cmd \"%s\"\n", cmdline); 184 if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) 185 return -2; 186 pclose (fp); 187 verbmesg (2, zp->conf, "\t %s reload return: \"%s\"\n", zp->conf->dist_cmd, str_chop (str, '\n')); 188 } 189 190 return 0; 191} 192 193/***************************************************************** 194** reload a zone via "rndc" 195*****************************************************************/ 196int reload_zone (const char *domain, const zconf_t *z) 197{ 198 char cmdline[254+1]; 199 char str[254+1]; 200 FILE *fp; 201 202 assert (z != NULL); 203 dbg_val3 ("reload_zone %d :%s: :%s:\n", z->verbosity, domain, z->view); 204 if ( z->view ) 205 snprintf (str, sizeof (str), "\"%s\" in view \"%s\"", domain, z->view); 206 else 207 snprintf (str, sizeof (str), "\"%s\"", domain); 208 209 lg_mesg (LG_NOTICE, "%s: reload triggered", str); 210 verbmesg (1, z, "\tReload zone %s\n", str); 211 212 if ( z->view ) 213 snprintf (cmdline, sizeof (cmdline), "%s reload %s IN %s", RELOADCMD, domain, z->view); 214 else 215 snprintf (cmdline, sizeof (cmdline), "%s reload %s", RELOADCMD, domain); 216 217 *str = '\0'; 218 if ( z->noexec == 0 ) 219 { 220 verbmesg (2, z, "\t Run cmd \"%s\"\n", cmdline); 221 if ( (fp = popen (cmdline, "r")) == NULL || fgets (str, sizeof str, fp) == NULL ) 222 return -1; 223 pclose (fp); 224 verbmesg (2, z, "\t rndc reload return: \"%s\"\n", str_chop (str, '\n')); 225 } 226 227 return 0; 228} 229