1 /* Copyright (C) 2019 OSSEC Foundation
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
10 #include "addagent/manage_agents.h"
12 #include <external/cJSON/cJSON.h>
16 #define ARGV0 "rootcheck_control"
19 static void helpmsg(void) __attribute__((noreturn));
24 printf("\nOSSEC HIDS %s: Manages the policy and auditing database.\n",
26 printf("Available options:\n");
27 printf("\t-h This help message.\n");
28 printf("\t-l List available (active or not) agents.\n");
29 printf("\t-lc List only active agents.\n");
30 printf("\t-u <id> Updates (clear) the database for the agent.\n");
31 printf("\t-u all Updates (clear) the database for all agents.\n");
32 printf("\t-i <id> Prints database for the agent.\n");
33 printf("\t-r Used with -i, prints all the resolved issues.\n");
34 printf("\t-q Used with -i, prints all the outstanding issues.\n");
35 printf("\t-L Used with -i, prints the last scan.\n");
36 printf("\t-s Changes the output to CSV (comma delimited).\n");
37 printf("\t-j Changes the output to JSON.\n");
41 int main(int argc, char **argv)
43 const char *dir = DEFAULTDIR;
44 const char *group = GROUPGLOBAL;
45 const char *user = USER;
46 const char *agent_id = NULL;
50 int c = 0, info_agent = 0, update_rootcheck = 0,
51 list_agents = 0, show_last = 0,
53 int active_only = 0, csv_output = 0, json_output = 0;
56 cJSON *json_root = NULL;
67 while ((c = getopt(argc, argv, "VhqrDdLlcsju:i:")) != -1) {
102 merror("%s: -u needs an argument", ARGV0);
109 merror("%s: -u needs an argument", ARGV0);
113 update_rootcheck = 1;
122 /* Get the group name */
123 gid = Privsep_GetGroup(group);
124 uid = Privsep_GetUser(user);
125 if (uid == (uid_t) - 1 || gid == (gid_t) - 1) {
126 ErrorExit(USER_ERROR, ARGV0, user, group);
130 if (Privsep_SetGroup(gid) < 0) {
131 ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
134 /* Chroot to the default directory */
135 if (Privsep_Chroot(dir) < 0) {
136 ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
139 /* Inside chroot now */
143 if (Privsep_SetUser(uid) < 0) {
144 ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
147 /* Get server hostname */
148 memset(shost, '\0', 512);
149 if (gethostname(shost, 512 - 1) != 0) {
150 strncpy(shost, "localhost", 32);
154 /* List available agents */
157 printf("\nOSSEC HIDS %s. List of available agents:",
159 printf("\n ID: 000, Name: %s (server), IP: 127.0.0.1, "
160 "Active/Local\n", shost);
162 printf("000,%s (server),127.0.0.1,Active/Local,\n", shost);
164 print_agents(1, active_only, csv_output, 0);
169 /* Update rootcheck database */
170 if (update_rootcheck) {
171 char json_buffer[1024];
173 /* Clean all agents (and server) db */
174 if (strcmp(agent_id, "all") == 0) {
176 struct dirent *entry;
178 sys_dir = opendir(ROOTCHECK_DIR);
181 cJSON_AddNumberToObject(json_root, "error", 11);
182 snprintf(json_buffer, 1023, "%s: Unable to open: '%s'", ARGV0, ROOTCHECK_DIR);
183 cJSON_AddStringToObject(json_root, "description", json_buffer);
184 printf("%s", cJSON_PrintUnformatted(json_root));
187 ErrorExit("%s: Unable to open: '%s'", ARGV0, ROOTCHECK_DIR);
191 while ((entry = readdir(sys_dir)) != NULL) {
193 char full_path[OS_MAXSTR + 1];
195 /* Do not even attempt to delete . and .. :) */
196 if ((strcmp(entry->d_name, ".") == 0) ||
197 (strcmp(entry->d_name, "..") == 0)) {
201 snprintf(full_path, OS_MAXSTR, "%s/%s", ROOTCHECK_DIR,
204 fp = fopen(full_path, "w");
208 if (entry->d_name[0] == '.') {
215 cJSON_AddNumberToObject(json_root, "error", 0);
216 cJSON_AddStringToObject(json_root, "response", "Policy and auditing database updated");
217 printf("%s", cJSON_PrintUnformatted(json_root));
219 printf("\n** Policy and auditing database updated.\n\n");
224 else if ((strcmp(agent_id, "000") == 0) ||
225 (strcmp(agent_id, "local") == 0)) {
226 char final_dir[1024];
228 snprintf(final_dir, 1020, "/%s/rootcheck", ROOTCHECK_DIR);
230 fp = fopen(final_dir, "w");
236 cJSON_AddNumberToObject(json_root, "error", 0);
237 cJSON_AddStringToObject(json_root, "response", "Policy and auditing database updated");
238 printf("%s", cJSON_PrintUnformatted(json_root));
240 printf("\n** Policy and auditing database updated.\n\n");
245 /* Database from remote agents */
252 i = OS_IsAllowedID(&keys, agent_id);
255 cJSON_AddNumberToObject(json_root, "error", 12);
256 snprintf(json_buffer, 1023, "Invalid agent id '%s'.", agent_id);
257 cJSON_AddStringToObject(json_root, "description", json_buffer);
258 printf("%s", cJSON_PrintUnformatted(json_root));
261 printf("\n** Invalid agent id '%s'.\n", agent_id);
267 /* Delete syscheck */
268 delete_rootcheck(keys.keyentries[i]->name,
269 keys.keyentries[i]->ip->ip, 0);
272 cJSON_AddNumberToObject(json_root, "error", 0);
273 cJSON_AddStringToObject(json_root, "response", "Policy and auditing database updated");
274 printf("%s", cJSON_PrintUnformatted(json_root));
276 printf("\n** Policy and auditing database updated.\n\n");
283 /* Print information from an agent */
286 char final_ip[IPSIZE + 4];
288 cJSON *json_events = NULL;
290 json_events = cJSON_CreateArray();
292 if ((strcmp(agent_id, "000") == 0) ||
293 (strcmp(agent_id, "local") == 0)) {
294 if (!(csv_output || json_output))
296 printf("\nPolicy and auditing events for local system '%s - %s':\n",
299 print_rootcheck(NULL, NULL, NULL, resolved_only, csv_output,
300 json_events, show_last);
303 cJSON_AddNumberToObject(json_root, "error", 0);
304 cJSON_AddItemToObject(json_root, "response", json_events);
305 printf("%s", cJSON_PrintUnformatted(json_root));
311 i = OS_IsAllowedID(&keys, agent_id);
314 char json_buffer[1024];
315 snprintf(json_buffer, 1023, "Invalid agent id '%s'", agent_id);
316 cJSON_AddNumberToObject(json_root, "error", 13);
317 cJSON_AddStringToObject(json_root, "description", json_buffer);
318 printf("%s", cJSON_PrintUnformatted(json_root));
321 printf("\n** Invalid agent id '%s'.\n", agent_id);
327 /* Getting full address/prefixlength from ip. */
328 final_ip[(sizeof final_ip) - 1] = '\0';
329 snprintf(final_ip, sizeof final_ip, "%s/%u",
330 keys.keyentries[i]->ip->ip,
331 keys.keyentries[i]->ip->prefixlength);
333 if (!(csv_output || json_output))
334 printf("\nPolicy and auditing events for agent "
336 keys.keyentries[i]->name, keys.keyentries[i]->id,
339 print_rootcheck(keys.keyentries[i]->name,
340 keys.keyentries[i]->ip->ip, NULL,
341 resolved_only, csv_output, json_events, show_last);
344 cJSON_AddNumberToObject(json_root, "error", 0);
345 cJSON_AddItemToObject(json_root, "response", json_events);
346 printf("%s", cJSON_PrintUnformatted(json_root));
356 cJSON_AddNumberToObject(json_root, "error", 10);
357 cJSON_AddStringToObject(json_root, "description", "Invalid argument combination");
358 printf("%s", cJSON_PrintUnformatted(json_root));
361 printf("\n** Invalid argument combination.\n");