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