71c705b0189a1d565c3c32f459a04b8822797c96
[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                 break;
99             case 'c':
100                 active_only++;
101                 break;
102             case 'r':
103                 registry_only = 1;
104                 break;
105             case 'i':
106                 info_agent++;
107                 if(!optarg)
108                 {
109                     merror("%s: -u needs an argument",ARGV0);
110                     helpmsg();
111                 }
112                 agent_id = optarg;
113                 break;
114             case 'f':
115                 if(!optarg)
116                 {
117                     merror("%s: -u needs an argument",ARGV0);
118                     helpmsg();
119                 }
120                 fname = optarg;
121                 break;
122             case 'u':
123                 if(!optarg)
124                 {
125                     merror("%s: -u needs an argument",ARGV0);
126                     helpmsg();
127                 }
128                 agent_id = optarg;
129                 update_syscheck = 1;
130                 break;
131             default:
132                 helpmsg();
133                 break;
134         }
135
136     }
137
138
139     /* Getting the group name */
140     gid = Privsep_GetGroup(group);
141     uid = Privsep_GetUser(user);
142     if(gid < 0)
143     {
144             ErrorExit(USER_ERROR, ARGV0, user, group);
145     }
146
147
148     /* Setting the group */
149     if(Privsep_SetGroup(gid) < 0)
150     {
151             ErrorExit(SETGID_ERROR,ARGV0, group);
152     }
153
154
155     /* Chrooting to the default directory */
156     if(Privsep_Chroot(dir) < 0)
157     {
158         ErrorExit(CHROOT_ERROR, ARGV0, dir);
159     }
160
161
162     /* Inside chroot now */
163     nowChroot();
164
165
166     /* Setting the user */
167     if(Privsep_SetUser(uid) < 0)
168     {
169         ErrorExit(SETUID_ERROR, ARGV0, user);
170     }
171
172
173
174     /* Getting servers hostname */
175     memset(shost, '\0', 512);
176     if(gethostname(shost, 512 -1) != 0)
177     {
178         strncpy(shost, "localhost", 32);
179         return(0);
180     }
181
182
183
184     /* Listing available agents. */
185     if(list_agents)
186     {
187         if(!csv_output)
188         {
189             printf("\nOSSEC HIDS %s. List of available agents:",
190                     ARGV0);
191             printf("\n   ID: 000, Name: %s (server), IP: 127.0.0.1, "
192                    "Active/Local\n", shost);
193         }
194         else
195         {
196             printf("000,%s (server),127.0.0.1,Active/Local,\n", shost);
197         }
198         print_agents(1, active_only, csv_output);
199         printf("\n");
200         exit(0);
201     }
202
203
204
205     /* Update syscheck database. */
206     if(update_syscheck)
207     {
208         /* Cleaning all agents (and server) db. */
209         if(strcmp(agent_id, "all") == 0)
210         {
211             DIR *sys_dir;
212             struct dirent *entry;
213
214             sys_dir = opendir(SYSCHECK_DIR);
215             if(!sys_dir)
216             {
217                 ErrorExit("%s: Unable to open: '%s'", ARGV0, SYSCHECK_DIR);
218             }
219
220             while((entry = readdir(sys_dir)) != NULL)
221             {
222                 FILE *fp;
223                 char full_path[OS_MAXSTR +1];
224
225                 /* Do not even attempt to delete . and .. :) */
226                 if((strcmp(entry->d_name,".") == 0)||
227                    (strcmp(entry->d_name,"..") == 0))
228                 {
229                     continue;
230                 }
231
232                 snprintf(full_path, OS_MAXSTR,"%s/%s", SYSCHECK_DIR,
233                          entry->d_name);
234
235                 fp = fopen(full_path, "w");
236                 if(fp)
237                 {
238                     fclose(fp);
239                 }
240                 if(entry->d_name[0] == '.')
241                 {
242                     unlink(full_path);
243                 }
244             }
245
246             closedir(sys_dir);
247             printf("\n** Integrity check database updated.\n\n");
248             exit(0);
249         }
250
251         else if((strcmp(agent_id, "000") == 0) ||
252                 (strcmp(agent_id, "local") == 0))
253         {
254             char final_dir[1024];
255             FILE *fp;
256             snprintf(final_dir, 1020, "/%s/syscheck", SYSCHECK_DIR);
257
258             fp = fopen(final_dir, "w");
259             if(fp)
260             {
261                 fclose(fp);
262             }
263             unlink(final_dir);
264
265
266             /* Deleting cpt file */
267             snprintf(final_dir, 1020, "/%s/.syscheck.cpt", SYSCHECK_DIR);
268
269             fp = fopen(final_dir, "w");
270             if(fp)
271             {
272                 fclose(fp);
273             }
274             unlink(final_dir);
275
276             printf("\n** Integrity check database updated.\n\n");
277             exit(0);
278         }
279
280         /* Database from remote agents. */
281         else
282         {
283             int i;
284             keystore keys;
285
286             OS_ReadKeys(&keys);
287
288             i = OS_IsAllowedID(&keys, agent_id);
289             if(i < 0)
290             {
291                 printf("\n** Invalid agent id '%s'.\n", agent_id);
292                 helpmsg();
293             }
294
295             /* Deleting syscheck */
296             delete_syscheck(keys.keyentries[i]->name,
297                             keys.keyentries[i]->ip->ip, 0);
298
299             printf("\n** Integrity check database updated.\n\n");
300             exit(0);
301         }
302     }
303
304
305     /* Printing information from an agent. */
306     if(info_agent)
307     {
308         int i;
309         char final_ip[128 +1];
310         char final_mask[128 +1];
311         keystore keys;
312
313
314         if((strcmp(agent_id, "000") == 0) ||
315            (strcmp(agent_id, "local") == 0))
316         {
317             printf("\nIntegrity checking changes for local system '%s - %s':\n",
318                     shost, "127.0.0.1");
319             if(fname)
320             {
321                 printf("Detailed information for entries matching: '%s'\n",
322                        fname);
323             }
324
325             print_syscheck(NULL,
326                            NULL, fname, 0, 0,
327                            csv_output, zero_counter);
328         }
329         else if(strchr(agent_id, '@'))
330         {
331             if(fname)
332             {
333                 printf("Detailed information for entries matching: '%s'\n",
334                        fname);
335             }
336             print_syscheck(agent_id, NULL, fname, registry_only, 0,
337                            csv_output, zero_counter);
338         }
339         else
340         {
341
342             OS_ReadKeys(&keys);
343
344             i = OS_IsAllowedID(&keys, agent_id);
345             if(i < 0)
346             {
347                 printf("\n** Invalid agent id '%s'.\n", agent_id);
348                 helpmsg();
349             }
350
351             /* Getting netmask from ip. */
352             final_ip[128] = '\0';
353             final_mask[128] = '\0';
354             getNetmask(keys.keyentries[i]->ip->netmask, final_mask, 128);
355             snprintf(final_ip, 128, "%s%s",keys.keyentries[i]->ip->ip,
356                     final_mask);
357
358             if(registry_only)
359             {
360                 printf("\nIntegrity changes for 'Windows Registry' of"
361                        " agent '%s (%s) - %s':\n",
362                        keys.keyentries[i]->name, keys.keyentries[i]->id,
363                        final_ip);
364             }
365             else
366             {
367                 printf("\nIntegrity changes for agent "
368                        "'%s (%s) - %s':\n",
369                        keys.keyentries[i]->name, keys.keyentries[i]->id,
370                        final_ip);
371             }
372
373             if(fname)
374             {
375                 printf("Detailed information for entries matching: '%s'\n",
376                        fname);
377             }
378             print_syscheck(keys.keyentries[i]->name,
379                     keys.keyentries[i]->ip->ip, fname,
380                     registry_only, 0, csv_output, zero_counter);
381
382         }
383
384         exit(0);
385     }
386
387
388
389     printf("\n** Invalid argument combination.\n");
390     helpmsg();
391
392
393     return(0);
394 }
395
396
397 /* EOF */