OpenDNSSEC-enforcer 2.1.13
zone_set_policy_cmd.c
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2017 .SE (The Internet Infrastructure Foundation).
3 * Copyright (c) 2017 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/engine.h"
32#include "cmdhandler.h"
34#include "file.h"
35#include "str.h"
36#include "log.h"
37#include "clientpipe.h"
38#include "longgetopt.h"
39#include "db/zone_db.h"
41
43
44#include <limits.h>
45#include <getopt.h>
46
47static const char *module_str = "zone_set_policy_cmd";
48
49static void
50usage(int sockfd)
51{
52 client_printf(sockfd,
53 "zone set-policy\n"
54 " --zone <zone> aka -z\n"
55 " --policy <policy> aka -p\n"
56 );
57 client_printf(sockfd,
58 " [--xml] aka -u\n"
59 );
60}
61
62static void
63help(int sockfd)
64{
65 client_printf(sockfd,
66 "Change the policy of an existing zone in the enforcer database.\n"
67 "\nOptions:\n"
68 "zone name of the zone\n"
69 "policy name of the new policy\n"
70 "xml update the zonelist.xml file\n\n"
71 );
72}
73
74static int set_zone_policy(int sockfd, db_connection_t* dbconn, zone_db_t* zone, policy_t* policy) {
75 const db_value_t* wanted_policy_id = policy_id(policy);
76 int cmp;
77
78 if (db_value_cmp(zone_db_policy_id(zone), wanted_policy_id, &cmp)) {
79 client_printf_err(sockfd, "Unable to update zone, database error!\n");
80 return 1;
81 }
82 if (!cmp) {
83 client_printf_err(sockfd, "Policy same as before, not updating.\n");
84 return 0;
85 }
86
87 if (zone_db_set_policy_id(zone, wanted_policy_id)) {
88 client_printf_err(sockfd, "Unable to update zone, database error!\n");
89 return 1;
90 }
91
92 if (zone_db_update(zone)) {
93 client_printf(sockfd, "Failed to update zone in database.\n");
94 return 1;
95 }
96 ods_log_info("[%s] zone %s policy updated to %s", module_str, zone_db_name(zone), policy_name(policy));
97 client_printf(sockfd, "Zone %s policy successfully set to %s\n", zone_db_name(zone), policy_name(policy));
98 return 0;
99}
100
101static int
102run(cmdhandler_ctx_type* context, int argc, char* argv[])
103{
104 int sockfd = context->sockfd;
105 struct longgetopt optctx;
106 const char *zone_name = NULL;
107 char *policy_name = NULL;
108 int write_xml = 0;
109 int long_index = 0, opt = 0;
110 int ret = 0;
111 char path[PATH_MAX];
112 db_connection_t* dbconn = getconnectioncontext(context);
113 engine_type* engine = getglobalcontext(context);
114
115 static struct option long_options[] = {
116 {"zone", required_argument, 0, 'z'},
117 {"policy", required_argument, 0, 'p'},
118 {"xml", no_argument, 0, 'u'},
119 {0, 0, 0, 0}
120 };
121
122 for(opt = longgetopt(argc, argv, "z:p:u", long_options, &long_index, &optctx); opt != -1;
123 opt = longgetopt(argc, argv, NULL, long_options, &long_index, &optctx)) {
124 switch (opt) {
125 case 'z':
126 zone_name = optctx.optarg;
127 break;
128 case 'p':
129 policy_name = strdup(optctx.optarg);
130 break;
131 case 'u':
132 write_xml = 1;
133 break;
134 default:
135 client_printf_err(sockfd, "unknown arguments\n");
136 ods_log_error("[%s] unknown arguments for zone set-policy command", module_str);
137 return -1;
138 }
139 }
140
141 if (!zone_name) {
142 client_printf_err(sockfd, "expected option --zone <zone>\n");
143 if (policy_name) {
144 free(policy_name);
145 }
146 return -1;
147 } else if (!policy_name) {
148 client_printf_err(sockfd, "expected option --policy <policy>\n");
149 return -1;
150 }
151
152 //validation
153
154 zone_db_t* zone = zone_db_new_get_by_name(dbconn, zone_name);
155 if (!zone) {
156 client_printf_err(sockfd, "Unable to update zone, zone does not exist!\n");
157 free(policy_name);
158 return 1;
159 }
160
162 free(policy_name);
163 if (!policy) {
164 client_printf_err(sockfd, "Unable to update zone, policy does not exist!\n");
165 zone_db_free(zone);
166 return 1;
167 }
168
169 /* input looks okay, lets update the database */
170 ret = set_zone_policy(sockfd, dbconn, zone, policy);
171
172 zone_db_free(zone);
174
175 if (write_xml) {
176 if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
177 ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
178 client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
179 ret = 1;
180 } else {
181 ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
182 client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
183 }
184 }
185
186 if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
187 || zonelist_export(sockfd, dbconn, path, 0) != ZONELIST_EXPORT_OK)
188 {
189 ods_log_error("[%s] internal zonelist update failed", module_str);
190 client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
191 ret = 1;
192 } else {
193 ods_log_info("[%s] internal zonelist updated successfully", module_str);
194 }
195
196 return ret;
197}
198
199struct cmd_func_block zone_set_policy_funcblock = {
200 "zone set-policy", &usage, &help, NULL, NULL, &run, NULL
201};
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition: db_value.c:102
db_connection_t * getconnectioncontext(cmdhandler_ctx_type *context)
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
policy_t * policy_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: policy.c:2090
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
const db_value_t * policy_id(const policy_t *policy)
Definition: policy.c:805
void policy_free(policy_t *policy)
Definition: policy.c:518
engineconfig_type * config
Definition: engine.h:48
const char * working_dir
Definition: cfg.h:64
const char * zonelist_filename
Definition: cfg.h:57
Definition: policy.h:60
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
const db_value_t * zone_db_policy_id(const zone_db_t *zone)
Definition: zone_db.c:736
int zone_db_set_policy_id(zone_db_t *zone, const db_value_t *policy_id)
Definition: zone_db.c:918
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone_db.c:1569
struct cmd_func_block zone_set_policy_funcblock
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
#define ZONELIST_EXPORT_OK