1 /*
2 * PROJECT: ReactOS Service Host
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: base/services/svchost/globals.c
5 * PURPOSE: Functions to initialize global settings and support
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "svchost.h"
12
13 /* GLOBALS *******************************************************************/
14
15 PSID NullSid, WorldSid, LocalSid, NetworkSid, InteractiveSid, ServiceLogonSid;
16 PSID LocalSystemSid, LocalServiceSid, NetworkServiceSid, BuiltinDomainSid;
17 PSID AuthenticatedUserSid, AnonymousLogonSid, AliasAdminsSid, AliasUsersSid;
18 PSID AliasGuestsSid, AliasPowerUsersSid, AliasAccountOpsSid, AliasSystemOpsSid;
19 PSID AliasPrintOpsSid;
20 PSID AliasBackupOpsSid;
21
22 SID_DATA SidData[12] =
23 {
24 { &NullSid, { SECURITY_NULL_SID_AUTHORITY }, SECURITY_NULL_RID },
25 { &WorldSid, { SECURITY_WORLD_SID_AUTHORITY }, SECURITY_WORLD_RID },
26 { &LocalSid, { SECURITY_LOCAL_SID_AUTHORITY }, SECURITY_LOCAL_RID },
27 { &NetworkSid, { SECURITY_NT_AUTHORITY }, SECURITY_NETWORK_RID },
28 { &InteractiveSid, { SECURITY_NT_AUTHORITY }, SECURITY_INTERACTIVE_RID },
29 { &ServiceLogonSid, { SECURITY_NT_AUTHORITY }, SECURITY_SERVICE_RID },
30 { &LocalSystemSid, { SECURITY_NT_AUTHORITY }, SECURITY_LOCAL_SYSTEM_RID },
31 { &LocalServiceSid, { SECURITY_NT_AUTHORITY }, SECURITY_LOCAL_SERVICE_RID },
32 { &NetworkServiceSid, { SECURITY_NT_AUTHORITY }, SECURITY_NETWORK_SERVICE_RID },
33 { &BuiltinDomainSid, { SECURITY_NT_AUTHORITY }, SECURITY_BUILTIN_DOMAIN_RID },
34 { &AuthenticatedUserSid, { SECURITY_NT_AUTHORITY }, SECURITY_AUTHENTICATED_USER_RID },
35 { &AnonymousLogonSid, { SECURITY_NT_AUTHORITY }, SECURITY_ANONYMOUS_LOGON_RID },
36 };
37
38 DOMAIN_SID_DATA DomainSidData[8] =
39 {
40 { &AliasAdminsSid, DOMAIN_ALIAS_RID_ADMINS },
41 { &AliasUsersSid, DOMAIN_ALIAS_RID_USERS },
42 { &AliasGuestsSid, DOMAIN_ALIAS_RID_GUESTS },
43 { &AliasPowerUsersSid, DOMAIN_ALIAS_RID_POWER_USERS },
44 { &AliasAccountOpsSid, DOMAIN_ALIAS_RID_ACCOUNT_OPS },
45 { &AliasSystemOpsSid, DOMAIN_ALIAS_RID_SYSTEM_OPS },
46 { &AliasPrintOpsSid, DOMAIN_ALIAS_RID_PRINT_OPS },
47 { &AliasBackupOpsSid, DOMAIN_ALIAS_RID_BACKUP_OPS },
48 };
49
50 PSVCHOST_GLOBAL_DATA g_pSvchostSharedGlobals;
51 DWORD g_SvchostInitFlag;
52 HANDLE g_hHeap;
53
54 /* FUNCTIONS *****************************************************************/
55
56 VOID
57 WINAPI
MemInit(_In_ HANDLE Heap)58 MemInit (
59 _In_ HANDLE Heap
60 )
61 {
62 /* Save the heap handle */
63 g_hHeap = Heap;
64 }
65
66 BOOL
67 WINAPI
MemFree(_In_ LPVOID lpMem)68 MemFree (
69 _In_ LPVOID lpMem
70 )
71 {
72 /* Free memory back into the heap */
73 return HeapFree(g_hHeap, 0, lpMem);
74 }
75
76 PVOID
77 WINAPI
MemAlloc(_In_ DWORD dwFlags,_In_ DWORD dwBytes)78 MemAlloc (
79 _In_ DWORD dwFlags,
80 _In_ DWORD dwBytes
81 )
82 {
83 /* Allocate memory from the heap */
84 return HeapAlloc(g_hHeap, dwFlags, dwBytes);
85 }
86
87 VOID
88 WINAPI
SvchostBuildSharedGlobals(VOID)89 SvchostBuildSharedGlobals (
90 VOID
91 )
92 {
93 ASSERT(g_pSvchostSharedGlobals == NULL);
94
95 /* Is RPC initialized? */
96 if (!(g_SvchostInitFlag & SVCHOST_RPC_INIT_COMPLETE))
97 {
98 /* Nope, go initialize it */
99 if (!NT_SUCCESS(RpcpInitRpcServer())) return;
100
101 /* This is now done */
102 g_SvchostInitFlag |= SVCHOST_RPC_INIT_COMPLETE;
103 }
104
105 /* Is NetBIOS initialized? */
106 if (!(g_SvchostInitFlag & SVCHOST_NBT_INIT_COMPLETE))
107 {
108 /* Nope, set it up */
109 SvcNetBiosInit();
110
111 /* This is now done */
112 g_SvchostInitFlag |= SVCHOST_NBT_INIT_COMPLETE;
113 }
114
115 /* Do we have the global SIDs initialized? */
116 if (!(g_SvchostInitFlag & SVCHOST_SID_INIT_COMPLETE))
117 {
118 /* Create the SIDs we'll export in the global structure */
119 if (!NT_SUCCESS(ScCreateWellKnownSids())) return;
120
121 /* This is now done */
122 g_SvchostInitFlag |= SVCHOST_SID_INIT_COMPLETE;
123 }
124
125 /* Allocate memory for the globals */
126 g_pSvchostSharedGlobals = MemAlloc(HEAP_ZERO_MEMORY,
127 sizeof(*g_pSvchostSharedGlobals));
128 if (g_pSvchostSharedGlobals == NULL) return;
129
130 /* Write the pointers to the SIDs */
131 g_pSvchostSharedGlobals->NullSid = NullSid;
132 g_pSvchostSharedGlobals->WorldSid = WorldSid;
133 g_pSvchostSharedGlobals->LocalSid = LocalSid;
134 g_pSvchostSharedGlobals->NetworkSid = NetworkSid;
135 g_pSvchostSharedGlobals->LocalSystemSid = LocalSystemSid;
136 g_pSvchostSharedGlobals->LocalServiceSid = LocalServiceSid;
137 g_pSvchostSharedGlobals->NetworkServiceSid = NetworkServiceSid;
138 g_pSvchostSharedGlobals->BuiltinDomainSid = BuiltinDomainSid;
139 g_pSvchostSharedGlobals->AuthenticatedUserSid = AuthenticatedUserSid;
140 g_pSvchostSharedGlobals->AnonymousLogonSid = AnonymousLogonSid;
141 g_pSvchostSharedGlobals->AliasAdminsSid = AliasAdminsSid;
142 g_pSvchostSharedGlobals->AliasUsersSid = AliasUsersSid;
143 g_pSvchostSharedGlobals->AliasGuestsSid = AliasGuestsSid;
144 g_pSvchostSharedGlobals->AliasPowerUsersSid = AliasPowerUsersSid;
145 g_pSvchostSharedGlobals->AliasAccountOpsSid = AliasAccountOpsSid;
146 g_pSvchostSharedGlobals->AliasSystemOpsSid = AliasSystemOpsSid;
147 g_pSvchostSharedGlobals->AliasPrintOpsSid = AliasPrintOpsSid;
148 g_pSvchostSharedGlobals->AliasBackupOpsSid = AliasBackupOpsSid;
149
150 /* Write the pointers to the callbacks */
151 g_pSvchostSharedGlobals->StartRpcServer = RpcpStartRpcServer;
152 g_pSvchostSharedGlobals->StopRpcServer = RpcpStopRpcServer;
153 g_pSvchostSharedGlobals->StopRpcServerEx = RpcpStopRpcServerEx;
154 g_pSvchostSharedGlobals->NetBiosOpen = SvcNetBiosOpen;
155 g_pSvchostSharedGlobals->NetBiosClose = SvcNetBiosClose;
156 g_pSvchostSharedGlobals->NetBiosReset = SvcNetBiosReset;
157 g_pSvchostSharedGlobals->RegisterStopCallback = SvcRegisterStopCallback;
158 }
159
160 VOID
161 WINAPI
SvchostCharLowerW(_In_ LPCWSTR lpSrcStr)162 SvchostCharLowerW (
163 _In_ LPCWSTR lpSrcStr
164 )
165 {
166 DWORD cchSrc;
167
168 /* If there's nothing to do, bail out */
169 if (lpSrcStr == NULL) return;
170
171 /* Get the length of the input string */
172 cchSrc = wcslen(lpSrcStr);
173
174 /* Call the locale API to lower-case it */
175 if (LCMapStringW(LANG_USER_DEFAULT,
176 LCMAP_LOWERCASE,
177 lpSrcStr,
178 cchSrc + 1,
179 (LPWSTR)lpSrcStr,
180 cchSrc + 1) == FALSE)
181 {
182 DBG_ERR("SvchostCharLowerW failed for %ws\n", lpSrcStr);
183 }
184 }
185
186 NTSTATUS
187 NTAPI
ScDomainIdToSid(_In_ PSID SourceSid,_In_ ULONG DomainId,_Out_ PSID * DestinationSid)188 ScDomainIdToSid (
189 _In_ PSID SourceSid,
190 _In_ ULONG DomainId,
191 _Out_ PSID *DestinationSid
192 )
193 {
194 ULONG sidCount, sidLength;
195 NTSTATUS status;
196
197 /* Get the length of the SID based onthe number of subauthorities */
198 sidCount = *RtlSubAuthorityCountSid(SourceSid);
199 sidLength = RtlLengthRequiredSid(sidCount + 1);
200
201 /* Allocate it */
202 *DestinationSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, sidLength);
203 if (*DestinationSid)
204 {
205 /* Make a copy of it */
206 status = RtlCopySid(sidLength, *DestinationSid, SourceSid);
207 if (NT_SUCCESS(status))
208 {
209 /* Increase the subauthority count */
210 ++*RtlSubAuthorityCountSid(*DestinationSid);
211
212 /* And add the specific domain RID we're creating */
213 *RtlSubAuthoritySid(*DestinationSid, sidCount) = DomainId;
214
215 /* Everything worked */
216 status = STATUS_SUCCESS;
217 }
218 else
219 {
220 /* The SID copy failed, so free the SID we just allocated */
221 RtlFreeHeap(RtlGetProcessHeap(), 0, *DestinationSid);
222 }
223 }
224 else
225 {
226 /* No space for the SID, bail out */
227 status = STATUS_NO_MEMORY;
228 }
229
230 /* Return back to the caller */
231 return status;
232 }
233
234 NTSTATUS
235 NTAPI
ScAllocateAndInitializeSid(_Out_ PSID * Sid,_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,_In_ ULONG SubAuthorityCount)236 ScAllocateAndInitializeSid (
237 _Out_ PSID *Sid,
238 _In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
239 _In_ ULONG SubAuthorityCount
240 )
241 {
242 NTSTATUS Status;
243
244 /* Allocate room for the SID */
245 *Sid = RtlAllocateHeap(RtlGetProcessHeap(),
246 0,
247 RtlLengthRequiredSid(SubAuthorityCount));
248 if (*Sid)
249 {
250 /* Initialize it, we're done */
251 RtlInitializeSid(*Sid, IdentifierAuthority, SubAuthorityCount);
252 Status = STATUS_SUCCESS;
253 }
254 else
255 {
256 /* No memory, we'll fail */
257 Status = STATUS_NO_MEMORY;
258 }
259
260 /* Return what happened */
261 return Status;
262 }
263
264 NTSTATUS
265 NTAPI
ScCreateWellKnownSids(VOID)266 ScCreateWellKnownSids (
267 VOID
268 )
269 {
270 ULONG i;
271 NTSTATUS Status;
272
273 /* Loop the non-domain SIDs */
274 for (i = 0; i < RTL_NUMBER_OF(SidData); i++)
275 {
276 /* Convert our optimized structure into an actual SID */
277 Status = ScAllocateAndInitializeSid(SidData[i].Sid,
278 &SidData[i].Authority,
279 1);
280
281 if (!NT_SUCCESS(Status))
282 {
283 DBG_ERR("ScAllocateAndInitializeSid failed for %u\n", i);
284 break;
285 }
286
287 /* Write the correct sub-authority */
288 *RtlSubAuthoritySid(*SidData[i].Sid, 0) = SidData[i].SubAuthority;
289 }
290
291 /* Now loop the domain SIDs */
292 for (i = 0; i < RTL_NUMBER_OF(DomainSidData); i++)
293 {
294 /* Convert our optimized structure into an actual SID */
295 Status = ScDomainIdToSid(BuiltinDomainSid,
296 DomainSidData[i].SubAuthority,
297 DomainSidData[i].Sid);
298 if (!NT_SUCCESS(Status))
299 {
300 DBG_ERR("ScDomainIdToSid failed for %u\n", i);
301 break;
302 }
303 }
304
305 /* If we got to the end, return success */
306 return (i == RTL_NUMBER_OF(DomainSidData)) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
307 }
308
309