new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / monitord / main.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights 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 #include "shared.h"
11 #include "config/config.h"
12 #include "monitord.h"
13 #include "os_net/os_net.h"
14
15 /* Prototypes */
16 static void help_monitord(void) __attribute__((noreturn));
17
18
19 /* Print help statement */
20 static void help_monitord()
21 {
22     print_header();
23     print_out("  %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0);
24     print_out("    -V          Version and license message");
25     print_out("    -h          This help message");
26     print_out("    -d          Execute in debug mode. This parameter");
27     print_out("                can be specified multiple times");
28     print_out("                to increase the debug level.");
29     print_out("    -t          Test configuration");
30     print_out("    -f          Run in foreground");
31     print_out("    -u <user>   User to run as (default: %s)", USER);
32     print_out("    -g <group>  Group to run as (default: %s)", GROUPGLOBAL);
33     print_out("    -c <config> Configuration file to use (default: %s)", DEFAULTCPATH);
34     print_out("    -D <dir>    Directory to chroot into (default: %s)", DEFAULTDIR);
35     print_out(" ");
36     exit(1);
37 }
38
39 int main(int argc, char **argv)
40 {
41     int c, test_config = 0, run_foreground = 0;
42     uid_t uid;
43     gid_t gid;
44     const char *dir  = DEFAULTDIR;
45     const char *user = USER;
46     const char *group = GROUPGLOBAL;
47     const char *cfg = DEFAULTCPATH;
48
49     /* Initialize global variables */
50     mond.a_queue = 0;
51
52     /* Set the name */
53     OS_SetName(ARGV0);
54
55     while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) {
56         switch (c) {
57             case 'V':
58                 print_version();
59                 break;
60             case 'h':
61                 help_monitord();
62                 break;
63             case 'd':
64                 nowDebug();
65                 break;
66             case 'f':
67                 run_foreground = 1;
68                 break;
69             case 'u':
70                 if (!optarg) {
71                     ErrorExit("%s: -u needs an argument", ARGV0);
72                 }
73                 user = optarg;
74                 break;
75             case 'g':
76                 if (!optarg) {
77                     ErrorExit("%s: -g needs an argument", ARGV0);
78                 }
79                 group = optarg;
80                 break;
81             case 'D':
82                 if (!optarg) {
83                     ErrorExit("%s: -D needs an argument", ARGV0);
84                 }
85                 dir = optarg;
86                 break;
87             case 'c':
88                 if (!optarg) {
89                     ErrorExit("%s: -c needs an argument", ARGV0);
90                 }
91                 cfg = optarg;
92                 break;
93             case 't':
94                 test_config = 1;
95                 break;
96             default:
97                 help_monitord();
98                 break;
99         }
100
101     }
102
103     /* Start daemon */
104     debug1(STARTED_MSG, ARGV0);
105
106     /*Check if the user/group given are valid */
107     uid = Privsep_GetUser(user);
108     gid = Privsep_GetGroup(group);
109     if (uid == (uid_t) - 1 || gid == (gid_t) - 1) {
110         ErrorExit(USER_ERROR, ARGV0, user, group);
111     }
112
113     /* Get config options */
114     mond.day_wait = (unsigned short) getDefine_Int("monitord", "day_wait", 5, 240);
115     mond.compress = (short) getDefine_Int("monitord", "compress", 0, 1);
116     mond.sign = (short) getDefine_Int("monitord", "sign", 0, 1);
117     mond.monitor_agents = (short) getDefine_Int("monitord", "monitor_agents", 0, 1);
118     mond.notify_time = getDefine_Int("monitord", "notify_time", 60, 3600);
119     mond.agents = NULL;
120     mond.smtpserver = NULL;
121     mond.emailfrom = NULL;
122     mond.emailidsname = NULL;
123
124     c = 0;
125     c |= CREPORTS;
126     if (ReadConfig(c, cfg, &mond, NULL) < 0) {
127         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
128     }
129
130     /* If we have any reports configured, read smtp/emailfrom */
131     if (mond.reports) {
132         OS_XML xml;
133         char *tmpsmtp;
134
135         const char *(xml_smtp[]) = {"ossec_config", "global", "smtp_server", NULL};
136         const char *(xml_from[]) = {"ossec_config", "global", "email_from", NULL};
137         const char *(xml_idsname[]) = {"ossec_config", "global", "email_idsname", NULL};
138
139         if (OS_ReadXML(cfg, &xml) < 0) {
140             ErrorExit(CONFIG_ERROR, ARGV0, cfg);
141         }
142
143         tmpsmtp = OS_GetOneContentforElement(&xml, xml_smtp);
144         mond.emailfrom = OS_GetOneContentforElement(&xml, xml_from);
145         mond.emailidsname = OS_GetOneContentforElement(&xml, xml_idsname);
146
147         if (tmpsmtp && mond.emailfrom) {
148             mond.smtpserver = OS_GetHost(tmpsmtp, 5);
149             if (!mond.smtpserver) {
150                 merror(INVALID_SMTP, ARGV0, tmpsmtp);
151                 if (mond.emailfrom) {
152                     free(mond.emailfrom);
153                 }
154                 mond.emailfrom = NULL;
155                 merror("%s: Invalid SMTP server.  Disabling email reports.", ARGV0);
156             }
157         } else {
158             if (tmpsmtp) {
159                 free(tmpsmtp);
160             }
161             if (mond.emailfrom) {
162                 free(mond.emailfrom);
163             }
164
165             mond.emailfrom = NULL;
166             merror("%s: SMTP server or 'email from' missing. Disabling email reports.", ARGV0);
167         }
168
169         OS_ClearXML(&xml);
170     }
171
172     /* Exit here if test config is set */
173     if (test_config) {
174         exit(0);
175     }
176
177     if (!run_foreground) {
178         /* Going on daemon mode */
179         nowDaemon();
180         goDaemon();
181     }
182
183     /* Privilege separation */
184     if (Privsep_SetGroup(gid) < 0) {
185         ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
186     }
187
188     /* chroot */
189     if (Privsep_Chroot(dir) < 0) {
190         ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
191     }
192
193     nowChroot();
194
195     /* Change user */
196     if (Privsep_SetUser(uid) < 0) {
197         ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
198     }
199
200     debug1(CHROOT_MSG, ARGV0, dir);
201     debug1(PRIVSEP_MSG, ARGV0, user);
202
203     /* Signal manipulation */
204     StartSIG(ARGV0);
205
206     /* Create PID files */
207     if (CreatePID(ARGV0, getpid()) < 0) {
208         ErrorExit(PID_ERROR, ARGV0);
209     }
210
211     /* Start up message */
212     verbose(STARTUP_MSG, ARGV0, (int)getpid());
213
214     /* The real daemon now */
215     Monitord();
216     exit(0);
217 }