1 /*
2  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
3  * Copyright (c) 2014 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 "cmdhandler.h"
32 #include "daemon/enforcercommands.h"
33 #include "daemon/engine.h"
34 #include "file.h"
35 #include "log.h"
36 #include "str.h"
37 #include "duration.h"
38 #include "clientpipe.h"
39 #include "db/zone_db.h"
40 #include "db/policy.h"
41 #include "db/db_value.h"
42 
43 #include "keystate/zone_list_cmd.h"
44 
45 static const char *module_str = "zone_list_cmd";
46 
47 static void
usage(int sockfd)48 usage(int sockfd)
49 {
50 	client_printf(sockfd,
51 		"zone list\n");
52 }
53 
54 static void
help(int sockfd)55 help(int sockfd)
56 {
57     client_printf(sockfd,
58         "List all zones currently in the database.\n\n"
59     );
60 }
61 
62 static int
run(int sockfd,cmdhandler_ctx_type * context,const char * cmd)63 run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
64 {
65     const char* fmt = "%-31s %-13s %-26s %-34s\n";
66     zone_list_db_t* zone_list;
67     const zone_db_t* zone;
68     policy_t* policy = NULL;
69     const char* nctime;
70     char buf[32];
71     int cmp;
72     db_connection_t* dbconn = getconnectioncontext(context);
73     engine_type* engine = getglobalcontext(context);
74     (void)cmd;
75 
76 	ods_log_debug("[%s] %s command", module_str, zone_list_funcblock.cmdname);
77 
78 	if (!(zone_list = zone_list_db_new_get(dbconn))) {
79 	    client_printf_err(sockfd, "Unable to get list of zones, memory allocation or database error!\n");
80 	    return 1;
81 	}
82 
83     client_printf(sockfd, "Database set to: %s\n", engine->config->datastore);
84     if (!(zone = zone_list_db_next(zone_list))) {
85         client_printf(sockfd, "No zones in database.\n");
86         zone_list_db_free(zone_list);
87         return 0;
88     }
89 
90     client_printf(sockfd, "Zones:\n");
91     client_printf(sockfd, fmt, "Zone:", "Policy:", "Next change:",
92         "Signer Configuration:");
93     while (zone) {
94         if (zone_db_next_change(zone) >= time_now()) {
95             if (!ods_ctime_r(buf, sizeof(buf), zone_db_next_change(zone))) {
96                 nctime = "invalid date/time";
97             }
98             else {
99                 nctime = buf;
100             }
101         } else if (zone_db_next_change(zone) >= 0) {
102             nctime = "as soon as possible";
103         } else {
104             nctime = "no changes scheduled";
105         }
106 
107         if (policy) {
108             /*
109              * If we already have a policy object; If policy_id compare fails
110              * or if they are not the same free the policy object to we will
111              * later retrieve the correct policy
112              */
113             if (db_value_cmp(policy_id(policy), zone_db_policy_id(zone), &cmp)
114                 || cmp)
115             {
116                 policy_free(policy);
117                 policy = NULL;
118             }
119         }
120         if (!policy) {
121             policy = zone_db_get_policy(zone);
122         }
123 
124         client_printf(sockfd, fmt,
125             zone_db_name(zone),
126             (policy ? policy_name(policy) : "NOT_FOUND"),
127             nctime,
128             zone_db_signconf_path(zone));
129 
130         zone = zone_list_db_next(zone_list);
131     }
132     policy_free(policy);
133     zone_list_db_free(zone_list);
134 
135     return 0;
136 }
137 
138 struct cmd_func_block zone_list_funcblock = {
139 	"zone list", &usage, &help, NULL, &run
140 };
141