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 #ifndef WIN32
15 #include "os_dns/os_dns.h"
16 #endif //WIN32
17
18 struct imsgbuf server_ibuf;
19
20 /* Start the agent daemon */
AgentdStart(const char * dir,int uid,int gid,const char * user,const char * group)21 void AgentdStart(const char *dir, int uid, int gid, const char *user, const char *group)
22 {
23 int rc = 0;
24 int maxfd = 0;
25 fd_set fdset;
26 struct timeval fdtimeout;
27
28 available_server = 0;
29
30 /* Initial random numbers must happen before chroot */
31 srandom_init();
32
33 merror("going daemon");
34 /* Going Daemon */
35 if (!run_foreground) {
36 nowDaemon();
37 goDaemon();
38 }
39
40 #ifndef WIN32
41 merror("starting imsg stuff");
42 /* Prepare for os_dns */
43 struct imsgbuf osdns_ibuf;
44 //struct imsgbuf osdns_ibuf;
45 int imsg_fds[2];
46 merror("Creating socketpair()");
47 if ((socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds)) == -1) {
48 ErrorExit("%s: ERROR: Could not create socket pair.", ARGV0);
49 }
50 if (setnonblock(imsg_fds[0]) < 0) {
51 ErrorExit("%s: ERROR: Could not set imsg_fds[0] to nonblock", ARGV0);
52 }
53 if (setnonblock(imsg_fds[1]) < 0) {
54 ErrorExit("%s: ERROR: Could not set imsg_fds[1] to nonblock", ARGV0);
55 }
56
57 /* Fork os_dns process */
58 switch(fork()) {
59 case -1:
60 ErrorExit("%s: ERROR: Cannot fork() os_dns process", ARGV0);
61 case 0:
62 close(imsg_fds[0]);
63 merror("os_dns imsg_init()");
64 imsg_init(&osdns_ibuf, imsg_fds[1]);
65 exit(osdns(&osdns_ibuf, ARGV0));
66 }
67
68 /* Setup imsg for the rest of agentd */
69 close(imsg_fds[1]);
70 //imsg_init(&agt->ibuf, imsg_fds[1]);
71 merror("agentd imsg_init()");
72 imsg_init(&server_ibuf, imsg_fds[0]);
73
74 #endif //WIN32
75
76 /* Set group ID */
77 if (Privsep_SetGroup(gid) < 0) {
78 ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
79 }
80
81 /* chroot */
82 if (Privsep_Chroot(dir) < 0) {
83 ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
84 }
85 nowChroot();
86
87 if (Privsep_SetUser(uid) < 0) {
88 ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
89 }
90
91 /* Create the queue and read from it. Exit if fails. */
92 if ((agt->m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) {
93 ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno));
94 }
95
96 maxfd = agt->m_queue;
97 agt->sock = -1;
98
99 /* Create PID file */
100 if (CreatePID(ARGV0, getpid()) < 0) {
101 merror(PID_ERROR, ARGV0);
102 }
103
104 /* Read private keys */
105 verbose(ENC_READ, ARGV0);
106
107 OS_ReadKeys(&keys);
108 OS_StartCounter(&keys);
109
110 os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id,
111 agt->profile);
112
113 /* Start up message */
114 verbose(STARTUP_MSG, ARGV0, (int)getpid());
115
116 random();
117
118 /* Connect UDP */
119 rc = 0;
120 while (rc < agt->rip_id) {
121 verbose("%s: INFO: Server %d: %s", ARGV0, rc+1, agt->rip[rc]);
122 rc++;
123 }
124
125 /* Try to connect to the server */
126 if (!connect_server(0)) {
127 ErrorExit(UNABLE_CONN, ARGV0);
128 }
129
130 /* Set max fd for select */
131 if (agt->sock > maxfd) {
132 maxfd = agt->sock;
133 }
134
135 /* Connect to the execd queue */
136 if (agt->execdq == 0) {
137 if ((agt->execdq = StartMQ(EXECQUEUE, WRITE)) < 0) {
138 merror("%s: INFO: Unable to connect to the active response "
139 "queue (disabled).", ARGV0);
140 agt->execdq = -1;
141 }
142 }
143
144 /* Try to connect to server */
145 os_setwait();
146
147 start_agent(1);
148
149 os_delwait();
150
151 /* Send integrity message for agent configs */
152 intcheck_file(OSSECCONF, dir);
153 intcheck_file(OSSEC_DEFINES, dir);
154
155 /* Send first notification */
156 #ifdef WIN32
157 run_notify();
158 #else
159 run_notify();
160 #endif //WIN32
161
162 /* Maxfd must be higher socket +1 */
163 maxfd++;
164
165 /* Monitor loop */
166 while (1) {
167 /* Monitor all available sockets from here */
168 FD_ZERO(&fdset);
169 FD_SET(agt->sock, &fdset);
170 FD_SET(agt->m_queue, &fdset);
171
172 fdtimeout.tv_sec = 1;
173 fdtimeout.tv_usec = 0;
174
175 /* Continuously send notifications */
176 #ifdef WIN32
177 run_notify();
178 #else
179 run_notify();
180 #endif //WIN32
181
182 /* Wait with a timeout for any descriptor */
183 rc = select(maxfd, &fdset, NULL, NULL, &fdtimeout);
184 if (rc == -1) {
185 ErrorExit(SELECT_ERROR, ARGV0, errno, strerror(errno));
186 } else if (rc == 0) {
187 continue;
188 }
189
190 /* For the receiver */
191 if (FD_ISSET(agt->sock, &fdset)) {
192 receive_msg();
193 }
194
195 /* For the forwarder */
196 if (FD_ISSET(agt->m_queue, &fdset)) {
197 #ifdef WIN32
198 EventForward();
199 #else
200 EventForward();
201 #endif
202 }
203 }
204 }
205
206