Imported Upstream version 2.5.1
[ossec-hids.git] / src / util / agent_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 "agent_control"
19
20
21 /** help **/
22 void helpmsg()
23 {
24     printf("\nOSSEC HIDS %s: Control remote agents.\n", ARGV0);
25     printf("Available options:\n");
26     printf("\t-h          This help message.\n");
27     printf("\t-l          List available (active or not) agents.\n");
28     printf("\t-lc         List active agents.\n");
29     printf("\t-i <id>     Extracts information from an agent.\n");
30     printf("\t-R <id>     Restarts agent.\n");
31     printf("\t-r -a       Runs the integrity/rootkit checking on all agents now.\n");
32     printf("\t-r -u <id>  Runs the integrity/rootkit checking on one agent now.\n\n");
33     printf("\t-b <ip>     Blocks the specified ip address.\n");
34     printf("\t-f <ar>     Used with -b, specifies which response to run.\n");
35     printf("\t-L          List available active responses.\n");
36     printf("\t-s          Changes the output to CSV (comma delimited).\n");
37     exit(1);
38 }
39
40
41 /** main **/
42 int main(int argc, char **argv)
43 {
44     char *dir = DEFAULTDIR;
45     char *group = GROUPGLOBAL;
46     char *user = USER;
47     char *agent_id = NULL;
48     char *ip_address = NULL;
49     char *ar = NULL;
50
51     int arq = 0;
52     int gid = 0;
53     int uid = 0;
54     int c = 0, restart_syscheck = 0, restart_all_agents = 0, list_agents = 0;
55     int info_agent = 0, agt_id = 0, active_only = 0, csv_output = 0; 
56     int list_responses = 0, end_time = 0, restart_agent = 0;
57
58     char shost[512];
59     
60     keystore keys;
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, "VehdlLcsaru:i:b:f:R:")) != -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_responses = 1;
89                 break;    
90             case 'e':
91                 end_time = 1;
92                 break;     
93             case 'r':
94                 restart_syscheck = 1;
95                 break;
96             case 'l':
97                 list_agents++;
98                 break;
99             case 's':
100                 csv_output = 1;    
101                 break;    
102             case 'c':
103                 active_only++;
104                 break;    
105             case 'i':
106                 info_agent++;
107             case 'u':
108                 if(!optarg)
109                 {
110                     merror("%s: -u needs an argument",ARGV0);
111                     helpmsg();
112                 }
113                 agent_id = optarg;
114                 break;
115             case 'b':
116                 if(!optarg)
117                 {
118                     merror("%s: -b needs an argument",ARGV0);
119                     helpmsg();
120                 }
121                 ip_address = optarg;
122                 break;
123             case 'f':
124                 if(!optarg)
125                 {
126                     merror("%s: -e needs an argument",ARGV0);
127                     helpmsg();
128                 }
129                 ar = optarg;
130                 break;
131             case 'R':
132                 if(!optarg)
133                 {
134                     merror("%s: -R needs an argument",ARGV0);
135                     helpmsg();
136                 }
137                 agent_id = optarg;
138                 restart_agent = 1;    
139             case 'a':
140                 restart_all_agents = 1;
141                 break;
142             default:
143                 helpmsg();
144                 break;
145         }
146
147     }
148     
149     
150     /* Getting the group name */
151     gid = Privsep_GetGroup(group);
152     uid = Privsep_GetUser(user);
153     if(gid < 0)
154     {
155             ErrorExit(USER_ERROR, ARGV0, user, group);
156     }
157         
158     
159     /* Setting the group */
160     if(Privsep_SetGroup(gid) < 0)
161     {
162             ErrorExit(SETGID_ERROR,ARGV0, group);
163     }
164     
165     
166     /* Chrooting to the default directory */
167     if(Privsep_Chroot(dir) < 0)
168     {
169         ErrorExit(CHROOT_ERROR, ARGV0, dir);
170     }
171
172
173     /* Inside chroot now */
174     nowChroot();
175  
176
177     /* Setting the user */
178     if(Privsep_SetUser(uid) < 0)
179     {
180         ErrorExit(SETUID_ERROR, ARGV0, user);
181     }
182
183
184
185     /* Getting servers hostname */
186     memset(shost, '\0', 512);
187     if(gethostname(shost, 512 -1) != 0)
188     {
189         strncpy(shost, "localhost", 32);
190         return(0);
191     }
192
193
194     /* Listing responses. */
195     if(list_responses)
196     {
197         FILE *fp;
198         if(!csv_output)
199         {
200             printf("\nOSSEC HIDS %s. Available active responses:\n", ARGV0);
201         }
202         
203         fp = fopen(DEFAULTAR, "r");
204         if(fp)
205         {
206             char buffer[256];
207
208             while(fgets(buffer, 255, fp) != NULL)
209             {
210                 char *r_name;
211                 char *r_cmd;
212                 char *r_timeout;
213
214                 r_name = buffer;
215                 r_cmd = strchr(buffer, ' ');
216                 if(!r_cmd)
217                     continue;
218                 
219                 *r_cmd = '\0';
220                 r_cmd++;
221                 if(*r_cmd == '-')
222                     r_cmd++;
223                 if(*r_cmd == ' ')
224                     r_cmd++;
225
226                 r_timeout = strchr(r_cmd, ' ');
227                 if(!r_timeout)
228                     continue;
229                 *r_timeout = '\0';        
230                             
231                 if(strcmp(r_name, "restart-ossec0") == 0)
232                 {
233                     continue;
234                 }
235                 printf("\n   Response name: %s, command: %s", r_name, r_cmd);
236             }
237
238             printf("\n\n");
239             fclose(fp);
240         }
241         else
242         {
243             printf("\n   No active response available.\n\n");
244         }
245
246         exit(0);
247     }
248
249     
250     /* Listing available agents. */
251     if(list_agents)
252     {
253         if(!csv_output)
254         {
255             printf("\nOSSEC HIDS %s. List of available agents:", 
256                     ARGV0);
257             printf("\n   ID: 000, Name: %s (server), IP: 127.0.0.1, Active/Local\n",
258                     shost);
259         }
260         else
261         {
262             printf("000,%s (server),127.0.0.1,Active/Local,\n", shost);
263         }
264         print_agents(1, active_only, csv_output);
265         printf("\n");
266         exit(0);
267     }
268     
269
270
271     /* Checking if the provided ID is valid. */
272     if(agent_id != NULL) 
273     {
274         if(strcmp(agent_id, "000") != 0)
275         {
276             OS_ReadKeys(&keys);
277
278             agt_id = OS_IsAllowedID(&keys, agent_id);
279             if(agt_id < 0)
280             {
281                 printf("\n** Invalid agent id '%s'.\n", agent_id);
282                 helpmsg();
283             }
284         }
285         else
286         {
287             /* server. */
288             agt_id = -1;
289         }
290     }
291    
292
293
294     /* Printing information from an agent. */
295     if(info_agent)
296     {
297         int agt_status = 0;
298         char final_ip[128 +1];
299         char final_mask[128 +1];
300         agent_info *agt_info;
301         
302         final_ip[128] = '\0';
303         final_mask[128] = '\0';
304         
305
306         if(!csv_output)
307             printf("\nOSSEC HIDS %s. Agent information:", ARGV0);
308
309         if(agt_id != -1)
310         {
311             agt_status = get_agent_status(keys.keyentries[agt_id]->name,
312                                           keys.keyentries[agt_id]->ip->ip);
313
314             agt_info = get_agent_info(keys.keyentries[agt_id]->name,
315                                       keys.keyentries[agt_id]->ip->ip);
316
317             /* Getting netmask from ip. */
318             getNetmask(keys.keyentries[agt_id]->ip->netmask, final_mask, 128);
319             snprintf(final_ip, 128, "%s%s",keys.keyentries[agt_id]->ip->ip, 
320                                            final_mask);
321
322
323             if(!csv_output)
324             {
325                 printf("\n   Agent ID:   %s\n", keys.keyentries[agt_id]->id);
326                 printf("   Agent Name: %s\n", keys.keyentries[agt_id]->name);
327                 printf("   IP address: %s\n", final_ip);
328                 printf("   Status:     %s\n\n",print_agent_status(agt_status));
329             }
330             else
331             {
332                 printf("%s,%s,%s,%s,", 
333                        keys.keyentries[agt_id]->id,
334                        keys.keyentries[agt_id]->name,
335                        final_ip,
336                        print_agent_status(agt_status)); 
337             }
338         }
339         else
340         {
341             agt_status = get_agent_status(NULL, NULL); 
342             agt_info = get_agent_info(NULL, "127.0.0.1");
343
344             if(!csv_output)
345             {
346             printf("\n   Agent ID:   000 (local instance)\n");
347             printf("   Agent Name: %s\n", shost);
348             printf("   IP address: 127.0.0.1\n");
349             printf("   Status:     %s/Local\n\n",print_agent_status(agt_status));
350             }
351
352             else
353             {
354                 printf("000,%s,127.0.0.1,%s/Local,",
355                         shost,
356                         print_agent_status(agt_status));
357                         
358             }
359         }
360
361         
362         if(!csv_output)
363         {
364         printf("   Operating system:    %s\n", agt_info->os);
365         printf("   Client version:      %s\n", agt_info->version);
366         printf("   Last keep alive:     %s\n\n", agt_info->last_keepalive);
367         
368
369         if(end_time)
370         {
371         printf("   Syscheck last started at:  %s\n", agt_info->syscheck_time);
372         printf("   Syscheck last ended   at:  %s\n", agt_info->syscheck_endtime);
373         printf("   Rootcheck last started at: %s\n", agt_info->rootcheck_time);
374         printf("   Rootcheck last ended   at: %s\n\n", agt_info->rootcheck_endtime);
375         }
376         else
377         {
378         printf("   Syscheck last started  at: %s\n", agt_info->syscheck_time);
379         printf("   Rootcheck last started at: %s\n", agt_info->rootcheck_time);
380         }
381         }
382         else
383         {
384             printf("%s,%s,%s,%s,%s,\n", 
385                    agt_info->os,
386                    agt_info->version,
387                    agt_info->last_keepalive,
388                    agt_info->syscheck_time,
389                    agt_info->rootcheck_time);
390         }
391         
392         exit(0);
393     }
394
395
396
397     /* Restarting syscheck every where. */
398     if(restart_all_agents && restart_syscheck)
399     {
400
401         /* Connecting to remoted. */
402         debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
403         arq = connect_to_remoted();
404         if(arq < 0)
405         {
406             printf("\n** Unable to connect to remoted.\n");
407             exit(1);
408         }
409         debug1("%s: DEBUG: Connected...", ARGV0);
410
411
412         /* Sending restart message to all agents. */
413         if(send_msg_to_agent(arq, HC_SK_RESTART, NULL, NULL) == 0)
414         {
415             printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on all agents.",
416                     ARGV0);
417         }
418         else
419         {
420             printf("\n** Unable to restart syscheck on all agents.\n");
421             exit(1);
422         }
423
424         exit(0);
425     }
426     
427
428
429     if(restart_syscheck && agent_id)
430     {
431
432         /* Restart on the server. */
433         if(strcmp(agent_id, "000") == 0)
434         {
435             os_set_restart_syscheck();
436
437             printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck "
438                    "locally.\n", ARGV0);
439
440             exit(0);
441         }
442
443
444
445         /* Connecting to remoted. */
446         debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
447         arq = connect_to_remoted();
448         if(arq < 0)
449         {
450             printf("\n** Unable to connect to remoted.\n");
451             exit(1);
452         }
453         debug1("%s: DEBUG: Connected...", ARGV0);
454
455
456         if(send_msg_to_agent(arq, HC_SK_RESTART, agent_id, NULL) == 0)
457         {
458             printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on agent: %s\n",
459                     ARGV0, agent_id);
460         }
461         else
462         {
463             printf("\n** Unable to restart syscheck on agent: %s\n", agent_id);
464             exit(1);
465         }
466
467         exit(0);
468     }
469     
470     
471     if(restart_agent && agent_id)
472     {
473         /* Connecting to remoted. */
474         debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
475         arq = connect_to_remoted();
476         if(arq < 0)
477         {
478             printf("\n** Unable to connect to remoted.\n");
479             exit(1);
480         }
481         debug1("%s: DEBUG: Connected...", ARGV0);
482
483
484         if(send_msg_to_agent(arq, "restart-ossec0", agent_id, "null") == 0)
485         {
486             printf("\nOSSEC HIDS %s: Restarting agent: %s\n",
487                     ARGV0, agent_id);
488         }
489         else
490         {
491             printf("\n** Unable to restart agent: %s\n", agent_id);
492             exit(1);
493         }
494
495         exit(0);
496     }
497
498
499     /* running active response on the specified agent id. */
500     if(ip_address && ar && agent_id)
501     {
502         /* Connecting to remoted. */
503         debug1("%s: DEBUG: Connecting to remoted...", ARGV0);
504         arq = connect_to_remoted();
505         if(arq < 0)
506         {
507             printf("\n** Unable to connect to remoted.\n");
508             exit(1);
509         }
510         debug1("%s: DEBUG: Connected...", ARGV0);
511
512
513         if(send_msg_to_agent(arq, ar, agent_id, ip_address) == 0)
514         {
515             printf("\nOSSEC HIDS %s: Running active response '%s' on: %s\n",
516                     ARGV0, ar, agent_id);
517         }
518         else
519         {
520             printf("\n** Unable to restart syscheck on agent: %s\n", agent_id);
521             exit(1);
522         }
523
524         exit(0);
525     }
526     
527
528     printf("\n** Invalid argument combination.\n");
529     helpmsg();
530
531
532     return(0);
533 }
534
535
536 /* EOF */