new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / client-agent / main.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 /* agent daemon */
11
12 #include "shared.h"
13 #include "agentd.h"
14
15 #ifndef ARGV0
16 #define ARGV0 "ossec-agentd"
17 #endif
18
19 /* Prototypes */
20 static void help_agentd(void) __attribute((noreturn));
21
22
23 /* Print help statement */
24 static void help_agentd()
25 {
26     print_header();
27     print_out("  %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0);
28     print_out("    -V          Version and license message");
29     print_out("    -h          This help message");
30     print_out("    -d          Execute in debug mode. This parameter");
31     print_out("                can be specified multiple times");
32     print_out("                to increase the debug level.");
33     print_out("    -t          Test configuration");
34     print_out("    -f          Run in foreground");
35     print_out("    -u <user>   User to run as (default: %s)", USER);
36     print_out("    -g <group>  Group to run as (default: %s)", GROUPGLOBAL);
37     print_out("    -c <config> Configuration file to use (default: %s)", DEFAULTCPATH);
38     print_out("    -D <dir>    Directory to chroot into (default: %s)", DEFAULTDIR);
39     print_out(" ");
40     exit(1);
41 }
42
43 int main(int argc, char **argv)
44 {
45     int c = 0;
46     int test_config = 0;
47     int debug_level = 0;
48
49     const char *dir = DEFAULTDIR;
50     const char *user = USER;
51     const char *group = GROUPGLOBAL;
52     const char *cfg = DEFAULTCPATH;
53
54     uid_t uid;
55     gid_t gid;
56
57     run_foreground = 0;
58
59     /* Set the name */
60     OS_SetName(ARGV0);
61
62     while ((c = getopt(argc, argv, "Vtdfhu:g:D:c:")) != -1) {
63         switch (c) {
64             case 'V':
65                 print_version();
66                 break;
67             case 'h':
68                 help_agentd();
69                 break;
70             case 'd':
71                 nowDebug();
72                 debug_level = 1;
73                 break;
74             case 'f':
75                 run_foreground = 1;
76                 break;
77             case 'u':
78                 if (!optarg) {
79                     ErrorExit("%s: -u needs an argument", ARGV0);
80                 }
81                 user = optarg;
82                 break;
83             case 'g':
84                 if (!optarg) {
85                     ErrorExit("%s: -g needs an argument", ARGV0);
86                 }
87                 group = optarg;
88                 break;
89             case 't':
90                 test_config = 1;
91                 break;
92             case 'D':
93                 if (!optarg) {
94                     ErrorExit("%s: -D needs an argument", ARGV0);
95                 }
96                 dir = optarg;
97                 break;
98             case 'c':
99                 if (!optarg) {
100                     ErrorExit("%s: -c needs an argument.", ARGV0);
101                 }
102                 cfg = optarg;
103                 break;
104             default:
105                 help_agentd();
106                 break;
107         }
108     }
109
110     debug1(STARTED_MSG, ARGV0);
111
112     agt = (agent *)calloc(1, sizeof(agent));
113     if (!agt) {
114         ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
115     }
116
117     /* Check current debug_level
118      * Command line setting takes precedence
119      */
120     if (debug_level == 0) {
121         /* Get debug level */
122         debug_level = getDefine_Int("agent", "debug", 0, 2);
123         while (debug_level != 0) {
124             nowDebug();
125             debug_level--;
126         }
127     }
128
129     /* Read config */
130     if (ClientConf(cfg) < 0) {
131         ErrorExit(CLIENT_ERROR, ARGV0);
132     }
133
134     if (!agt->rip) {
135         merror(AG_INV_IP, ARGV0);
136         ErrorExit(CLIENT_ERROR, ARGV0);
137     }
138
139     if (agt->notify_time == 0) {
140         agt->notify_time = NOTIFY_TIME;
141     }
142     if (agt->max_time_reconnect_try == 0 ) {
143         agt->max_time_reconnect_try = NOTIFY_TIME * 3;
144     }
145     if (agt->max_time_reconnect_try <= agt->notify_time) {
146         agt->max_time_reconnect_try = (agt->notify_time * 3);
147         verbose("%s: INFO: Max time to reconnect can't be less than notify_time(%d), using notify_time*3 (%d)", ARGV0, agt->notify_time, agt->max_time_reconnect_try);
148     }
149     verbose("%s: INFO: Using notify time: %d and max time to reconnect: %d", ARGV0, agt->notify_time, agt->max_time_reconnect_try);
150
151     /* Check auth keys */
152     if (!OS_CheckKeys()) {
153         ErrorExit(AG_NOKEYS_EXIT, ARGV0);
154     }
155
156     /* Check if the user/group given are valid */
157     uid = Privsep_GetUser(user);
158     gid = Privsep_GetGroup(group);
159     if (uid == (uid_t) - 1 || gid == (gid_t) - 1) {
160         ErrorExit(USER_ERROR, ARGV0, user, group);
161     }
162
163     /* Exit if test config */
164     if (test_config) {
165         exit(0);
166     }
167
168     /* Start the signal manipulation */
169     StartSIG(ARGV0);
170
171     /* Agentd Start */
172     AgentdStart(dir, uid, gid, user, group);
173
174     return (0);
175 }
176