00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00039 #include <xdas_base.h>
00040
00041 #include "xdasd_main.h"
00042 #include "xdasd_log.h"
00043 #include "xdasd_cmdline.h"
00044
00045 #include <stdio.h>
00046 #include <errno.h>
00047
00048 #define WIN32_LEAN_AND_MEAN
00049 #include <windows.h>
00050 #include <tchar.h>
00051
00057 #define SERVICENAME _T("xdasd")
00058 #define SERVICEDISPLAYNAME _T("Distributed Audit Service")
00059 #define SERVICEDESCRIPTION \
00060 _T("OpenXDAS Distributed Audit Service provides a common point ") \
00061 _T("of event filtering and propagation for XDAS audit events.")
00062
00063 static SERVICE_STATUS_HANDLE s_hss;
00064 static SERVICE_STATUS s_status;
00065
00072 static TCHAR * xdasd_gle_text(void)
00073 {
00074 static TCHAR buf[256];
00075
00076 DWORD rv, gle = GetLastError();
00077
00078 *buf = 0;
00079 if ((rv = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, gle,
00080 LANG_NEUTRAL, buf, xdas_elemcount(buf) - 14, 0)) > 3)
00081 {
00082 buf[_tcslen(buf) - 3] = 0;
00083 _sntprintf(buf + _tcslen(buf), 14, _T(" (0x%x)"), gle);
00084 }
00085 return buf;
00086 }
00087
00088
00089
00090
00091
00104 static int xdasd_w32svc_install(int automatic)
00105 {
00106 DWORD options = automatic? SERVICE_AUTO_START: SERVICE_DEMAND_START;
00107 SC_HANDLE hscm, hsvc;
00108 TCHAR path[512];
00109 int rv = 1;
00110
00111 if (GetModuleFileName(0, path, xdas_elemcount(path)) == 0)
00112 _tprintf(_T("Unable to install %s: %s.\n"),
00113 SERVICEDISPLAYNAME, xdasd_gle_text());
00114 else if ((hscm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS)) != 0)
00115 {
00116 if ((hsvc = CreateService(hscm, SERVICENAME, SERVICEDISPLAYNAME,
00117 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, options,
00118 SERVICE_ERROR_NORMAL, path, 0, 0, _T(""), 0, 0)) != 0)
00119 {
00120 static SERVICE_DESCRIPTION sd = { SERVICEDESCRIPTION };
00121 ChangeServiceConfig2(hsvc, SERVICE_CONFIG_DESCRIPTION, &sd);
00122 _putts(SERVICEDISPLAYNAME _T(" installed."));
00123 CloseServiceHandle(hsvc);
00124 rv = 0;
00125 }
00126 else
00127 _tprintf(_T("CreateService failed: %s.\n"), xdasd_gle_text());
00128 CloseServiceHandle(hscm);
00129 }
00130 else
00131 _tprintf(_T("OpenSCManager failed: %s.\n"), xdasd_gle_text());
00132
00133 return rv;
00134 }
00135
00149 static int xdasd_w32svc_stop_handle(SC_HANDLE hsvc, int silent)
00150 {
00151 int rv = 1;
00152
00153 if (ControlService(hsvc, SERVICE_CONTROL_STOP, &s_status) != FALSE)
00154 {
00155 _tprintf(_T("Stopping %s."), SERVICEDISPLAYNAME);
00156 while (QueryServiceStatus(hsvc, &s_status) != 0
00157 && s_status.dwCurrentState == SERVICE_STOP_PENDING)
00158 {
00159 printf(".");
00160 Sleep(1000);
00161 }
00162 if (s_status.dwCurrentState == SERVICE_STOPPED)
00163 {
00164 _putts(_T(".Stopped."));
00165 rv = 0;
00166 }
00167 else
00168 _putts(_T("FAILED.\n"));
00169 }
00170 else if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE)
00171 {
00172 if (!silent)
00173 _putts(SERVICEDISPLAYNAME _T(" not running."));
00174 rv = 0;
00175 }
00176 else
00177 _tprintf(_T("Unable to stop %s: %s.\n"),
00178 SERVICEDISPLAYNAME, xdasd_gle_text());
00179
00180 return 0;
00181 }
00182
00191 static int xdasd_w32svc_remove(void)
00192 {
00193 int rv = 1;
00194 SC_HANDLE hscm, hsvc;
00195
00196 if ((hscm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS)) != 0)
00197 {
00198 if ((hsvc = OpenService(hscm, SERVICENAME, SERVICE_ALL_ACCESS)) != 0)
00199 {
00200 xdasd_w32svc_stop_handle(hsvc, 1);
00201 if (DeleteService(hsvc) != FALSE)
00202 _putts(SERVICEDISPLAYNAME _T(" has been removed."));
00203 else
00204 _tprintf(_T("DeleteService failed: %s.\n"), xdasd_gle_text());
00205 CloseServiceHandle(hsvc);
00206 rv = 0;
00207 }
00208 else
00209 _tprintf(_T("OpenService failed: %s.\n"), xdasd_gle_text());
00210
00211 CloseServiceHandle(hscm);
00212 }
00213 else
00214 _tprintf(_T("OpenSCManager failed: %s.\n"), xdasd_gle_text());
00215
00216 return rv;
00217 }
00218
00225 static int xdasd_w32svc_start(void)
00226 {
00227 int rv = 1;
00228 SC_HANDLE hscm, hsvc;
00229
00230 if ((hscm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS)) != 0)
00231 {
00232 if ((hsvc = OpenService(hscm, SERVICENAME, SERVICE_ALL_ACCESS)) != 0)
00233 {
00234 if ((rv = (int)StartService(hsvc, 0, 0)) != 0)
00235 _putts(SERVICEDISPLAYNAME _T(" has been started."));
00236 else
00237 _tprintf(_T("StartService failed: %s.\n"), xdasd_gle_text());
00238 CloseServiceHandle(hsvc);
00239 }
00240 else
00241 _tprintf(_T("OpenService failed: %s.\n"), xdasd_gle_text());
00242 CloseServiceHandle(hscm);
00243 }
00244 else
00245 _tprintf(_T("OpenSCManager failed: %s\n"), xdasd_gle_text());
00246
00247 return rv;
00248 }
00249
00254 static int xdasd_w32svc_stop(void)
00255 {
00256 int rv = 1;
00257 SC_HANDLE hscm, hsvc;
00258
00259 if ((hscm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS)) != 0)
00260 {
00261 if ((hsvc = OpenService(hscm, SERVICENAME, SERVICE_ALL_ACCESS)) != 0)
00262 {
00263 rv = xdasd_w32svc_stop_handle(hsvc, 0);
00264 CloseServiceHandle(hsvc);
00265 }
00266 else
00267 _tprintf(_T("OpenService failed: %s.\n"), xdasd_gle_text());
00268
00269 CloseServiceHandle(hscm);
00270 }
00271 else
00272 _tprintf(_T("OpenSCManager failed: %s.\n"), xdasd_gle_text());
00273
00274 return rv;
00275 }
00276
00277
00278
00279
00280
00291 static BOOL xdasd_scmgr_report(DWORD curstate, DWORD ecode, DWORD hint)
00292 {
00293 static DWORD chkpoint = 1;
00294
00295 BOOL rv = TRUE;
00296
00297
00298 if (curstate == SERVICE_START_PENDING)
00299 s_status.dwControlsAccepted = 0;
00300 else
00301 s_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
00302
00303 s_status.dwCurrentState = curstate;
00304 s_status.dwWin32ExitCode = ecode;
00305 s_status.dwWaitHint = hint;
00306 s_status.dwCheckPoint =
00307 (curstate == SERVICE_RUNNING || curstate == SERVICE_STOPPED)?
00308 0: chkpoint++;
00309
00310
00311 if ((rv = SetServiceStatus(s_hss, &s_status)) == FALSE)
00312 xdasd_log(0, "SetServiceStatus failed.\n");
00313
00314 return rv;
00315 }
00316
00321 static void xdasd_stop_service(void)
00322 {
00323 xdasd_set_signal(XDASD_SIGTERM);
00324 xdasd_scmgr_report(SERVICE_STOPPED, NO_ERROR, 3000);
00325 }
00326
00334 static void xdasd_start_service(int argc, char ** argv)
00335 {
00336 (void)argc;
00337 (void)argv;
00338
00340 }
00341
00351 static VOID WINAPI xdasd_svc_control(DWORD ccode)
00352 {
00353 if (ccode == SERVICE_CONTROL_STOP)
00354 {
00355 xdasd_scmgr_report(SERVICE_STOP_PENDING, NO_ERROR, 0);
00356 xdasd_stop_service();
00357 return;
00358 }
00359 xdasd_scmgr_report(s_status.dwCurrentState, NO_ERROR, 0);
00360 }
00361
00378 static void WINAPI xdasd_service_main(DWORD argc, LPTSTR * argv)
00379 {
00380 if ((s_hss = RegisterServiceCtrlHandler(SERVICENAME,
00381 xdasd_svc_control)) != 0)
00382 {
00383
00384 s_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00385 s_status.dwServiceSpecificExitCode = 0;
00386
00387
00388 if (xdasd_scmgr_report(SERVICE_START_PENDING, NO_ERROR, 3000))
00389 {
00390 int err;
00391 XDASDCmdLine cmdline;
00392
00393
00394 if (xdasd_parse_cmdline(argc, (char **)argv, &cmdline) < 0)
00395 {
00396 xdasd_scmgr_report(SERVICE_STOP_PENDING, (DWORD)(-1), 0);
00397 return;
00398 }
00399
00400 if (!xdasd_scmgr_report(SERVICE_START_PENDING, 0, 3000))
00401 return;
00402
00403 err = xdasd_main_init(&cmdline);
00404 xdasd_scmgr_report(err? SERVICE_STOP_PENDING: SERVICE_RUNNING, err, 0);
00405 if (!err)
00406 xdasd_main_run();
00407 }
00408 xdasd_scmgr_report(SERVICE_STOPPED, 0, 0);
00409 }
00410 }
00411
00421 int main(int argc, char ** argv)
00422 {
00423 int err;
00424 XDASDCmdLine cmdline;
00425
00426 if (xdasd_parse_cmdline(argc, argv, &cmdline) != 0)
00427 xdasd_fatal("Invalid command line.\n");
00428
00429 switch (cmdline.action)
00430 {
00431 case XDASD_INSTALL: return xdasd_w32svc_install(cmdline.autostart);
00432 case XDASD_REMOVE: return xdasd_w32svc_remove();
00433 case XDASD_START: return xdasd_w32svc_start();
00434 case XDASD_STOP: return xdasd_w32svc_stop();
00435
00436 default:
00437 {
00438 static SERVICE_TABLE_ENTRY dispatchTable[] =
00439 {
00440 {SERVICENAME, (LPSERVICE_MAIN_FUNCTION)xdasd_service_main},
00441 {0, 0}
00442 };
00443
00444 if (StartServiceCtrlDispatcher(dispatchTable) != FALSE)
00445 return 0;
00446 if (GetLastError() != ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
00447 return 1;
00448 }
00449 }
00450 if ((err = xdasd_main_init(&cmdline)) == 0)
00451 xdasd_main_run();
00452 return err;
00453 }
00454