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 58 MemInit ( 59 _In_ HANDLE Heap 60 ) 61 { 62 /* Save the heap handle */ 63 g_hHeap = Heap; 64 } 65 66 BOOL 67 WINAPI 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 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 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 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 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 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 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