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