zone_del_cmd.c
Go to the documentation of this file.
/*
* Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
* Copyright (c) 2014 OpenDNSSEC AB (svb)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "cmdhandler.h"
#include "daemon/enforcercommands.h"
#include "daemon/engine.h"
#include "file.h"
#include "log.h"
#include "str.h"
#include "clientpipe.h"
#include "db/zone_db.h"
#include "hsmkey/hsm_key_factory.h"
#include "keystate/zonelist_update.h"
#include "keystate/zonelist_export.h"
#include "keystate/zone_del_cmd.h"
#include <limits.h>
#include <getopt.h>
static const char *module_str = "zone_del_cmd";
static void
usage(int sockfd)
{
client_printf(sockfd,
"zone delete\n"
" --zone <zone> | --all aka -z | -a \n"
" [--xml] aka -u \n"
);
}
static void
help(int sockfd)
{
client_printf(sockfd,
"Delete one zone or all of them from the enforcer database.\n"
"\nOptions:\n"
"zone|all name of the zone or all zones\n"
"xml update zonelist.xml and remove the contents for the deleted zone\n\n"
);
}
static int delete_key_data(zone_db_t* zone, db_connection_t *dbconn, int sockfd) {
int successful;
key_data_list_t* key_data_list;
key_data_t* key_data;
key_state_list_t* key_state_list;
key_state_t* key_state;
/*
* Get key data for the zone and for each key data get the key state
* and try to delete all key state then the key data
*/
if (!(key_data_list = key_data_list_new_get_by_zone_id(dbconn, zone_db_id(zone)))) {
client_printf_err(sockfd, "Unable to get key data for zone %s from database!\n", zone_db_name(zone));
return 0;
}
successful = 1;
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)) {
if (!(key_state_list = key_state_list_new_get_by_key_data_id(dbconn, key_data_id(key_data)))) {
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));
successful = 0;
continue;
}
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)) {
if (key_state_delete(key_state)) {
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));
successful = 0;
continue;
}
}
key_state_list_free(key_state_list);
if (key_data_delete(key_data)) {
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));
successful = 0;
continue;
}
if (hsm_key_factory_release_key_id(key_data_hsm_key_id(key_data), dbconn)) {
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));
successful = 0;
continue;
}
}
key_data_list_free(key_data_list);
return successful;
}
static int
run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
{
#define NARGV 6
char* buf;
const char* argv[NARGV];
int argc = 0;
const char *zone_name2 = NULL;
int all = 0;
int write_xml = 0;
int long_index = 0, opt = 0;
zone_list_db_t* zone_list;
zone_db_t* zone;
int ret = 0;
char path[PATH_MAX];
char *signconf_del = NULL;
db_connection_t* dbconn = getconnectioncontext(context);;
engine_type* engine = getglobalcontext(context);
static struct option long_options[] = {
{"zone", required_argument, 0, 'z'},
{"all", no_argument, 0, 'a'},
{"xml", no_argument, 0, 'u'},
{0, 0, 0, 0}
};
ods_log_debug("[%s] %s command", module_str, zone_del_funcblock.cmdname);
if (!(buf = strdup(cmd))) {
client_printf_err(sockfd, "memory error\n");
return -1;
}
argc = ods_str_explode(buf, NARGV, argv);
if (argc == -1) {
client_printf_err(sockfd, "too many arguments\n");
ods_log_error("[%s] too many arguments for %s command",
module_str, zone_del_funcblock.cmdname);
free(buf);
return -1;
}
optind = 0;
while ((opt = getopt_long(argc, (char* const*)argv, "z:au", long_options, &long_index)) != -1) {
switch (opt) {
case 'z':
zone_name2 = optarg;
break;
case 'a':
all = 1;
break;
case 'u':
write_xml = 1;
break;
default:
client_printf_err(sockfd, "unknown arguments\n");
ods_log_error("[%s] unknown arguments for %s command",
module_str, zone_del_funcblock.cmdname);
free(buf);
return -1;
}
}
if (zone_name2 && !all) {
if (!(zone = zone_db_new_get_by_name(dbconn, zone_name2))) {
client_printf_err(sockfd, "Unable to delete zone, zone %s not found!\n", zone_name2);
free(buf);
return 1;
}
if (!delete_key_data(zone, dbconn, sockfd)) {
zone_db_free(zone);
free(buf);
return 1;
}
if (zone_db_delete(zone)) {
client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_name2);
zone_db_free(zone);
free(buf);
return 1;
}
signconf_del = (char*) calloc(strlen(zone_db_signconf_path(zone)) +
strlen(".ZONE_DELETED") + 1, sizeof(char));
if (!signconf_del) {
ods_log_error("[%s] malloc failed", module_str);
zone_db_free(zone);
free(buf);
return 1;
}
strncpy(signconf_del, zone_db_signconf_path(zone), strlen(zone_db_signconf_path(zone)));
strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
rename(zone_db_signconf_path(zone), signconf_del);
free(signconf_del);
signconf_del = NULL;
/* Delete all 'zone' related tasks */
schedule_purge_owner(engine->taskq, TASK_CLASS_ENFORCER, zone_name2);
ods_log_info("[%s] zone %s deleted", module_str, zone_name2);
client_printf(sockfd, "Deleted zone %s successfully\n", zone_name2);
} else if (!zone_name2 && all) {
if (!(zone_list = zone_list_db_new_get(dbconn))) {
client_printf_err(sockfd, "Unable to get list of zones from database!\n");
free(buf);
return 1;
}
for (zone = zone_list_db_get_next(zone_list); zone; zone_db_free(zone), zone = zone_list_db_get_next(zone_list)) {
if (!delete_key_data(zone, dbconn, sockfd)) {
continue;
}
if (zone_db_delete(zone)) {
client_printf_err(sockfd, "Unable to delete zone %s from database!\n", zone_db_name(zone));
continue;
}
signconf_del = (char*) calloc(strlen(zone_db_signconf_path(zone)) +
strlen(".ZONE_DELETED") + 1, sizeof(char));
if (!signconf_del) {
ods_log_error("[%s] malloc failed", module_str);
zone_db_free(zone);
zone_list_db_free(zone_list);
free(buf);
return 1;
}
strncpy(signconf_del, zone_db_signconf_path(zone), strlen(zone_db_signconf_path(zone)));
strncat(signconf_del, ".ZONE_DELETED", strlen(".ZONE_DELETED"));
rename(zone_db_signconf_path(zone), signconf_del);
free(signconf_del);
signconf_del = NULL;
/* Delete all 'zone' related tasks */
schedule_purge_owner(engine->taskq, TASK_CLASS_ENFORCER, zone_db_name(zone));
ods_log_info("[%s] zone %s deleted", module_str, zone_db_name(zone));
client_printf(sockfd, "Deleted zone %s successfully\n", zone_db_name(zone));
}
zone_list_db_free(zone_list);
zone = NULL;
client_printf(sockfd, "All zones deleted successfully\n");
} else {
client_printf_err(sockfd, "expected either --zone <zone> or --all\n");
free(buf);
return -1;
}
free(buf);
if (write_xml) {
if (zone) {
if (zonelist_update_delete(sockfd, engine->config->zonelist_filename, zone, 1) != ZONELIST_UPDATE_OK) {
ods_log_error("[%s] zonelist %s updated failed", module_str, engine->config->zonelist_filename);
client_printf_err(sockfd, "Zonelist %s update failed!\n", engine->config->zonelist_filename);
ret = 1;
} else {
ods_log_info("[%s] zonelist %s updated successfully", module_str, engine->config->zonelist_filename);
client_printf(sockfd, "Zonelist %s updated successfully\n", engine->config->zonelist_filename);
}
} else {
if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
ret = 1;
} else {
ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
}
}
}
if (zone) {
if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
|| zonelist_update_delete(sockfd, path, zone, 0) != ZONELIST_UPDATE_OK)
{
ods_log_error("[%s] internal zonelist update failed", module_str);
client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
ret = 1;
} else {
ods_log_info("[%s] internal zonelist updated successfully", module_str);
}
} else {
if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
|| zonelist_export(sockfd, dbconn, path, 0) != ZONELIST_EXPORT_OK)
{
ods_log_error("[%s] internal zonelist update failed", module_str);
client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
ret = 1;
} else {
ods_log_info("[%s] internal zonelist updated successfully", module_str);
}
}
zone_db_free(zone);
return ret;
}
struct cmd_func_block zone_del_funcblock = {
"zone delete", &usage, &help, NULL, &run
};
key_data_role_text
const char * key_data_role_text(const key_data_t *key_data)
Definition: key_data.c:711
key_data_list
Definition: key_data.h:477
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
Definition: key_state.h:65
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
zone_db.h
key_state_delete
int key_state_delete(const key_state_t *key_state)
Definition: key_state.c:831
hsm_key_factory.h
zone_list_db_get_next
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
engine.h
ZONELIST_UPDATE_OK
#define ZONELIST_UPDATE_OK
Definition: zonelist_update.h:37
key_state_type_text
const char * key_state_type_text(const key_state_t *key_state)
Definition: key_state.c:353
NARGV
#define NARGV
engineconfig_struct::zonelist_filename
const char * zonelist_filename
Definition: cfg.h:57
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
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_data_id
const db_value_t * key_data_id(const key_data_t *key_data)
Definition: key_data.c:553
zonelist_export.h
zone_db_signconf_path
const char * zone_db_signconf_path(const zone_db_t *zone)
Definition: zone_db.c:798
getglobalcontext
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:102
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
getconnectioncontext
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
Definition: enforcercommands.c:108
ZONELIST_EXPORT_OK
#define ZONELIST_EXPORT_OK
Definition: zonelist_export.h:37
zone_list_db_free
void zone_list_db_free(zone_list_db_t *zone_list)
Definition: zone_db.c:1989
engine_struct::config
engineconfig_type * config
Definition: engine.h:48
zonelist_export
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
Definition: zonelist_export.c:47
key_state_free
void key_state_free(key_state_t *key_state)
Definition: key_state.c:214
zone_db
Definition: zone_db.h:46
zonelist_update.h
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
enforcercommands.h
zone_list_db
Definition: zone_db.h:466
key_state_list
Definition: key_state.h:262
zone_del_cmd.h
key_state_list_free
void key_state_list_free(key_state_list_t *key_state_list)
Definition: key_state.c:924
zone_del_funcblock
struct cmd_func_block zone_del_funcblock
Definition: zone_del_cmd.c:314
engineconfig_struct::working_dir
const char * working_dir
Definition: cfg.h:64
zone_db_delete
int zone_db_delete(zone_db_t *zone)
Definition: zone_db.c:1884
zone_list_db_new_get
zone_list_db_t * zone_list_db_new_get(const db_connection_t *connection)
Definition: zone_db.c:2402
key_data_list_free
void key_data_list_free(key_data_list_t *key_data_list)
Definition: key_data.c:1694
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
engine_struct
Definition: engine.h:47
key_data_free
void key_data_free(key_data_t *key_data)
Definition: key_data.c:304
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
engine_struct::taskq
schedule_type * taskq
Definition: engine.h:60
key_data
Definition: key_data.h:66
db_connection
Definition: db_connection.h:46
zone_db_id
const db_value_t * zone_db_id(const zone_db_t *zone)
Definition: zone_db.c:728
key_data_delete
int key_data_delete(key_data_t *key_data)
Definition: key_data.c:1587
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:694
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