Imported Upstream version 2.7
[ossec-hids.git] / src / os_execd / exec.c
1 /* @(#) $Id: ./src/os_execd/exec.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 "shared.h"
15 #include "os_regex/os_regex.h"
16 #include "execd.h"
17
18 char exec_names[MAX_AR +1][OS_FLSIZE +1];
19 char exec_cmd[MAX_AR +1][OS_FLSIZE +1];
20 int  exec_timeout[MAX_AR +1];
21 int  exec_size = 0;
22 int  f_time_reading = 1;
23
24
25 /** int ReadExecConfig() v0.1:
26  * Reads the shared exec config.
27  * Returns 1 on success or 0 on failure.
28  * Format of the file is 'name - command - timeout'
29  */
30 int ReadExecConfig()
31 {
32     int i = 0, j = 0, dup_entry = 0;
33     FILE *fp;
34     FILE *process_file;
35     char buffer[OS_MAXSTR +1];
36
37     /* Cleaning up */
38     for(i = 0;i <= exec_size+1; i++)
39     {
40         memset(exec_names[i], '\0', OS_FLSIZE +1);
41         memset(exec_cmd[i], '\0', OS_FLSIZE +1);
42         exec_timeout[i] = 0;
43     }
44     exec_size = 0;
45
46
47     /* Opening file */
48     fp = fopen(DEFAULTARPATH, "r");
49     if(!fp)
50     {
51         merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH);
52         return(0);
53     }
54
55
56     /* Reading config */
57     while(fgets(buffer, OS_MAXSTR, fp) != NULL)
58     {
59         char *str_pt;
60         char *tmp_str;
61
62         str_pt = buffer;
63
64         /* Cleaning up the buffer */
65         tmp_str = strchr(buffer, ' ');
66         if(!tmp_str)
67         {
68             merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH);
69             continue;
70         }
71         *tmp_str = '\0';
72         tmp_str++;
73
74
75         /* Searching for ' ' and - */
76         if(*tmp_str == '-')
77         {
78             tmp_str+=2;
79         }
80         else
81         {
82             merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH);
83             continue;
84         }
85
86
87
88         /* Setting the name */
89         strncpy(exec_names[exec_size], str_pt, OS_FLSIZE);
90         exec_names[exec_size][OS_FLSIZE] = '\0';
91
92
93         str_pt = tmp_str;
94
95         tmp_str = strchr(tmp_str, ' ');
96         if(!tmp_str)
97         {
98             merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH);
99             continue;
100         }
101         *tmp_str = '\0';
102
103
104         /* Writting the full command path */
105         snprintf(exec_cmd[exec_size], OS_FLSIZE,
106                                       "%s/%s",
107                                       AR_BINDIRPATH,
108                                       str_pt);
109         process_file = fopen(exec_cmd[exec_size], "r");
110         if(!process_file)
111         {
112             if(f_time_reading)
113             {
114                 verbose("%s: INFO: Active response command not present: '%s'. "
115                         "Not using it on this system.",
116                         ARGV0, exec_cmd[exec_size]);
117             }
118
119             exec_cmd[exec_size][0] = '\0';
120         }
121         else
122         {
123             fclose(process_file);
124         }
125
126
127         /* Searching for ' ' and - */
128         tmp_str++;
129         if(*tmp_str == '-')
130         {
131             tmp_str+=2;
132         }
133         else
134         {
135             merror(EXEC_INV_CONF, ARGV0, DEFAULTARPATH);
136             continue;
137         }
138
139
140         str_pt = tmp_str;
141         tmp_str = strchr(tmp_str, '\n');
142         if(tmp_str)
143             *tmp_str = '\0';
144
145
146         /* Getting the exec timeout */
147         exec_timeout[exec_size] = atoi(str_pt);
148
149
150         /* Checking if name is duplicated. */
151         dup_entry = 0;
152         for(j = 0; j< exec_size; j++)
153         {
154             if(strcmp(exec_names[j], exec_names[exec_size]) == 0)
155             {
156                 if(exec_cmd[j][0] == '\0')
157                 {
158                     strncpy(exec_cmd[j], exec_cmd[exec_size], OS_FLSIZE);
159                     exec_cmd[j][OS_FLSIZE] = '\0';
160                     dup_entry = 1;
161                     break;
162                 }
163                 else if(exec_cmd[exec_size][0] == '\0')
164                 {
165                     dup_entry = 1;
166                 }
167             }
168         }
169
170         if(dup_entry)
171         {
172             exec_cmd[exec_size][0] = '\0';
173             exec_names[exec_size][0] = '\0';
174             exec_timeout[exec_size] = 0;
175         }
176         else
177         {
178             exec_size++;
179         }
180     }
181
182     fclose(fp);
183     f_time_reading = 0;
184
185     return(1);
186 }
187
188
189
190 /** char *GetCommandbyName(char *name, int *timeout) v0.2
191  * Returns a pointer to the command name (full path)
192  * Returns NULL if name cannot be found
193  * If timeout is not NULL, write the timeout for that
194  * command to it.
195  */
196 char *GetCommandbyName(char *name, int *timeout)
197 {
198     int i = 0;
199
200     for(;i < exec_size; i++)
201     {
202         if(strcmp(name, exec_names[i]) == 0)
203         {
204             *timeout = exec_timeout[i];
205             return(exec_cmd[i]);
206         }
207     }
208
209     return(NULL);
210 }
211
212
213 /** void ExecCmd(char **cmd, char *extra_data) v0.1
214  * Execute command given. Must be a argv** NULL terminated.
215  * Void. Prints error to log message in case of problems.
216  */
217 void ExecCmd(char **cmd)
218 {
219     #ifndef WIN32
220     pid_t pid;
221
222
223     /* Forking and leaving it running */
224     pid = fork();
225     if(pid == 0)
226     {
227         if(execv(*cmd, cmd) < 0)
228         {
229             merror(EXEC_CMDERROR, ARGV0, *cmd, strerror(errno));
230             exit(1);
231         }
232
233         exit(0);
234     }
235
236     #endif
237
238     return;
239 }
240
241
242 void ExecCmd_Win32(char *cmd)
243 {
244     /* Windows code now. */
245     #ifdef WIN32
246
247     STARTUPINFO si;
248     PROCESS_INFORMATION pi;
249
250     ZeroMemory( &si, sizeof(si) );
251     si.cb = sizeof(si);
252     ZeroMemory( &pi, sizeof(pi) );
253
254     if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL,
255                       &si, &pi))
256     {
257         merror("%s: ERROR: Unable to create active response process. ", ARGV0);
258         return;
259     }
260
261
262     /* Wait until process exits. */
263     WaitForSingleObject(pi.hProcess, INFINITE );
264
265     /* Close process and thread */
266     CloseHandle( pi.hProcess );
267     CloseHandle( pi.hThread );
268
269
270     #endif
271
272     return;
273 }
274
275
276 /* EOF */