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