xdasd_w32.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  * Copyright (c) 2006, Novell, Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions are 
00007  * met:
00008  * 
00009  *     * Redistributions of source code must retain the above copyright 
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright 
00012  *       notice, this list of conditions and the following disclaimer in the 
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Novell nor the names of its contributors 
00015  *       may be used to endorse or promote products derived from this 
00016  *       software without specific prior written permission.
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00020  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00021  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00022  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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;  /* remove trailing period */
00083       _sntprintf(buf + _tcslen(buf), 14, _T(" (0x%x)"), gle); 
00084    } 
00085    return buf;
00086 } 
00087 
00088 /*==========================================================================
00089                         Service Installation/Initiation
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                               Service Execution
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    /* when debugging we don't report to the SCM */
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    /* report the status of the service to the service control manager.*/
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       /* initialize SERVICE_STATUS members that don't change */
00384       s_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00385       s_status.dwServiceSpecificExitCode = 0;
00386 
00387       /* report the xdasd status to the service control manager */
00388       if (xdasd_scmgr_report(SERVICE_START_PENDING, NO_ERROR, 3000))
00389       {
00390          int err;
00391          XDASDCmdLine cmdline;
00392 
00393          /* NOTE: The following cast is a problem that needs to be fixed! */
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: /* default action (no cmdline options) is to run the service */
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 

Generated on Thu Aug 20 22:33:06 2009 for OpenXDAS by  doxygen 1.5.6