Imported Upstream version 2.7
[ossec-hids.git] / src / util / syscheck_control.c
1 /* @(#) $Id: ./src/util/syscheck_control.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All right reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation
11  */
12
13
14 #include "addagent/manage_agents.h"
15 #include "sec.h"
16
17
18 #undef ARGV0
19 #define ARGV0 "syscheck_control"
20
21
22 /** help **/
23 void helpmsg()
24 {
25     printf("\nOSSEC HIDS %s: Manages the integrity checking database.\n",
26            ARGV0);
27     printf("Available options:\n");
28     printf("\t-h          This help message.\n");
29     printf("\t-l          List available (active or not) agents.\n");
30     printf("\t-lc         List only active agents.\n");
31     printf("\t-u <id>     Updates (clear) the database for the agent.\n");
32     printf("\t-u all      Updates (clear) the database for all agents.\n");
33     printf("\t-i <id>     List modified files for the agent.\n");
34     printf("\t-r -i <id>  List modified registry entries for the agent "
35            "(Windows only).\n");
36     printf("\t-f <file>   Prints information about a modified file.\n");
37     printf("\t-z          Used with the -f, zeroes the auto-ignore counter.\n");
38     printf("\t-d          Used with the -f, ignores that file.\n");
39     printf("\t-s          Changes the output to CSV (comma delimited).\n");
40     exit(1);
41 }
42
43
44 /** main **/
45 int main(int argc, char **argv)
46 {
47     char *dir = DEFAULTDIR;
48     char *group = GROUPGLOBAL;
49     char *user = USER;
50     char *agent_id = NULL;
51     char *fname = NULL;
52
53     int gid = 0;
54     int uid = 0;
55     int c = 0, info_agent = 0, update_syscheck = 0,
56                list_agents = 0, zero_counter = 0,
57                registry_only = 0;
58     int active_only = 0, csv_output = 0;
59
60     char shost[512];
61
62
63
64     /* Setting the name */
65     OS_SetName(ARGV0);
66
67
68     /* user arguments */
69     if(argc < 2)
70     {
71         helpmsg();
72     }
73
74
75     while((c = getopt(argc, argv, "VhzrDdlcsu:i:f:")) != -1)
76     {
77         switch(c){
78             case 'V':
79                 print_version();
80                 break;
81             case 'h':
82                 helpmsg();
83                 break;
84             case 'D':
85                 nowDebug();
86                 break;
87             case 'l':
88                 list_agents++;
89                 break;
90             case 'z':
91                 zero_counter = 1;
92                 break;
93             case 'd':
94                 zero_counter = 2;
95                 break;
96             case 's':
97                 csv_output = 1;
98             case 'c':
99                 active_only++;
100                 break;
101             case 'r':
102                 registry_only = 1;
103                 break;
104             case 'i':
105                 info_agent++;
106                 if(!optarg)
107                 {
108                     merror("%s: -u needs an argument",ARGV0);
109                     helpmsg();
110                 }
111                 agent_id = optarg;
112                 break;
113             case 'f':
114                 if(!optarg)
115                 {
116                     merror("%s: -u needs an argument",ARGV0);
117                     helpmsg();
118                 }
119                 fname = optarg;
120                 break;
121             case 'u':
122                 if(!optarg)
123                 {
124                     merror("%s: -u needs an argument",ARGV0);
125                     helpmsg();
126                 }
127                 agent_id = optarg;
128                 update_syscheck = 1;
129                 break;
130             default:
131                 helpmsg();
132                 break;
133         }
134
135     }
136
137
138     /* Getting the group name */
139     gid = Privsep_GetGroup(group);
140     uid = Privsep_GetUser(user);
141     if(gid < 0)
142     {
143             ErrorExit(USER_ERROR, ARGV0, user, group);
144     }
145         
146
147     /* Setting the group */
148     if(Privsep_SetGroup(gid) < 0)
149     {
150             ErrorExit(SETGID_ERROR,ARGV0, group);
151     }
152
153
154     /* Chrooting to the default directory */
155     if(Privsep_Chroot(dir) < 0)
156     {
157         ErrorExit(CHROOT_ERROR, ARGV0, dir);
158     }
159
160
161     /* Inside chroot now */
162     nowChroot();
163
164
165     /* Setting the user */
166     if(Privsep_SetUser(uid) < 0)
167     {
168         ErrorExit(SETUID_ERROR, ARGV0, user);
169     }
170
171
172
173     /* Getting servers hostname */
174     memset(shost, '\0', 512);
175     if(gethostname(shost, 512 -1) != 0)
176     {
177         strncpy(shost, "localhost", 32);
178         return(0);
179     }
180
181
182
183     /* Listing available agents. */
184     if(list_agents)
185     {
186         if(!csv_output)
187         {
188             printf("\nOSSEC HIDS %s. List of available agents:",
189                     ARGV0);
190             printf("\n   ID: 000, Name: %s (server), IP: 127.0.0.1, "
191                    "Active/Local\n", shost);
192         }
193         else
194         {
195             printf("000,%s (server),127.0.0.1,Active/Local,\n", shost);
196         }
197         print_agents(1, active_only, csv_output);
198         printf("\n");
199         exit(0);
200     }
201
202
203
204     /* Update syscheck database. */
205     if(update_syscheck)
206     {
207         /* Cleaning all agents (and server) db. */
208         if(strcmp(agent_id, "all") == 0)
209         {
210             DIR *sys_dir;
211             struct dirent *entry;
212
213             sys_dir = opendir(SYSCHECK_DIR);
214             if(!sys_dir)
215             {
216                 ErrorExit("%s: Unable to open: '%s'", ARGV0, SYSCHECK_DIR);
217             }
218
219             while((entry = readdir(sys_dir)) != NULL)
220             {
221                 FILE *fp;
222                 char full_path[OS_MAXSTR +1];
223
224                 /* Do not even attempt to delete . and .. :) */
225                 if((strcmp(entry->d_name,".") == 0)||
226                    (strcmp(entry->d_name,"..") == 0))
227                 {
228                     continue;
229                 }
230
231                 snprintf(full_path, OS_MAXSTR,"%s/%s", SYSCHECK_DIR,
232                          entry->d_name);
233
234                 fp = fopen(full_path, "w");
235                 if(fp)
236                 {
237                     fclose(fp);
238                 }
239                 if(entry->d_name[0] == '.')
240                 {
241                     unlink(full_path);
242                 }
243             }
244
245             closedir(sys_dir);
246             printf("\n** Integrity check database updated.\n\n");
247             exit(0);
248         }
249
250         else if((strcmp(agent_id, "000") == 0) ||
251                 (strcmp(agent_id, "local") == 0))
252         {
253             char final_dir[1024];
254             FILE *fp;
255             snprintf(final_dir, 1020, "/%s/syscheck", SYSCHECK_DIR);
256
257             fp = fopen(final_dir, "w");
258             if(fp)
259             {
260                 fclose(fp);
261             }
262             unlink(final_dir);
263
264
265             /* Deleting cpt file */
266             snprintf(final_dir, 1020, "/%s/.syscheck.cpt", SYSCHECK_DIR);
267
268             fp = fopen(final_dir, "w");
269             if(fp)
270             {
271                 fclose(fp);
272             }
273             unlink(final_dir);
274
275             printf("\n** Integrity check database updated.\n\n");
276             exit(0);
277         }
278
279         /* Database from remote agents. */
280         else
281         {
282             int i;
283             keystore keys;
284
285             OS_ReadKeys(&keys);
286
287             i = OS_IsAllowedID(&keys, agent_id);
288             if(i < 0)
289             {
290                 printf("\n** Invalid agent id '%s'.\n", agent_id);
291                 helpmsg();
292             }
293
294             /* Deleting syscheck */
295             delete_syscheck(keys.keyentries[i]->name,
296                             keys.keyentries[i]->ip->ip, 0);
297
298             printf("\n** Integrity check database updated.\n\n");
299             exit(0);
300         }
301     }
302
303
304     /* Printing information from an agent. */
305     if(info_agent)
306     {
307         int i;
308         char final_ip[128 +1];
309         char final_mask[128 +1];
310         keystore keys;
311
312
313         if((strcmp(agent_id, "000") == 0) ||
314            (strcmp(agent_id, "local") == 0))
315         {
316             printf("\nIntegrity checking changes for local system '%s - %s':\n",
317                     shost, "127.0.0.1");
318             if(fname)
319             {
320                 printf("Detailed information for entries matching: '%s'\n",
321                        fname);
322             }
323
324             print_syscheck(NULL,
325                            NULL, fname, 0, 0,
326                            csv_output, zero_counter);
327         }
328         else if(strchr(agent_id, '@'))
329         {
330             if(fname)
331             {
332                 printf("Detailed information for entries matching: '%s'\n",
333                        fname);
334             }
335             print_syscheck(agent_id, NULL, fname, registry_only, 0,
336                            csv_output, zero_counter);
337         }
338         else
339         {
340
341             OS_ReadKeys(&keys);
342
343             i = OS_IsAllowedID(&keys, agent_id);
344             if(i < 0)
345             {
346                 printf("\n** Invalid agent id '%s'.\n", agent_id);
347                 helpmsg();
348             }
349
350             /* Getting netmask from ip. */
351             final_ip[128] = '\0';
352             final_mask[128] = '\0';
353             getNetmask(keys.keyentries[i]->ip->netmask, final_mask, 128);
354             snprintf(final_ip, 128, "%s%s",keys.keyentries[i]->ip->ip,
355                     final_mask);
356
357             if(registry_only)
358             {
359                 printf("\nIntegrity changes for 'Windows Registry' of"
360                        " agent '%s (%s) - %s':\n",
361                        keys.keyentries[i]->name, keys.keyentries[i]->id,
362                        final_ip);
363             }
364             else
365             {
366                 printf("\nIntegrity changes for agent "
367                        "'%s (%s) - %s':\n",
368                        keys.keyentries[i]->name, keys.keyentries[i]->id,
369                        final_ip);
370             }
371
372             if(fname)
373             {
374                 printf("Detailed information for entries matching: '%s'\n",
375                        fname);
376             }
377             print_syscheck(keys.keyentries[i]->name,
378                     keys.keyentries[i]->ip->ip, fname,
379                     registry_only, 0, csv_output, zero_counter);
380
381         }
382
383         exit(0);
384     }
385
386
387
388     printf("\n** Invalid argument combination.\n");
389     helpmsg();
390
391
392     return(0);
393 }
394
395
396 /* EOF */