zone_set_policy_cmd.c
Go to the documentation of this file.
/*
* Copyright (c) 2017 .SE (The Internet Infrastructure Foundation).
* Copyright (c) 2017 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 "daemon/engine.h"
#include "cmdhandler.h"
#include "daemon/enforcercommands.h"
#include "file.h"
#include "str.h"
#include "log.h"
#include "clientpipe.h"
#include "longgetopt.h"
#include "db/zone_db.h"
#include "keystate/zonelist_export.h"
#include "keystate/zone_set_policy_cmd.h"
#include <limits.h>
#include <getopt.h>
static const char *module_str = "zone_set_policy_cmd";
static void
usage(int sockfd)
{
client_printf(sockfd,
"zone set-policy\n"
" --zone <zone> aka -z\n"
" --policy <policy> aka -p\n"
);
client_printf(sockfd,
" [--xml] aka -u\n"
);
}
static void
help(int sockfd)
{
client_printf(sockfd,
"Change the policy of an existing zone in the enforcer database.\n"
"\nOptions:\n"
"zone name of the zone\n"
"policy name of the new policy\n"
"xml update the zonelist.xml file\n\n"
);
}
static int set_zone_policy(int sockfd, db_connection_t* dbconn, zone_db_t* zone, policy_t* policy) {
const db_value_t* wanted_policy_id = policy_id(policy);
int cmp;
if (db_value_cmp(zone_db_policy_id(zone), wanted_policy_id, &cmp)) {
client_printf_err(sockfd, "Unable to update zone, database error!\n");
return 1;
}
if (!cmp) {
client_printf_err(sockfd, "Policy same as before, not updating.\n");
return 0;
}
if (zone_db_set_policy_id(zone, wanted_policy_id)) {
client_printf_err(sockfd, "Unable to update zone, database error!\n");
return 1;
}
if (zone_db_update(zone)) {
client_printf(sockfd, "Failed to update zone in database.\n");
return 1;
}
ods_log_info("[%s] zone %s policy updated to %s", module_str, zone_db_name(zone), policy_name(policy));
client_printf(sockfd, "Zone %s policy successfully set to %s\n", zone_db_name(zone), policy_name(policy));
return 0;
}
static int
run(cmdhandler_ctx_type* context, int argc, char* argv[])
{
int sockfd = context->sockfd;
struct longgetopt optctx;
const char *zone_name = NULL;
char *policy_name = NULL;
int write_xml = 0;
int long_index = 0, opt = 0;
int ret = 0;
char path[PATH_MAX];
db_connection_t* dbconn = getconnectioncontext(context);
engine_type* engine = getglobalcontext(context);
static struct option long_options[] = {
{"zone", required_argument, 0, 'z'},
{"policy", required_argument, 0, 'p'},
{"xml", no_argument, 0, 'u'},
{0, 0, 0, 0}
};
for(opt = longgetopt(argc, argv, "z:p:u", long_options, &long_index, &optctx); opt != -1;
opt = longgetopt(argc, argv, NULL, long_options, &long_index, &optctx)) {
switch (opt) {
case 'z':
zone_name = optctx.optarg;
break;
case 'p':
policy_name = strdup(optctx.optarg);
break;
case 'u':
write_xml = 1;
break;
default:
client_printf_err(sockfd, "unknown arguments\n");
ods_log_error("[%s] unknown arguments for zone set-policy command", module_str);
return -1;
}
}
if (!zone_name) {
client_printf_err(sockfd, "expected option --zone <zone>\n");
if (policy_name) {
free(policy_name);
}
return -1;
} else if (!policy_name) {
client_printf_err(sockfd, "expected option --policy <policy>\n");
return -1;
}
//validation
zone_db_t* zone = zone_db_new_get_by_name(dbconn, zone_name);
if (!zone) {
client_printf_err(sockfd, "Unable to update zone, zone does not exist!\n");
free(policy_name);
return 1;
}
policy_t* policy = policy_new_get_by_name(dbconn, policy_name);
free(policy_name);
if (!policy) {
client_printf_err(sockfd, "Unable to update zone, policy does not exist!\n");
zone_db_free(zone);
return 1;
}
/* input looks okay, lets update the database */
ret = set_zone_policy(sockfd, dbconn, zone, policy);
zone_db_free(zone);
policy_free(policy);
if (write_xml) {
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 (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);
}
return ret;
}
struct cmd_func_block zone_set_policy_funcblock = {
"zone set-policy", &usage, &help, NULL, NULL, &run, NULL
};
db_connection_t
struct db_connection db_connection_t
Definition db_connection.h:34
db_value_cmp
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition db_value.c:102
db_value_t
struct db_value db_value_t
Definition db_value.h:35
getconnectioncontext
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
Definition enforcercommands.c:107
getglobalcontext
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
Definition enforcercommands.c:101
enforcercommands.h
engine.h
engine_type
struct engine_struct engine_type
Definition engine.h:38
policy_new_get_by_name
policy_t * policy_new_get_by_name(const db_connection_t *connection, const char *name)
Definition policy.c:2090
policy_name
const char * policy_name(const policy_t *policy)
Definition policy.c:813
policy_id
const db_value_t * policy_id(const policy_t *policy)
Definition policy.c:805
policy_free
void policy_free(policy_t *policy)
Definition policy.c:518
policy_t
struct policy policy_t
Definition policy.h:37
policy
Definition policy.h:60
zone_db_free
void zone_db_free(zone_db_t *zone)
Definition zone_db.c:325
zone_db_policy_id
const db_value_t * zone_db_policy_id(const zone_db_t *zone)
Definition zone_db.c:736
zone_db_set_policy_id
int zone_db_set_policy_id(zone_db_t *zone, const db_value_t *policy_id)
Definition zone_db.c:918
zone_db_name
const char * zone_db_name(const zone_db_t *zone)
Definition zone_db.c:782
zone_db_update
int zone_db_update(zone_db_t *zone)
Definition zone_db.c:1589
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
zone_db.h
zone_db_t
struct zone_db zone_db_t
Definition zone_db.h:37
zone_set_policy_funcblock
struct cmd_func_block zone_set_policy_funcblock
Definition zone_set_policy_cmd.c:199
zone_set_policy_cmd.h
zonelist_export
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
Definition zonelist_export.c:47
zonelist_export.h
ZONELIST_EXPORT_OK
#define ZONELIST_EXPORT_OK
Definition zonelist_export.h:37