OpenDNSSEC-enforcer  2.1.7
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 "cmdhandler.h"
33 #include "daemon/engine.h"
34 #include "file.h"
35 #include "log.h"
36 #include "str.h"
37 #include "clientpipe.h"
38 #include "db/zone_db.h"
39 #include "hsmkey/hsm_key_factory.h"
42 
43 #include "keystate/zone_del_cmd.h"
44 
45 #include <limits.h>
46 #include <getopt.h>
47 
48 static const char *module_str = "zone_del_cmd";
49 
50 static void
51 usage(int sockfd)
52 {
53  client_printf(sockfd,
54  "zone delete\n"
55  " --zone <zone> | --all aka -z | -a \n"
56  " [--xml] aka -u \n"
57  );
58 }
59 
60 static void
61 help(int sockfd)
62 {
63  client_printf(sockfd,
64  "Delete one zone or all of them from the enforcer database.\n"
65  "\nOptions:\n"
66  "zone|all name of the zone or all zones\n"
67  "xml update zonelist.xml and remove the contents for the deleted zone\n\n"
68  );
69 }
70 
71 static int delete_key_data(zone_db_t* zone, db_connection_t *dbconn, int sockfd) {
72  int successful;
77 
78  /*
79  * Get key data for the zone and for each key data get the key state
80  * and try to delete all key state then the key data
81  */
83  client_printf_err(sockfd, "Unable to get key data for zone %s from database!\n", zone_db_name(zone));
84  return 0;
85  }
86  successful = 1;
89  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_db_name(zone));
90  successful = 0;
91  continue;
92  }
93 
96  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_db_name(zone));
97  successful = 0;
98  continue;
99  }
100  }
102 
103  if (key_data_delete(key_data)) {
104  client_printf_err(sockfd, "Unable to delete key data %s of zone %s from database!\n", key_data_role_text(key_data), zone_db_name(zone));
105  successful = 0;
106  continue;
107  }
108 
110  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_db_name(zone));
111  successful = 0;
112  continue;
113  }
114  }
116 
117  return successful;
118 }
119 
120 static int
121 run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
122 {
123  #define NARGV 6
124  char* buf;
125  const char* argv[NARGV];
126  int argc = 0;
127  const char *zone_name2 = NULL;
128  int all = 0;
129  int write_xml = 0;
130  int long_index = 0, opt = 0;
131  zone_list_db_t* zone_list;
132  zone_db_t* zone;
133  int ret = 0;
134  char path[PATH_MAX];
135  char *signconf_del = NULL;
136  db_connection_t* dbconn = getconnectioncontext(context);;
137  engine_type* engine = getglobalcontext(context);
138 
139  static struct option long_options[] = {
140  {"zone", required_argument, 0, 'z'},
141  {"all", no_argument, 0, 'a'},
142  {"xml", no_argument, 0, 'u'},
143  {0, 0, 0, 0}
144  };
145 
146  ods_log_debug("[%s] %s command", module_str, zone_del_funcblock.cmdname);
147 
148  if (!(buf = strdup(cmd))) {
149  client_printf_err(sockfd, "memory error\n");
150  return -1;
151  }
152 
153  argc = ods_str_explode(buf, NARGV, argv);
154  if (argc == -1) {
155  client_printf_err(sockfd, "too many arguments\n");
156  ods_log_error("[%s] too many arguments for %s command",
157  module_str, zone_del_funcblock.cmdname);
158  free(buf);
159  return -1;
160  }
161 
162  optind = 0;
163  while ((opt = getopt_long(argc, (char* const*)argv, "z:au", long_options, &long_index)) != -1) {
164  switch (opt) {
165  case 'z':
166  zone_name2 = optarg;
167  break;
168  case 'a':
169  all = 1;
170  break;
171  case 'u':
172  write_xml = 1;
173  break;
174  default:
175  client_printf_err(sockfd, "unknown arguments\n");
176  ods_log_error("[%s] unknown arguments for %s command",
177  module_str, zone_del_funcblock.cmdname);
178  free(buf);
179  return -1;
180  }
181  }
182 
183  if (zone_name2 && !all) {
184  if (!(zone = zone_db_new_get_by_name(dbconn, zone_name2))) {
185  client_printf_err(sockfd, "Unable to delete zone, zone %s not found!\n", zone_name2);
186  free(buf);
187  return 1;
188  }
189 
190  if (!delete_key_data(zone, dbconn, sockfd)) {
191  zone_db_free(zone);
192  free(buf);
193  return 1;
194  }
195  if (zone_db_delete(zone)) {
196  client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_name2);
197  zone_db_free(zone);
198  free(buf);
199  return 1;
200  }
201  signconf_del = (char*) calloc(strlen(zone_db_signconf_path(zone)) +
202  strlen(".ZONE_DELETED") + 1, sizeof(char));
203  if (!signconf_del) {
204  ods_log_error("[%s] malloc failed", module_str);
205  zone_db_free(zone);
206  free(buf);
207  return 1;
208  }
209  strncpy(signconf_del, zone_db_signconf_path(zone), strlen(zone_db_signconf_path(zone)));
210  strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
211  rename(zone_db_signconf_path(zone), signconf_del);
212  free(signconf_del);
213  signconf_del = NULL;
214 
215  /* Delete all 'zone' related tasks */
216  schedule_purge_owner(engine->taskq, TASK_CLASS_ENFORCER, zone_name2);
217 
218  ods_log_info("[%s] zone %s deleted", module_str, zone_name2);
219  client_printf(sockfd, "Deleted zone %s successfully\n", zone_name2);
220  } else if (!zone_name2 && all) {
221  if (!(zone_list = zone_list_db_new_get(dbconn))) {
222  client_printf_err(sockfd, "Unable to get list of zones from database!\n");
223  free(buf);
224  return 1;
225  }
226  for (zone = zone_list_db_get_next(zone_list); zone; zone_db_free(zone), zone = zone_list_db_get_next(zone_list)) {
227  if (!delete_key_data(zone, dbconn, sockfd)) {
228  continue;
229  }
230  if (zone_db_delete(zone)) {
231  client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_db_name(zone));
232  continue;
233  }
234 
235  signconf_del = (char*) calloc(strlen(zone_db_signconf_path(zone)) +
236  strlen(".ZONE_DELETED") + 1, sizeof(char));
237  if (!signconf_del) {
238  ods_log_error("[%s] malloc failed", module_str);
239  zone_db_free(zone);
240  zone_list_db_free(zone_list);
241  free(buf);
242  return 1;
243  }
244  strncpy(signconf_del, zone_db_signconf_path(zone), strlen(zone_db_signconf_path(zone)));
245  strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
246  rename(zone_db_signconf_path(zone), signconf_del);
247  free(signconf_del);
248  signconf_del = NULL;
249 
250  /* Delete all 'zone' related tasks */
251  schedule_purge_owner(engine->taskq, TASK_CLASS_ENFORCER, zone_db_name(zone));
252 
253  ods_log_info("[%s] zone %s deleted", module_str, zone_db_name(zone));
254  client_printf(sockfd, "Deleted zone %s successfully\n", zone_db_name(zone));
255  }
256  zone_list_db_free(zone_list);
257  zone = NULL;
258  client_printf(sockfd, "All zones deleted successfully\n");
259  } else {
260  client_printf_err(sockfd, "expected either --zone <zone> or --all\n");
261  free(buf);
262  return -1;
263  }
264  free(buf);
265 
266  if (write_xml) {
267  if (zone) {
268  if (zonelist_update_delete(sockfd, engine->config->zonelist_filename, zone, 1) != ZONELIST_UPDATE_OK) {
269  ods_log_error("[%s] zonelist %s updated failed", module_str, engine->config->zonelist_filename);
270  client_printf_err(sockfd, "Zonelist %s update failed!\n", engine->config->zonelist_filename);
271  ret = 1;
272  } else {
273  ods_log_info("[%s] zonelist %s updated successfully", module_str, engine->config->zonelist_filename);
274  client_printf(sockfd, "Zonelist %s updated successfully\n", engine->config->zonelist_filename);
275  }
276  } else {
277  if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
278  ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
279  client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
280  ret = 1;
281  } else {
282  ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
283  client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
284  }
285  }
286  }
287 
288  if (zone) {
289  if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
290  || zonelist_update_delete(sockfd, path, zone, 0) != ZONELIST_UPDATE_OK)
291  {
292  ods_log_error("[%s] internal zonelist update failed", module_str);
293  client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
294  ret = 1;
295  } else {
296  ods_log_info("[%s] internal zonelist updated successfully", module_str);
297  }
298  } else {
299  if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
300  || zonelist_export(sockfd, dbconn, path, 0) != ZONELIST_EXPORT_OK)
301  {
302  ods_log_error("[%s] internal zonelist update failed", module_str);
303  client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
304  ret = 1;
305  } else {
306  ods_log_info("[%s] internal zonelist updated successfully", module_str);
307  }
308  }
309 
310  zone_db_free(zone);
311  return ret;
312 }
313 
314 struct cmd_func_block zone_del_funcblock = {
315  "zone delete", &usage, &help, NULL, &run
316 };
hsm_key_factory_release_key_id
int hsm_key_factory_release_key_id(const db_value_t *hsm_key_id, const db_connection_t *connection)
Definition: hsm_key_factory.c:704
hsm_key_factory.h
zone_del_funcblock
struct cmd_func_block zone_del_funcblock
Definition: zone_del_cmd.c:314
key_data_list
Definition: key_data.h:479
key_state_type_text
const char * key_state_type_text(const key_state_t *key_state)
Definition: key_state.c:353
zonelist_update.h
zone_db_id
const db_value_t * zone_db_id(const zone_db_t *zone)
Definition: zone_db.c:728
key_data_list_new_get_by_zone_id
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
enforcercommands.h
zone_db_signconf_path
const char * zone_db_signconf_path(const zone_db_t *zone)
Definition: zone_db.c:798
ZONELIST_UPDATE_OK
#define ZONELIST_UPDATE_OK
Definition: zonelist_update.h:37
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
key_state_list_free
void key_state_list_free(key_state_list_t *key_state_list)
Definition: key_state.c:924
key_data_role_text
const char * key_data_role_text(const key_data_t *key_data)
Definition: key_data.c:711
zone_db_new_get_by_name
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone_db.c:1569
key_state_list_get_next
key_state_t * key_state_list_get_next(key_state_list_t *key_state_list)
Definition: key_state.c:1398
key_state_delete
int key_state_delete(const key_state_t *key_state)
Definition: key_state.c:831
zonelist_update_delete
int zonelist_update_delete(int sockfd, const char *filename, const zone_db_t *zone, int comment)
Definition: zonelist_update.c:232
key_state
Definition: key_state.h:65
ZONELIST_EXPORT_OK
#define ZONELIST_EXPORT_OK
Definition: zonelist_export.h:37
zone_db.h
engineconfig_struct::working_dir
const char * working_dir
Definition: cfg.h:64
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
zonelist_export
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
Definition: zonelist_export.c:47
key_data_free
void key_data_free(key_data_t *key_data)
Definition: key_data.c:304
zone_db
Definition: zone_db.h:46
engine_struct::taskq
schedule_type * taskq
Definition: engine.h:60
getconnectioncontext
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:110
key_data_list_free
void key_data_list_free(key_data_list_t *key_data_list)
Definition: key_data.c:1694
engineconfig_struct::zonelist_filename
const char * zonelist_filename
Definition: cfg.h:57
zone_list_db
Definition: zone_db.h:466
zone_db_delete
int zone_db_delete(zone_db_t *zone)
Definition: zone_db.c:1884
NARGV
#define NARGV
zone_list_db_free
void zone_list_db_free(zone_list_db_t *zone_list)
Definition: zone_db.c:1989
engine_struct
Definition: engine.h:47
zone_del_cmd.h
zonelist_export.h
engine_struct::config
engineconfig_type * config
Definition: engine.h:48
key_state_list_new_get_by_key_data_id
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
engine.h
key_data_delete
int key_data_delete(key_data_t *key_data)
Definition: key_data.c:1587
zone_list_db_new_get
zone_list_db_t * zone_list_db_new_get(const db_connection_t *connection)
Definition: zone_db.c:2402
db_connection
Definition: db_connection.h:46
zone_list_db_get_next
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
getglobalcontext
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:104
key_data_id
const db_value_t * key_data_id(const key_data_t *key_data)
Definition: key_data.c:553
key_data_hsm_key_id
const db_value_t * key_data_hsm_key_id(const key_data_t *key_data)
Definition: key_data.c:607
key_data_list_get_next
key_data_t * key_data_list_get_next(key_data_list_t *key_data_list)
Definition: key_data.c:2425
key_data
Definition: key_data.h:68
key_state_free
void key_state_free(key_state_t *key_state)
Definition: key_state.c:214
key_state_list
Definition: key_state.h:262