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