OpenDNSSEC-enforcer  2.0.3
zone_del_cmd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
3  * Copyright (c) 2014 OpenDNSSEC AB (svb)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 #include "config.h"
30 
31 #include "daemon/cmdhandler.h"
32 #include "daemon/engine.h"
33 #include "file.h"
34 #include "log.h"
35 #include "str.h"
36 #include "clientpipe.h"
37 #include "db/zone.h"
38 #include "hsmkey/hsm_key_factory.h"
41 
42 #include "keystate/zone_del_cmd.h"
43 
44 #include <limits.h>
45 
46 static const char *module_str = "zone_del_cmd";
47 
48 static void
49 usage(int sockfd)
50 {
51  client_printf(sockfd,
52  "zone delete\n"
53  " --zone <zone> | --all aka -z | -a \n"
54  " [--xml] aka -u \n"
55  );
56 }
57 
58 static void
59 help(int sockfd)
60 {
61  client_printf(sockfd,
62  "Delete one zone or all of them from the enforcer database.\n"
63  "\nOptions:\n"
64  "zone|all name of the zone or all zones\n"
65  "xml update zonelist.xml and remove the contents for the deleted zone\n\n"
66  );
67 }
68 
69 static int
70 handles(const char *cmd, ssize_t n)
71 {
72  return ods_check_command(cmd, n, zone_del_funcblock()->cmdname)?1:0;
73 }
74 
75 static int delete_key_data(zone_t* zone, db_connection_t *dbconn, int sockfd) {
76  int successful;
81 
82  /*
83  * Get key data for the zone and for each key data get the key state
84  * and try to delete all key state then the key data
85  */
86  if (!(key_data_list = key_data_list_new_get_by_zone_id(dbconn, zone_id(zone)))) {
87  client_printf_err(sockfd, "Unable to get key data for zone %s from database!\n", zone_name(zone));
88  return 0;
89  }
90  successful = 1;
91  for (key_data = key_data_list_get_next(key_data_list); key_data; key_data_free(key_data), key_data = key_data_list_get_next(key_data_list)) {
92  if (!(key_state_list = key_state_list_new_get_by_key_data_id(dbconn, key_data_id(key_data)))) {
93  client_printf_err(sockfd, "Unable to get key states for key data %s of zone %s from database!\n", key_data_role_text(key_data), zone_name(zone));
94  successful = 0;
95  continue;
96  }
97 
98  for (key_state = key_state_list_get_next(key_state_list); key_state; key_state_free(key_state), key_state = key_state_list_get_next(key_state_list)) {
99  if (key_state_delete(key_state)) {
100  client_printf_err(sockfd, "Unable to delete key state %s for key data %s of zone %s from database!\n", key_state_type_text(key_state), key_data_role_text(key_data), zone_name(zone));
101  successful = 0;
102  continue;
103  }
104  }
105  key_state_list_free(key_state_list);
106 
107  if (key_data_delete(key_data)) {
108  client_printf_err(sockfd, "Unable to delete key data %s of zone %s from database!\n", key_data_role_text(key_data), zone_name(zone));
109  successful = 0;
110  continue;
111  }
112 
113  if (hsm_key_factory_release_key_id(key_data_hsm_key_id(key_data), dbconn)) {
114  client_printf_err(sockfd, "Unable to release HSM key for key data %s of zone %s from database!\n", key_data_role_text(key_data), zone_name(zone));
115  successful = 0;
116  continue;
117  }
118  }
119  key_data_list_free(key_data_list);
120 
121  return successful;
122 }
123 
124 static int
125 run(int sockfd, engine_type* engine, const char *cmd, ssize_t n,
126  db_connection_t *dbconn)
127 {
128  char* buf;
129  const char* argv[17];
130  int argc;
131  const char *zone_name2 = NULL;
132  int all;
133  int write_xml;
135  zone_t* zone;
136  int ret = 0;
137  char path[PATH_MAX];
138  char *signconf_del = NULL;
139  (void)engine;
140 
141  ods_log_debug("[%s] %s command", module_str, zone_del_funcblock()->cmdname);
142  cmd = ods_check_command(cmd, n, zone_del_funcblock()->cmdname);
143 
144  if (!(buf = strdup(cmd))) {
145  client_printf_err(sockfd, "memory error\n");
146  return -1;
147  }
148 
149  argc = ods_str_explode(buf, 17, argv);
150  if (argc > 17) {
151  client_printf_err(sockfd, "too many arguments\n");
152  free(buf);
153  return -1;
154  }
155 
156  ods_find_arg_and_param(&argc, argv, "zone", "z", &zone_name2);
157  all = ods_find_arg(&argc, argv, "all", "a") > -1 ? 1 : 0;
158  write_xml = ods_find_arg(&argc, argv, "xml", "u") > -1 ? 1 : 0;
159 
160  if (argc) {
161  client_printf_err(sockfd, "unknown arguments\n");
162  free(buf);
163  return -1;
164  }
165 
166  if (zone_name2 && !all) {
167  if (!(zone = zone_new_get_by_name(dbconn, zone_name2))) {
168  client_printf_err(sockfd, "Unable to delete zone, zone %s not found!\n", zone_name2);
169  free(buf);
170  return 1;
171  }
172 
173  if (!delete_key_data(zone, dbconn, sockfd)) {
174  zone_free(zone);
175  free(buf);
176  return 1;
177  }
178  if (zone_delete(zone)) {
179  client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_name2);
180  zone_free(zone);
181  free(buf);
182  return 1;
183  }
184  signconf_del = (char*) calloc(strlen(zone_signconf_path(zone)) +
185  strlen(".ZONE_DELETED") + 1, sizeof(char));
186  if (!signconf_del) {
187  ods_log_error("[%s] malloc failed", module_str);
188  zone_free(zone);
189  free(buf);
190  return 1;
191  }
192  strncpy(signconf_del, zone_signconf_path(zone), strlen(zone_signconf_path(zone)));
193  strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
194  rename(zone_signconf_path(zone), signconf_del);
195  free(signconf_del);
196  signconf_del = NULL;
197 
198  ods_log_info("[%s] zone %s deleted", module_str, zone_name2);
199  client_printf(sockfd, "Deleted zone %s successfully\n", zone_name2);
200  } else if (!zone_name2 && all) {
201  if (!(zone_list = zone_list_new_get(dbconn))) {
202  client_printf_err(sockfd, "Unable to get list of zones from database!\n");
203  free(buf);
204  return 1;
205  }
206  for (zone = zone_list_get_next(zone_list); zone; zone_free(zone), zone = zone_list_get_next(zone_list)) {
207  if (!delete_key_data(zone, dbconn, sockfd)) {
208  continue;
209  }
210  if (zone_delete(zone)) {
211  client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_name(zone));
212  continue;
213  }
214 
215  signconf_del = (char*) calloc(strlen(zone_signconf_path(zone)) +
216  strlen(".ZONE_DELETED") + 1, sizeof(char));
217  if (!signconf_del) {
218  ods_log_error("[%s] malloc failed", module_str);
219  zone_free(zone);
220  zone_list_free(zone_list);
221  free(buf);
222  return 1;
223  }
224  strncpy(signconf_del, zone_signconf_path(zone), strlen(zone_signconf_path(zone)));
225  strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
226  rename(zone_signconf_path(zone), signconf_del);
227  free(signconf_del);
228  signconf_del = NULL;
229 
230  ods_log_info("[%s] zone %s deleted", module_str, zone_name(zone));
231  client_printf(sockfd, "Deleted zone %s successfully\n", zone_name(zone));
232  }
233  zone_list_free(zone_list);
234  zone = NULL;
235  client_printf(sockfd, "All zones deleted successfully\n");
236  } else {
237  client_printf_err(sockfd, "expected either --zone <zone> or --all\n");
238  free(buf);
239  return -1;
240  }
241  free(buf);
242 
243  if (write_xml) {
244  if (zone) {
245  if (zonelist_update_delete(sockfd, engine->config->zonelist_filename, zone, 1) != ZONELIST_UPDATE_OK) {
246  ods_log_error("[%s] zonelist %s updated failed", module_str, engine->config->zonelist_filename);
247  client_printf_err(sockfd, "Zonelist %s update failed!\n", engine->config->zonelist_filename);
248  ret = 1;
249  } else {
250  ods_log_info("[%s] zonelist %s updated successfully", module_str, engine->config->zonelist_filename);
251  client_printf(sockfd, "Zonelist %s updated successfully\n", engine->config->zonelist_filename);
252  }
253  } else {
254  if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
255  ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
256  client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
257  ret = 1;
258  } else {
259  ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
260  client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
261  }
262  }
263  }
264 
265  if (zone) {
266  if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
267  || zonelist_update_delete(sockfd, path, zone, 0) != ZONELIST_UPDATE_OK)
268  {
269  ods_log_error("[%s] internal zonelist update failed", module_str);
270  client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
271  ret = 1;
272  } else {
273  ods_log_info("[%s] internal zonelist updated successfully", module_str);
274  }
275  } else {
276  if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
277  || zonelist_export(sockfd, dbconn, path, 0) != ZONELIST_EXPORT_OK)
278  {
279  ods_log_error("[%s] internal zonelist update failed", module_str);
280  client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
281  ret = 1;
282  } else {
283  ods_log_info("[%s] internal zonelist updated successfully", module_str);
284  }
285  }
286 
287  zone_free(zone);
288  return ret;
289 }
290 
291 static struct cmd_func_block funcblock = {
292  "zone delete", &usage, &help, &handles, &run
293 };
294 
295 struct cmd_func_block*
297 {
298  return &funcblock;
299 }
const char * key_data_role_text(const key_data_t *key_data)
Definition: key_data.c:711
void(* help)(int sockfd)
Definition: cmdhandler.h:64
int key_state_delete(key_state_t *key_state)
Definition: key_state.c:831
const char * zone_signconf_path(const zone_t *zone)
Definition: zone.c:798
void ods_log_debug(const char *format,...)
Definition: log.c:41
#define ZONELIST_UPDATE_OK
const char * key_state_type_text(const key_state_t *key_state)
Definition: key_state.c:353
const char * zonelist_filename
Definition: cfg.h:57
key_state_t * key_state_list_get_next(key_state_list_t *key_state_list)
Definition: key_state.c:1398
void zone_list_free(zone_list_t *zone_list)
Definition: zone.c:1989
void ods_log_info(const char *format,...)
Definition: log.c:55
int(* run)(int sockfd, struct engine_struct *engine, const char *cmd, ssize_t n, db_connection_t *dbconn)
Definition: cmdhandler.h:79
const db_value_t * key_data_id(const key_data_t *key_data)
Definition: key_data.c:553
const char * cmdname
Definition: cmdhandler.h:59
void ods_log_error(const char *format,...)
Definition: log.c:69
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
Definition: key_data.c:2425
void zone_free(zone_t *zone)
Definition: zone.c:325
void(* usage)(int sockfd)
Definition: cmdhandler.h:61
#define ZONELIST_EXPORT_OK
engineconfig_type * config
Definition: engine.h:53
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
void key_state_free(key_state_t *key_state)
Definition: key_state.c:214
zone_t * zone_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone.c:1569
const char * zone_name(const zone_t *zone)
Definition: zone.c:782
void key_state_list_free(key_state_list_t *key_state_list)
Definition: key_state.c:924
zone_t * zone_list_get_next(zone_list_t *zone_list)
Definition: zone.c:2666
const char * working_dir
Definition: cfg.h:64
void key_data_list_free(key_data_list_t *key_data_list)
Definition: key_data.c:1694
struct cmd_func_block * zone_del_funcblock(void)
Definition: zone_del_cmd.c:296
const db_value_t * key_data_hsm_key_id(const key_data_t *key_data)
Definition: key_data.c:607
void key_data_free(key_data_t *key_data)
Definition: key_data.c:304
const db_value_t * zone_id(const zone_t *zone)
Definition: zone.c:728
key_data_list_t * key_data_list_new_get_by_zone_id(const db_connection_t *connection, const db_value_t *zone_id)
Definition: key_data.c:2244
zone_list_t * zone_list_new_get(const db_connection_t *connection)
Definition: zone.c:2399
int zonelist_update_delete(int sockfd, const char *filename, const zone_t *zone, int comment)
Definition: zone.h:46
int(* handles)(const char *cmd, ssize_t n)
Definition: cmdhandler.h:67
int key_data_delete(key_data_t *key_data)
Definition: key_data.c:1587
int zone_delete(zone_t *zone)
Definition: zone.c:1884
int hsm_key_factory_release_key_id(const db_value_t *hsm_key_id, const db_connection_t *connection)
key_state_list_t * key_state_list_new_get_by_key_data_id(const db_connection_t *connection, const db_value_t *key_data_id)
Definition: key_state.c:1217