OpenDNSSEC-enforcer  2.1.12
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 
46 static const char *module_str = "zone_set_policy_cmd";
47 
48 static void
49 usage(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 
61 static void
62 help(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 
73 static 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 
100 static int
101 run(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 
210 struct 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)
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
policy_t * policy_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: policy.c:2090
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 char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
int zone_db_set_policy_id(zone_db_t *zone, const db_value_t *policy_id)
Definition: zone_db.c:918
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
const db_value_t * zone_db_policy_id(const zone_db_t *zone)
Definition: zone_db.c:736
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