new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / client-agent / agentd.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 #include "shared.h"
11 #include "agentd.h"
12 #include "os_net/os_net.h"
13
14
15 /* Start the agent daemon */
16 void AgentdStart(const char *dir, int uid, int gid, const char *user, const char *group)
17 {
18     int rc = 0;
19     int maxfd = 0;
20     fd_set fdset;
21     struct timeval fdtimeout;
22
23     available_server = 0;
24
25     /* Initial random numbers must happen before chroot */
26     srandom_init();
27
28     /* Going Daemon */
29     if (!run_foreground) {
30         nowDaemon();
31         goDaemon();
32     }
33
34     /* Set group ID */
35     if (Privsep_SetGroup(gid) < 0) {
36         ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
37     }
38
39     /* chroot */
40     if (Privsep_Chroot(dir) < 0) {
41         ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
42     }
43     nowChroot();
44
45     if (Privsep_SetUser(uid) < 0) {
46         ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
47     }
48
49     /* Create the queue and read from it. Exit if fails. */
50     if ((agt->m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) {
51         ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
52     }
53
54     maxfd = agt->m_queue;
55     agt->sock = -1;
56
57     /* Create PID file */
58     if (CreatePID(ARGV0, getpid()) < 0) {
59         merror(PID_ERROR, ARGV0);
60     }
61
62     /* Read private keys  */
63     verbose(ENC_READ, ARGV0);
64
65     OS_ReadKeys(&keys);
66     OS_StartCounter(&keys);
67
68     os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id,
69                         agt->profile);
70
71     /* Start up message */
72     verbose(STARTUP_MSG, ARGV0, (int)getpid());
73
74     random();
75
76     /* Connect UDP */
77     rc = 0;
78     while (rc < agt->rip_id) {
79         verbose("%s: INFO: Server %d: %s", ARGV0, rc+1, agt->rip[rc]);
80         rc++;
81     }
82
83     /* Try to connect to the server */
84     if (!connect_server(0)) {
85         ErrorExit(UNABLE_CONN, ARGV0);
86     }
87
88     /* Set max fd for select */
89     if (agt->sock > maxfd) {
90         maxfd = agt->sock;
91     }
92
93     /* Connect to the execd queue */
94     if (agt->execdq == 0) {
95         if ((agt->execdq = StartMQ(EXECQUEUE, WRITE)) < 0) {
96             merror("%s: INFO: Unable to connect to the active response "
97                    "queue (disabled).", ARGV0);
98             agt->execdq = -1;
99         }
100     }
101
102     /* Try to connect to server */
103     os_setwait();
104
105     start_agent(1);
106
107     os_delwait();
108
109     /* Send integrity message for agent configs */
110     intcheck_file(OSSECCONF, dir);
111     intcheck_file(OSSEC_DEFINES, dir);
112
113     /* Send first notification */
114     run_notify();
115
116     /* Maxfd must be higher socket +1 */
117     maxfd++;
118
119     /* Monitor loop */
120     while (1) {
121         /* Monitor all available sockets from here */
122         FD_ZERO(&fdset);
123         FD_SET(agt->sock, &fdset);
124         FD_SET(agt->m_queue, &fdset);
125
126         fdtimeout.tv_sec = 1;
127         fdtimeout.tv_usec = 0;
128
129         /* Continuously send notifications */
130         run_notify();
131
132         /* Wait with a timeout for any descriptor */
133         rc = select(maxfd, &fdset, NULL, NULL, &fdtimeout);
134         if (rc == -1) {
135             ErrorExit(SELECT_ERROR, ARGV0, errno, strerror(errno));
136         } else if (rc == 0) {
137             continue;
138         }
139
140         /* For the receiver */
141         if (FD_ISSET(agt->sock, &fdset)) {
142             receive_msg();
143         }
144
145         /* For the forwarder */
146         if (FD_ISSET(agt->m_queue, &fdset)) {
147             EventForward();
148         }
149     }
150 }
151