xref: /reactos/dll/win32/lsasrv/service.c (revision 84344399)
1 /*
2  * PROJECT:     Local Security Authority Server DLL
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/lsasrv/service.c
5  * PURPOSE:     Security service
6  * COPYRIGHT:   Copyright 2016, 2019 Eric Kohl <eric.kohl@reactos.org>
7  */
8 
9 /* INCLUDES ****************************************************************/
10 
11 #include "lsasrv.h"
12 #include <winsvc.h>
13 
14 typedef VOID (WINAPI *PNETLOGONMAIN)(INT ArgCount, PWSTR *ArgVector);
15 
16 VOID WINAPI I_ScIsSecurityProcess(VOID);
17 
18 static VOID WINAPI NetlogonServiceMain(DWORD dwArgc, PWSTR *pszArgv);
19 static VOID WINAPI SamSsServiceMain(DWORD dwArgc, PWSTR *pszArgv);
20 
21 SERVICE_TABLE_ENTRYW ServiceTable[] =
22 {
23     {L"NETLOGON", NetlogonServiceMain},
24     {L"SAMSS", SamSsServiceMain},
25     {NULL, NULL}
26 };
27 
28 
29 /* FUNCTIONS ***************************************************************/
30 
31 static
32 VOID
33 WINAPI
34 NetlogonServiceMain(
35     _In_ DWORD dwArgc,
36     _In_ PWSTR *pszArgv)
37 {
38     HINSTANCE hNetlogon = NULL;
39     PNETLOGONMAIN pNetlogonMain = NULL;
40 
41     TRACE("NetlogonServiceMain(%lu %p)\n", dwArgc, pszArgv);
42 
43     hNetlogon = LoadLibraryW(L"Netlogon.dll");
44     if (hNetlogon == NULL)
45     {
46         ERR("LoadLibrary() failed!\n");
47         return;
48     }
49 
50     pNetlogonMain = (PNETLOGONMAIN)GetProcAddress(hNetlogon, "NlNetlogonMain");
51     if (pNetlogonMain == NULL)
52     {
53         ERR("GetProcAddress(NlNetlogonMain) failed!\n");
54         FreeLibrary(hNetlogon);
55         return;
56     }
57 
58     TRACE("NlNetlogonMain %p\n", pNetlogonMain);
59 
60     pNetlogonMain(dwArgc, pszArgv);
61 }
62 
63 
64 static
65 VOID
66 WINAPI
67 SamSsControlHandler(
68     _In_ DWORD fdwControl)
69 {
70     TRACE("SamSsControlHandler(%lu)\n", fdwControl);
71 }
72 
73 
74 static
75 VOID
76 WINAPI
77 SamSsServiceMain(
78     _In_ DWORD dwArgc,
79     _In_ PWSTR *pszArgv)
80 {
81     SERVICE_STATUS_HANDLE hStatus;
82     SERVICE_STATUS ServiceStatus;
83 
84     TRACE("SamSsServiceMain(%lu %p)\n", dwArgc, pszArgv);
85 
86     hStatus = RegisterServiceCtrlHandlerW(L"SAMSS",
87                                           SamSsControlHandler);
88     if (hStatus == NULL)
89         return;
90 
91     ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
92     ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
93     ServiceStatus.dwControlsAccepted = 0;
94     ServiceStatus.dwWin32ExitCode = ERROR_SUCCESS;
95     ServiceStatus.dwServiceSpecificExitCode = ERROR_SUCCESS;
96     ServiceStatus.dwCheckPoint = 1;
97     ServiceStatus.dwWaitHint = 0x7530;
98 
99     SetServiceStatus(hStatus, &ServiceStatus);
100 
101     ServiceStatus.dwCurrentState = SERVICE_RUNNING;
102     ServiceStatus.dwCheckPoint = 0;
103     ServiceStatus.dwWaitHint = 0;
104 
105     SetServiceStatus(hStatus, &ServiceStatus);
106 }
107 
108 
109 static
110 DWORD
111 WINAPI
112 DispatcherThread(
113     _In_ PVOID pParameter)
114 {
115     HANDLE hEvent;
116     DWORD dwError;
117 
118     TRACE("DispatcherThread(%p)\n", pParameter);
119 
120     /* Create or open the SECURITY_SERVICES_STARTED event */
121     hEvent = CreateEventW(NULL,
122                           TRUE,
123                           FALSE,
124                           L"SECURITY_SERVICES_STARTED");
125     if (hEvent == NULL)
126     {
127         dwError = GetLastError();
128         if (dwError != ERROR_ALREADY_EXISTS)
129             return dwError;
130 
131         hEvent = OpenEventW(SYNCHRONIZE,
132                             FALSE,
133                             L"SECURITY_SERVICES_STARTED");
134         if (hEvent == NULL)
135             return GetLastError();
136     }
137 
138     /* Wait for the SECURITY_SERVICES_STARTED event to be signaled */
139     TRACE("Waiting for the SECURITY_SERVICES_STARTED event!\n");
140     dwError = WaitForSingleObject(hEvent, INFINITE);
141     TRACE("WaitForSingleObject returned %lu\n", dwError);
142 
143     /* Close the event handle */
144     CloseHandle(hEvent);
145 
146     /* Fail, if the event was not signaled */
147     if (dwError != WAIT_OBJECT_0)
148     {
149         ERR("Wait failed!\n");
150         return dwError;
151     }
152 
153     /* This is the security process */
154     I_ScIsSecurityProcess();
155 
156     /* Start the services */
157     TRACE("Start the security services!\n");
158     if (!StartServiceCtrlDispatcherW(ServiceTable))
159         return GetLastError();
160 
161     TRACE("Done!\n");
162 
163     return ERROR_SUCCESS;
164 }
165 
166 
167 NTSTATUS
168 WINAPI
169 ServiceInit(VOID)
170 {
171     HANDLE hThread;
172     DWORD dwThreadId;
173 
174     TRACE("ServiceInit()\n");
175 
176     hThread = CreateThread(NULL,
177                            0,
178                            DispatcherThread,
179                            NULL,
180                            0,
181                            &dwThreadId);
182     if (hThread == NULL)
183        return (NTSTATUS)GetLastError();
184 
185     return STATUS_SUCCESS;
186 }
187 
188 /* EOF */
189