Imported Upstream version 2.7
[ossec-hids.git] / src / win32 / win_service.c
1 /* @(#) $Id: ./src/win32/win_service.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights 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  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 #ifdef WIN32
18
19 #include "shared.h"
20 #include "os_win.h"
21 #include <winsvc.h>
22
23 #ifndef ARGV0
24 #define ARGV0 "ossec-agent"
25 #endif
26
27 static LPTSTR g_lpszServiceName        = "OssecSvc";
28 static LPTSTR g_lpszServiceDisplayName = "OSSEC HIDS";
29 static LPTSTR g_lpszServiceDescription = "OSSEC HIDS Windows Agent";
30
31 static SERVICE_STATUS          ossecServiceStatus;
32 static SERVICE_STATUS_HANDLE   ossecServiceStatusHandle;
33
34 /* ServiceStart */
35 void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv);
36
37
38
39 /* os_start_service: Starts ossec service */
40 int os_start_service()
41 {
42     int rc = 0;
43     SC_HANDLE schSCManager, schService;
44
45
46     /* Removing from the services database */
47     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
48     if (schSCManager)
49     {
50         schService = OpenService(schSCManager,g_lpszServiceName,
51                                  SC_MANAGER_ALL_ACCESS);
52         if(schService)
53         {
54
55             if(StartService(schService, 0, NULL))
56             {
57                 rc = 1;
58             }
59             else
60             {
61                 if(GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
62                 {
63                     rc = -1;
64                 }
65             }
66
67             CloseServiceHandle(schService);
68         }
69
70         CloseServiceHandle(schSCManager);
71     }
72
73     return(rc);
74 }
75
76
77 /* os_start_service: Starts ossec service */
78 int os_stop_service()
79 {
80     int rc = 0;
81     SC_HANDLE schSCManager, schService;
82
83
84     /* Removing from the services database */
85     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
86     if (schSCManager)
87     {
88         schService = OpenService(schSCManager,g_lpszServiceName,
89                                  SC_MANAGER_ALL_ACCESS);
90         if(schService)
91         {
92             SERVICE_STATUS lpServiceStatus;
93
94             if(ControlService(schService,
95                               SERVICE_CONTROL_STOP, &lpServiceStatus))
96             {
97                 rc = 1;
98             }
99
100             CloseServiceHandle(schService);
101         }
102
103         CloseServiceHandle(schSCManager);
104     }
105
106     return(rc);
107 }
108
109
110 /* int QueryService(): Checks if service is running. */
111 int CheckServiceRunning()
112 {
113     int rc = 0;
114     SC_HANDLE schSCManager, schService;
115
116
117     /* Removing from the services database */
118     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
119     if (schSCManager)
120     {
121         schService = OpenService(schSCManager,g_lpszServiceName,
122                                  SC_MANAGER_ALL_ACCESS);
123         if(schService)
124         {
125             /* Checking status */
126             SERVICE_STATUS lpServiceStatus;
127
128             if(QueryServiceStatus(schService, &lpServiceStatus))
129             {
130                 if(lpServiceStatus.dwCurrentState == SERVICE_RUNNING)
131                 {
132                     rc = 1;
133                 }
134             }
135             CloseServiceHandle(schService);
136         }
137
138         CloseServiceHandle(schSCManager);
139     }
140
141     return(rc);
142 }
143
144
145 /* int InstallService()
146  * Install the OSSEC HIDS agent service.
147  */
148 int InstallService(char *path)
149 {
150     char buffer[MAX_PATH+1];
151
152     SC_HANDLE schSCManager, schService;
153     LPCTSTR lpszBinaryPathName = NULL;
154     SERVICE_DESCRIPTION sdBuf;
155
156
157     /* Cleaning up some variables */
158     buffer[MAX_PATH] = '\0';
159
160
161     /* Executable path -- it must be called with the
162      * full path
163      */
164     lpszBinaryPathName = path;
165
166     /* Opening the services database */
167     schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
168
169     if (schSCManager == NULL)
170     {
171         goto install_error;
172     }
173
174     /* Creating the service */
175     schService = CreateService(schSCManager,
176                                g_lpszServiceName,
177                                g_lpszServiceDisplayName,
178                                SERVICE_ALL_ACCESS,
179                                SERVICE_WIN32_OWN_PROCESS,
180                                SERVICE_AUTO_START,
181                                SERVICE_ERROR_NORMAL,
182                                lpszBinaryPathName,
183                                NULL, NULL, NULL, NULL, NULL);
184
185     if (schService == NULL)
186     {
187         goto install_error;
188     }
189
190     /* Setting description */
191     sdBuf.lpDescription = g_lpszServiceDescription;
192     if(!ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf))
193     {
194         goto install_error;
195     }
196
197     CloseServiceHandle(schService);
198     CloseServiceHandle(schSCManager);
199
200     printf(" [%s] Successfully added to the Services database.\n", ARGV0);
201     return(1);
202
203
204     install_error:
205     {
206         char local_msg[1025];
207         LPVOID lpMsgBuf;
208
209         memset(local_msg, 0, 1025);
210
211         FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
212                        FORMAT_MESSAGE_FROM_SYSTEM |
213                        FORMAT_MESSAGE_IGNORE_INSERTS,
214                        NULL,
215                        GetLastError(),
216                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
217                        (LPTSTR) &lpMsgBuf,
218                        0,
219                        NULL);
220
221         merror(local_msg, 1024, "[%s] Unable to create registry "
222                                   "entry: %s", ARGV0,(LPCTSTR)lpMsgBuf);
223         return(0);
224     }
225 }
226
227
228 /* int UninstallService()
229  * Uninstall the OSSEC HIDS agent service.
230  */
231 int UninstallService()
232 {
233     SC_HANDLE schSCManager, schService;
234
235
236     /* Removing from the services database */
237     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
238     if (schSCManager)
239     {
240         schService = OpenService(schSCManager,g_lpszServiceName,DELETE);
241         if(schService)
242         {
243             if (DeleteService(schService))
244
245             {
246                 CloseServiceHandle(schService);
247                 CloseServiceHandle(schSCManager);
248
249                 printf(" [%s] Successfully removed from "
250                        "the Services database.\n", ARGV0);
251                 return(1);
252             }
253             CloseServiceHandle(schService);
254         }
255         CloseServiceHandle(schSCManager);
256     }
257
258     fprintf(stderr, " [%s] Error removing from "
259                     "the Services database.\n", ARGV0);
260
261     return(0);
262 }
263
264
265
266 /** VOID WINAPI OssecServiceCtrlHandler (DWORD dwOpcode)
267  * "Signal" handler
268  */
269 VOID WINAPI OssecServiceCtrlHandler(DWORD dwOpcode)
270 {
271     switch(dwOpcode)
272     {
273         case SERVICE_CONTROL_STOP:
274             ossecServiceStatus.dwCurrentState           = SERVICE_STOPPED;
275             ossecServiceStatus.dwWin32ExitCode          = 0;
276             ossecServiceStatus.dwCheckPoint             = 0;
277             ossecServiceStatus.dwWaitHint               = 0;
278
279             verbose("%s: Received exit signal.", ARGV0);
280             SetServiceStatus (ossecServiceStatusHandle, &ossecServiceStatus);
281             verbose("%s: Exiting...", ARGV0);
282             return;
283         default:
284             break;
285     }
286     return;
287 }
288
289
290 /** void WinSetError()
291  * Sets the error code in the services
292  */
293 void WinSetError()
294 {
295     OssecServiceCtrlHandler(SERVICE_CONTROL_STOP);
296 }
297
298
299 /** int os_WinMain(int argc, char **argv)
300  * Initializes OSSEC dispatcher
301  */
302 int os_WinMain(int argc, char **argv)
303 {
304     SERVICE_TABLE_ENTRY   steDispatchTable[] =
305     {
306         { g_lpszServiceName, OssecServiceStart },
307         { NULL,       NULL                     }
308     };
309
310     if(!StartServiceCtrlDispatcher(steDispatchTable))
311     {
312         merror("%s: Unable to set service information.", ARGV0);
313         return(1);
314     }
315
316     return(1);
317 }
318
319
320 /** void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv)
321  * Starts OSSEC service
322  */
323 void WINAPI OssecServiceStart (DWORD argc, LPTSTR *argv)
324 {
325     ossecServiceStatus.dwServiceType            = SERVICE_WIN32;
326     ossecServiceStatus.dwCurrentState           = SERVICE_START_PENDING;
327     ossecServiceStatus.dwControlsAccepted       = SERVICE_ACCEPT_STOP;
328     ossecServiceStatus.dwWin32ExitCode          = 0;
329     ossecServiceStatus.dwServiceSpecificExitCode= 0;
330     ossecServiceStatus.dwCheckPoint             = 0;
331     ossecServiceStatus.dwWaitHint               = 0;
332
333     ossecServiceStatusHandle =
334         RegisterServiceCtrlHandler(g_lpszServiceName,
335                                    OssecServiceCtrlHandler);
336
337     if (ossecServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
338     {
339         merror("%s: RegisterServiceCtrlHandler failed.", ARGV0);
340         return;
341     }
342
343     ossecServiceStatus.dwCurrentState = SERVICE_RUNNING;
344     ossecServiceStatus.dwCheckPoint = 0;
345     ossecServiceStatus.dwWaitHint = 0;
346
347     if (!SetServiceStatus(ossecServiceStatusHandle, &ossecServiceStatus))
348     {
349         merror("%s: SetServiceStatus error.", ARGV0);
350         return;
351     }
352
353
354     #ifdef OSSECHIDS
355     /* Starting process */
356     local_start();
357     #endif
358 }
359
360
361 #endif
362 /* EOF */