OpenDNSSEC-enforcer 2.1.10
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 "db/zone_db.h"
40
42
43#include <limits.h>
44#include <getopt.h>
45
46static const char *module_str = "zone_set_policy_cmd";
47
48static void
49usage(int sockfd)
50{
51 client_printf(sockfd,
52 "zone set-policy\n"
53 " --zone <zone> aka -z\n"
54 " --policy <policy> aka -p\n"
55 );
56 client_printf(sockfd,
57 " [--xml] aka -u\n"
58 );
59}
60
61static void
62help(int sockfd)
63{
64 client_printf(sockfd,
65 "Change the policy of an existing zone in the enforcer database.\n"
66 "\nOptions:\n"
67 "zone name of the zone\n"
68 "policy name of the new policy\n"
69 "xml update the zonelist.xml file\n\n"
70 );
71}
72
73static int set_zone_policy(int sockfd, db_connection_t* dbconn, zone_db_t* zone, policy_t* policy) {
74 const db_value_t* wanted_policy_id = policy_id(policy);
75 int cmp;
76
77 if (db_value_cmp(zone_db_policy_id(zone), wanted_policy_id, &cmp)) {
78 client_printf_err(sockfd, "Unable to update zone, database error!\n");
79 return 1;
80 }
81 if (!cmp) {
82 client_printf_err(sockfd, "Policy same as before, not updating.\n");
83 return 0;
84 }
85
86 if (zone_db_set_policy_id(zone, wanted_policy_id)) {
87 client_printf_err(sockfd, "Unable to update zone, database error!\n");
88 return 1;
89 }
90
91 if (zone_db_update(zone)) {
92 client_printf(sockfd, "Failed to update zone in database.\n");
93 return 1;
94 }
95 ods_log_info("[%s] zone %s policy updated to %s", module_str, zone_db_name(zone), policy_name(policy));
96 client_printf(sockfd, "Zone %s policy successfully set to %s\n", zone_db_name(zone), policy_name(policy));
97 return 0;
98}
99
100static int
101run(int sockfd, cmdhandler_ctx_type* context, char *cmd)
102{
103 #define NARGV 18
104 const char* argv[NARGV];
105 int argc = 0;
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 ods_log_debug("[%s] %s command", module_str, zone_set_policy_funcblock.cmdname);
123
124 argc = ods_str_explode(cmd, NARGV, argv);
125 if (argc == -1) {
126 client_printf_err(sockfd, "too many arguments\n");
127 ods_log_error("[%s] too many arguments for %s command",
128 module_str, zone_set_policy_funcblock.cmdname);
129 return -1;
130 }
131
132 optind = 0;
133 while ((opt = getopt_long(argc, (char* const*)argv, "z:p:u", long_options, &long_index)) != -1) {
134 switch (opt) {
135 case 'z':
136 zone_name = optarg;
137 break;
138 case 'p':
139 policy_name = strdup(optarg);
140 break;
141 case 'u':
142 write_xml = 1;
143 break;
144 default:
145 client_printf_err(sockfd, "unknown arguments\n");
146 ods_log_error("[%s] unknown arguments for %s command",
147 module_str, zone_set_policy_funcblock.cmdname);
148 return -1;
149 }
150 }
151
152 if (!zone_name) {
153 client_printf_err(sockfd, "expected option --zone <zone>\n");
154 if (policy_name) {
155 free(policy_name);
156 }
157 return -1;
158 } else if (!policy_name) {
159 client_printf_err(sockfd, "expected option --policy <policy>\n");
160 return -1;
161 }
162
163 //validation
164
165 zone_db_t* zone = zone_db_new_get_by_name(dbconn, zone_name);
166 if (!zone) {
167 client_printf_err(sockfd, "Unable to update zone, zone does not exist!\n");
168 free(policy_name);
169 return 1;
170 }
171
173 free(policy_name);
174 if (!policy) {
175 client_printf_err(sockfd, "Unable to update zone, policy does not exist!\n");
176 zone_db_free(zone);
177 return 1;
178 }
179
180 /* input looks okay, lets update the database */
181 ret = set_zone_policy(sockfd, dbconn, zone, policy);
182
183 zone_db_free(zone);
185
186 if (write_xml) {
187 if (zonelist_export(sockfd, dbconn, engine->config->zonelist_filename, 1) != ZONELIST_EXPORT_OK) {
188 ods_log_error("[%s] zonelist exported to %s failed", module_str, engine->config->zonelist_filename);
189 client_printf_err(sockfd, "Exported zonelist to %s failed!\n", engine->config->zonelist_filename);
190 ret = 1;
191 } else {
192 ods_log_info("[%s] zonelist exported to %s successfully", module_str, engine->config->zonelist_filename);
193 client_printf(sockfd, "Exported zonelist to %s successfully\n", engine->config->zonelist_filename);
194 }
195 }
196
197 if (snprintf(path, sizeof(path), "%s/%s", engine->config->working_dir, OPENDNSSEC_ENFORCER_ZONELIST) >= (int)sizeof(path)
198 || zonelist_export(sockfd, dbconn, path, 0) != ZONELIST_EXPORT_OK)
199 {
200 ods_log_error("[%s] internal zonelist update failed", module_str);
201 client_printf_err(sockfd, "Unable to update the internal zonelist %s, updates will not reach the Signer!\n", path);
202 ret = 1;
203 } else {
204 ods_log_info("[%s] internal zonelist updated successfully", module_str);
205 }
206
207 return ret;
208}
209
210struct cmd_func_block zone_set_policy_funcblock = {
211 "zone set-policy", &usage, &help, NULL, &run
212};
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
#define NARGV
int zonelist_export(int sockfd, db_connection_t *connection, const char *filename, int comment)
#define ZONELIST_EXPORT_OK