xref: /reactos/base/services/svchost/globals.c (revision 3d3a5aa0)
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