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