Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninit.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS CSR Sub System 00004 * FILE: subsys/csr/csrsrv/init.c 00005 * PURPOSE: CSR Server DLL Initialization 00006 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include "srv.h" 00012 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* DATA **********************************************************************/ 00017 00018 HANDLE CsrObjectDirectory; 00019 ULONG SessionId; 00020 BOOLEAN CsrProfileControl; 00021 UNICODE_STRING CsrDirectoryName; 00022 HANDLE CsrHeap; 00023 HANDLE BNOLinksDirectory; 00024 HANDLE SessionObjectDirectory; 00025 HANDLE DosDevicesDirectory; 00026 HANDLE CsrInitializationEvent; 00027 SYSTEM_BASIC_INFORMATION CsrNtSysInfo; 00028 ULONG CsrDebug; 00029 00030 /* PRIVATE FUNCTIONS *********************************************************/ 00031 00032 /*++ 00033 * @name CsrParseServerCommandLine 00034 * 00035 * The CsrParseServerCommandLine routine parses the CSRSS command-line in the 00036 * registry and performs operations for each entry found. 00037 * 00038 * @param ArgumentCount 00039 * Number of arguments on the command line. 00040 * 00041 * @param Arguments 00042 * Array of arguments. 00043 * 00044 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00045 * othwerwise. 00046 * 00047 * @remarks None. 00048 * 00049 *--*/ 00050 NTSTATUS 00051 FASTCALL 00052 CsrParseServerCommandLine(IN ULONG ArgumentCount, 00053 IN PCHAR Arguments[]) 00054 { 00055 NTSTATUS Status; 00056 PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; 00057 ULONG i, DllIndex; 00058 ANSI_STRING AnsiString; 00059 OBJECT_ATTRIBUTES ObjectAttributes; 00060 00061 /* Set the Defaults */ 00062 CsrTotalPerProcessDataLength = 0; 00063 CsrObjectDirectory = 0; 00064 CsrMaxApiRequestThreads = 16; 00065 00066 /* Save our Session ID, and create a Directory for it */ 00067 SessionId = NtCurrentPeb()->SessionId; 00068 Status = CsrCreateSessionObjectDirectory(SessionId); 00069 if (!NT_SUCCESS(Status)) 00070 { 00071 DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", 00072 Status); 00073 00074 /* It's not fatal if the session ID isn't zero */ 00075 if (SessionId) return Status; 00076 ASSERT(NT_SUCCESS(Status)); 00077 } 00078 00079 /* Loop through every argument */ 00080 for (i = 1; i < ArgumentCount; i++) 00081 { 00082 /* Split Name and Value */ 00083 ParameterName = Arguments[i]; 00084 ParameterValue = NULL; 00085 ParameterValue = strchr(ParameterName, '='); 00086 if (ParameterValue) *ParameterValue++ = ANSI_NULL; 00087 DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue); 00088 00089 /* Check for Object Directory */ 00090 if (!_stricmp(ParameterName, "ObjectDirectory")) 00091 { 00092 /* Check if a session ID is specified */ 00093 if (SessionId) 00094 { 00095 DPRINT1("Sessions not yet implemented\n"); 00096 ASSERT(SessionId); 00097 } 00098 00099 /* Initialize the directory name */ 00100 RtlInitAnsiString(&AnsiString, ParameterValue); 00101 Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, 00102 &AnsiString, 00103 TRUE); 00104 ASSERT(NT_SUCCESS(Status) || SessionId != 0); 00105 if (!NT_SUCCESS(Status)) return Status; 00106 00107 /* Create it */ 00108 InitializeObjectAttributes(&ObjectAttributes, 00109 &CsrDirectoryName, 00110 OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 00111 NULL, 00112 NULL); 00113 Status = NtCreateDirectoryObject(&CsrObjectDirectory, 00114 DIRECTORY_ALL_ACCESS, 00115 &ObjectAttributes); 00116 if (!NT_SUCCESS(Status)) return Status; 00117 00118 /* Secure it */ 00119 Status = CsrSetDirectorySecurity(CsrObjectDirectory); 00120 if (!NT_SUCCESS(Status)) return Status; 00121 } 00122 else if (!_stricmp(ParameterName, "SubSystemType")) 00123 { 00124 /* Ignored */ 00125 } 00126 else if (!_stricmp(ParameterName, "MaxRequestThreads")) 00127 { 00128 Status = RtlCharToInteger(ParameterValue, 00129 0, 00130 &CsrMaxApiRequestThreads); 00131 } 00132 else if (!_stricmp(ParameterName, "RequestThreads")) 00133 { 00134 /* Ignored */ 00135 Status = STATUS_SUCCESS; 00136 } 00137 else if (!_stricmp(ParameterName, "ProfileControl")) 00138 { 00139 /* Ignored */ 00140 } 00141 else if (!_stricmp(ParameterName, "SharedSection")) 00142 { 00143 /* Craete the Section */ 00144 Status = CsrSrvCreateSharedSection(ParameterValue); 00145 if (!NT_SUCCESS(Status)) 00146 { 00147 DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n", 00148 ParameterName, ParameterValue, Status); 00149 return Status; 00150 } 00151 00152 /* Load us */ 00153 Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER); 00154 } 00155 else if (!_stricmp(ParameterName, "ServerDLL")) 00156 { 00157 /* Loop the command line */ 00158 EntryPoint = NULL; 00159 Status = STATUS_INVALID_PARAMETER; 00160 ServerString = ParameterValue; 00161 while (*ServerString) 00162 { 00163 /* Check for the Entry Point */ 00164 if ((*ServerString == ':') && (!EntryPoint)) 00165 { 00166 /* Found it. Add a nullchar and save it */ 00167 *ServerString++ = ANSI_NULL; 00168 EntryPoint = ServerString; 00169 } 00170 00171 /* Check for the Dll Index */ 00172 if (*ServerString++ == ',') break; 00173 } 00174 00175 /* Did we find something to load? */ 00176 if (!*ServerString) 00177 { 00178 DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", 00179 ParameterValue, Status); 00180 return Status; 00181 } 00182 00183 /* Convert it to a ULONG */ 00184 Status = RtlCharToInteger(ServerString, 10, &DllIndex); 00185 00186 /* Add a null char if it was valid */ 00187 if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; 00188 00189 /* Load it */ 00190 if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); 00191 Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); 00192 if (!NT_SUCCESS(Status)) 00193 { 00194 DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", 00195 ParameterValue, Status); 00196 return Status; 00197 } 00198 } 00199 else if (!_stricmp(ParameterName, "Windows")) 00200 { 00201 /* Ignored */ 00202 } 00203 else 00204 { 00205 /* Invalid parameter on the command line */ 00206 Status = STATUS_INVALID_PARAMETER; 00207 } 00208 } 00209 00210 /* Return status */ 00211 return Status; 00212 } 00213 00214 /*++ 00215 * @name CsrCreateLocalSystemSD 00216 * 00217 * The CsrCreateLocalSystemSD routine creates a Security Descriptor for 00218 * the local account with PORT_ALL_ACCESS. 00219 * 00220 * @param LocalSystemSd 00221 * Pointer to a pointer to the security descriptor to create. 00222 * 00223 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00224 * othwerwise. 00225 * 00226 * @remarks None. 00227 * 00228 *--*/ 00229 NTSTATUS 00230 NTAPI 00231 CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd) 00232 { 00233 SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; 00234 PSID SystemSid; 00235 ULONG Length; 00236 PSECURITY_DESCRIPTOR SystemSd; 00237 PACL Dacl; 00238 NTSTATUS Status; 00239 00240 /* Initialize the System SID */ 00241 RtlAllocateAndInitializeSid(&NtSidAuthority, 1, 00242 SECURITY_LOCAL_SYSTEM_RID, 00243 0, 0, 0, 0, 0, 0, 0, 00244 &SystemSid); 00245 00246 /* Get the length of the SID */ 00247 Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 00248 00249 /* Allocate a buffer for the Security Descriptor, with SID and DACL */ 00250 SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); 00251 00252 /* Set the pointer to the DACL */ 00253 Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH); 00254 00255 /* Now create the SD itself */ 00256 Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION); 00257 if (!NT_SUCCESS(Status)) 00258 { 00259 /* Fail */ 00260 RtlFreeHeap(CsrHeap, 0, SystemSd); 00261 return Status; 00262 } 00263 00264 /* Create the DACL for it*/ 00265 RtlCreateAcl(Dacl, Length, ACL_REVISION2); 00266 00267 /* Create the ACE */ 00268 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid); 00269 if (!NT_SUCCESS(Status)) 00270 { 00271 /* Fail */ 00272 RtlFreeHeap(CsrHeap, 0, SystemSd); 00273 return Status; 00274 } 00275 00276 /* Clear the DACL in the SD */ 00277 Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE); 00278 if (!NT_SUCCESS(Status)) 00279 { 00280 /* Fail */ 00281 RtlFreeHeap(CsrHeap, 0, SystemSd); 00282 return Status; 00283 } 00284 00285 /* Free the SID and return*/ 00286 RtlFreeSid(SystemSid); 00287 *LocalSystemSd = SystemSd; 00288 return Status; 00289 } 00290 00291 /*++ 00292 * @name GetDosDevicesProtection 00293 * 00294 * The GetDosDevicesProtection creates a security descriptor for the DOS Devices 00295 * Object Directory. 00296 * 00297 * @param DosDevicesSd 00298 * Pointer to the Security Descriptor to return. 00299 * 00300 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00301 * othwerwise. 00302 * 00303 * @remarks Depending on the DOS Devices Protection Mode (set in the registry), 00304 * regular users may or may not have full access to the directory. 00305 * 00306 *--*/ 00307 NTSTATUS 00308 NTAPI 00309 GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd) 00310 { 00311 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; 00312 SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY}; 00313 SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY}; 00314 PSID WorldSid, CreatorSid, AdminSid, SystemSid; 00315 UCHAR KeyValueBuffer[0x40]; 00316 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; 00317 UNICODE_STRING KeyName; 00318 ULONG ProtectionMode = 0; 00319 OBJECT_ATTRIBUTES ObjectAttributes; 00320 PACL Dacl; 00321 PACCESS_ALLOWED_ACE Ace; 00322 HANDLE hKey; 00323 NTSTATUS Status; 00324 ULONG ResultLength, SidLength, AclLength; 00325 00326 /* Create the SD */ 00327 Status = RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION); 00328 ASSERT(NT_SUCCESS(Status)); 00329 00330 /* Initialize the System SID */ 00331 Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 1, 00332 SECURITY_LOCAL_SYSTEM_RID, 00333 0, 0, 0, 0, 0, 0, 0, 00334 &SystemSid); 00335 ASSERT(NT_SUCCESS(Status)); 00336 00337 /* Initialize the World SID */ 00338 Status = RtlAllocateAndInitializeSid(&WorldAuthority, 1, 00339 SECURITY_WORLD_RID, 00340 0, 0, 0, 0, 0, 0, 0, 00341 &WorldSid); 00342 ASSERT(NT_SUCCESS(Status)); 00343 00344 /* Initialize the Admin SID */ 00345 Status = RtlAllocateAndInitializeSid(&NtSidAuthority, 2, 00346 SECURITY_BUILTIN_DOMAIN_RID, 00347 DOMAIN_ALIAS_RID_ADMINS, 00348 0, 0, 0, 0, 0, 0, 00349 &AdminSid); 00350 ASSERT(NT_SUCCESS(Status)); 00351 00352 /* Initialize the Creator SID */ 00353 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1, 00354 SECURITY_CREATOR_OWNER_RID, 00355 0, 0, 0, 0, 0, 0, 0, 00356 &CreatorSid); 00357 ASSERT(NT_SUCCESS(Status)); 00358 00359 /* Open the Session Manager Key */ 00360 RtlInitUnicodeString(&KeyName, SM_REG_KEY); 00361 InitializeObjectAttributes(&ObjectAttributes, 00362 &KeyName, 00363 OBJ_CASE_INSENSITIVE, 00364 NULL, 00365 NULL); 00366 Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes); 00367 if (NT_SUCCESS(Status)) 00368 { 00369 /* Read the key value */ 00370 RtlInitUnicodeString(&KeyName, L"ProtectionMode"); 00371 Status = NtQueryValueKey(hKey, 00372 &KeyName, 00373 KeyValuePartialInformation, 00374 KeyValueBuffer, 00375 sizeof(KeyValueBuffer), 00376 &ResultLength); 00377 00378 /* Make sure it's what we expect it to be */ 00379 KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; 00380 if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) && 00381 (*(PULONG)KeyValuePartialInfo->Data)) 00382 { 00383 /* Save the Protection Mode */ 00384 ProtectionMode = *(PULONG)KeyValuePartialInfo->Data; 00385 } 00386 00387 /* Close the handle */ 00388 NtClose(hKey); 00389 } 00390 00391 /* Check the Protection Mode */ 00392 if (ProtectionMode & 3) 00393 { 00394 /* Calculate SID Lengths */ 00395 SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) + 00396 RtlLengthSid(AdminSid); 00397 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; 00398 00399 /* Allocate memory for the DACL */ 00400 Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); 00401 ASSERT(Dacl != NULL); 00402 00403 /* Build the ACL and add 3 ACEs */ 00404 Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); 00405 ASSERT(NT_SUCCESS(Status)); 00406 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); 00407 ASSERT(NT_SUCCESS(Status)); 00408 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid); 00409 ASSERT(NT_SUCCESS(Status)); 00410 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid); 00411 ASSERT(NT_SUCCESS(Status)); 00412 00413 /* Edit the ACEs to make them inheritable */ 00414 Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace); 00415 ASSERT(NT_SUCCESS(Status)); 00416 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 00417 Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace); 00418 ASSERT(NT_SUCCESS(Status)); 00419 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 00420 Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); 00421 ASSERT(NT_SUCCESS(Status)); 00422 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; 00423 00424 /* Set this DACL with the SD */ 00425 Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); 00426 ASSERT(NT_SUCCESS(Status)); 00427 goto Quickie; 00428 } 00429 else 00430 { 00431 /* Calculate SID Lengths */ 00432 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid); 00433 AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength; 00434 00435 /* Allocate memory for the DACL */ 00436 Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength); 00437 ASSERT(Dacl != NULL); 00438 00439 /* Build the ACL and add 3 ACEs */ 00440 Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2); 00441 ASSERT(NT_SUCCESS(Status)); 00442 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid); 00443 ASSERT(NT_SUCCESS(Status)); 00444 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid); 00445 ASSERT(NT_SUCCESS(Status)); 00446 Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid); 00447 ASSERT(NT_SUCCESS(Status)); 00448 00449 /* Edit the last ACE to make it inheritable */ 00450 Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace); 00451 ASSERT(NT_SUCCESS(Status)); 00452 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE; 00453 00454 /* Set this DACL with the SD */ 00455 Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE); 00456 ASSERT(NT_SUCCESS(Status)); 00457 goto Quickie; 00458 } 00459 00460 /* FIXME: failure cases! Fail: */ 00461 /* Free the memory */ 00462 RtlFreeHeap(CsrHeap, 0, Dacl); 00463 00464 /* FIXME: semi-failure cases! Quickie: */ 00465 Quickie: 00466 /* Free the SIDs */ 00467 RtlFreeSid(SystemSid); 00468 RtlFreeSid(WorldSid); 00469 RtlFreeSid(AdminSid); 00470 RtlFreeSid(CreatorSid); 00471 00472 /* Return */ 00473 return Status; 00474 } 00475 00476 /*++ 00477 * @name FreeDosDevicesProtection 00478 * 00479 * The FreeDosDevicesProtection frees the security descriptor that was created 00480 * by GetDosDevicesProtection 00481 * 00482 * @param DosDevicesSd 00483 * Pointer to the security descriptor to free. 00484 00485 * @return None. 00486 * 00487 * @remarks None. 00488 * 00489 *--*/ 00490 VOID 00491 NTAPI 00492 FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd) 00493 { 00494 PACL Dacl; 00495 BOOLEAN Present, Default; 00496 NTSTATUS Status; 00497 00498 /* Get the DACL corresponding to this SD */ 00499 Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default); 00500 ASSERT(NT_SUCCESS(Status)); 00501 ASSERT(Present); 00502 ASSERT(Dacl != NULL); 00503 00504 /* Free it */ 00505 if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl); 00506 } 00507 00508 /*++ 00509 * @name CsrCreateSessionObjectDirectory 00510 * 00511 * The CsrCreateSessionObjectDirectory routine creates the BaseNamedObjects, 00512 * Session and Dos Devices directories for the specified session. 00513 * 00514 * @param Session 00515 * Session ID for which to create the directories. 00516 * 00517 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00518 * othwerwise. 00519 * 00520 * @remarks None. 00521 * 00522 *--*/ 00523 NTSTATUS 00524 NTAPI 00525 CsrCreateSessionObjectDirectory(IN ULONG Session) 00526 { 00527 WCHAR SessionBuffer[512], BnoBuffer[512]; 00528 UNICODE_STRING SessionString, BnoString; 00529 OBJECT_ATTRIBUTES ObjectAttributes; 00530 HANDLE BnoHandle; 00531 SECURITY_DESCRIPTOR DosDevicesSd; 00532 NTSTATUS Status; 00533 00534 /* Generate the Session BNOLINKS Directory name */ 00535 swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT); 00536 RtlInitUnicodeString(&SessionString, SessionBuffer); 00537 00538 /* Create it */ 00539 InitializeObjectAttributes(&ObjectAttributes, 00540 &SessionString, 00541 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00542 NULL, 00543 NULL); 00544 Status = NtCreateDirectoryObject(&BNOLinksDirectory, 00545 DIRECTORY_ALL_ACCESS, 00546 &ObjectAttributes); 00547 if (!NT_SUCCESS(Status)) 00548 { 00549 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00550 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00551 return Status; 00552 } 00553 00554 /* Now add the Session ID */ 00555 swprintf(SessionBuffer, L"%ld", Session); 00556 RtlInitUnicodeString(&SessionString, SessionBuffer); 00557 00558 /* Check if this is the first Session */ 00559 if (Session) 00560 { 00561 /* Not the first, so the name will be slighly more complex */ 00562 swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session); 00563 RtlInitUnicodeString(&BnoString, BnoBuffer); 00564 } 00565 else 00566 { 00567 /* Use the direct name */ 00568 RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); 00569 } 00570 00571 /* Create the symlink */ 00572 InitializeObjectAttributes(&ObjectAttributes, 00573 &SessionString, 00574 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00575 BNOLinksDirectory, 00576 NULL); 00577 Status = NtCreateSymbolicLinkObject(&BnoHandle, 00578 SYMBOLIC_LINK_ALL_ACCESS, 00579 &ObjectAttributes, 00580 &BnoString); 00581 if (!NT_SUCCESS(Status)) 00582 { 00583 DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in " 00584 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00585 return Status; 00586 } 00587 00588 /* Create the \DosDevices Security Descriptor */ 00589 Status = GetDosDevicesProtection(&DosDevicesSd); 00590 if (!NT_SUCCESS(Status)) return Status; 00591 00592 /* Now create a directory for this session */ 00593 swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session); 00594 RtlInitUnicodeString(&SessionString, SessionBuffer); 00595 00596 /* Create the directory */ 00597 InitializeObjectAttributes(&ObjectAttributes, 00598 &SessionString, 00599 OBJ_OPENIF | OBJ_CASE_INSENSITIVE, 00600 0, 00601 &DosDevicesSd); 00602 Status = NtCreateDirectoryObject(&SessionObjectDirectory, 00603 DIRECTORY_ALL_ACCESS, 00604 &ObjectAttributes); 00605 if (!NT_SUCCESS(Status)) 00606 { 00607 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00608 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00609 FreeDosDevicesProtection(&DosDevicesSd); 00610 return Status; 00611 } 00612 00613 /* Next, create a directory for this session's DOS Devices */ 00614 RtlInitUnicodeString(&SessionString, L"DosDevices"); 00615 InitializeObjectAttributes(&ObjectAttributes, 00616 &SessionString, 00617 OBJ_CASE_INSENSITIVE, 00618 SessionObjectDirectory, 00619 &DosDevicesSd); 00620 Status = NtCreateDirectoryObject(&DosDevicesDirectory, 00621 DIRECTORY_ALL_ACCESS, 00622 &ObjectAttributes); 00623 if (!NT_SUCCESS(Status)) 00624 { 00625 DPRINT1("CSRSS: NtCreateDirectoryObject failed in " 00626 "CsrCreateSessionObjectDirectory - status = %lx\n", Status); 00627 } 00628 00629 /* Release the Security Descriptor */ 00630 FreeDosDevicesProtection(&DosDevicesSd); 00631 00632 /* Return */ 00633 return Status; 00634 } 00635 00636 /*++ 00637 * @name CsrSetProcessSecurity 00638 * 00639 * The CsrSetProcessSecurity routine protects access to the CSRSS process 00640 * from unauthorized tampering. 00641 * 00642 * @param None. 00643 * 00644 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00645 * othwerwise. 00646 * 00647 * @remarks None. 00648 * 00649 *--*/ 00650 NTSTATUS 00651 NTAPI 00652 CsrSetProcessSecurity(VOID) 00653 { 00654 NTSTATUS Status; 00655 HANDLE hToken, hProcess = NtCurrentProcess(); 00656 ULONG ReturnLength, Length; 00657 PTOKEN_USER TokenInfo = NULL; 00658 PSECURITY_DESCRIPTOR ProcSd = NULL; 00659 PACL Dacl; 00660 PSID UserSid; 00661 00662 /* Open our token */ 00663 Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken); 00664 if (!NT_SUCCESS(Status)) goto Quickie; 00665 00666 /* Get the Token User Length */ 00667 NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length); 00668 00669 /* Allocate space for it */ 00670 TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length); 00671 if (!TokenInfo) 00672 { 00673 Status = STATUS_NO_MEMORY; 00674 goto Quickie; 00675 } 00676 00677 /* Now query the data */ 00678 Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length); 00679 NtClose(hToken); 00680 if (!NT_SUCCESS(Status)) goto Quickie; 00681 00682 /* Now check the SID Length */ 00683 UserSid = TokenInfo->User.Sid; 00684 ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE); 00685 00686 /* Allocate a buffer for the Security Descriptor, with SID and DACL */ 00687 ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length); 00688 if (!ProcSd) 00689 { 00690 Status = STATUS_NO_MEMORY; 00691 goto Quickie; 00692 } 00693 00694 /* Set the pointer to the DACL */ 00695 Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH); 00696 00697 /* Now create the SD itself */ 00698 Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION); 00699 if (!NT_SUCCESS(Status)) goto Quickie; 00700 00701 /* Create the DACL for it*/ 00702 RtlCreateAcl(Dacl, Length, ACL_REVISION2); 00703 00704 /* Create the ACE */ 00705 Status = RtlAddAccessAllowedAce(Dacl, 00706 ACL_REVISION, 00707 PROCESS_VM_READ | PROCESS_VM_WRITE | 00708 PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE | 00709 PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME | 00710 PROCESS_QUERY_INFORMATION | READ_CONTROL, 00711 UserSid); 00712 if (!NT_SUCCESS(Status)) goto Quickie; 00713 00714 /* Clear the DACL in the SD */ 00715 Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE); 00716 if (!NT_SUCCESS(Status)) goto Quickie; 00717 00718 /* Write the SD into the Process */ 00719 Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd); 00720 00721 /* Free the memory and return */ 00722 Quickie: 00723 if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd); 00724 RtlFreeHeap(CsrHeap, 0, TokenInfo); 00725 return Status; 00726 } 00727 00728 /*++ 00729 * @name CsrSetDirectorySecurity 00730 * 00731 * The CsrSetDirectorySecurity routine sets the security descriptor for the 00732 * specified Object Directory. 00733 * 00734 * @param ObjectDirectory 00735 * Handle fo the Object Directory to protect. 00736 * 00737 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00738 * othwerwise. 00739 * 00740 * @remarks None. 00741 * 00742 *--*/ 00743 NTSTATUS 00744 NTAPI 00745 CsrSetDirectorySecurity(IN HANDLE ObjectDirectory) 00746 { 00747 /* FIXME: Implement */ 00748 return STATUS_SUCCESS; 00749 } 00750 00751 /* PUBLIC FUNCTIONS **********************************************************/ 00752 00753 /*++ 00754 * @name CsrServerInitialization 00755 * @implemented NT4 00756 * 00757 * The CsrServerInitialization routine is the native (not Server) entrypoint 00758 * of this Server DLL. It serves as the entrypoint for csrss. 00759 * 00760 * @param ArgumentCount 00761 * Number of arguments on the command line. 00762 * 00763 * @param Arguments 00764 * Array of arguments from the command line. 00765 * 00766 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00767 * othwerwise. 00768 * 00769 * @remarks None. 00770 * 00771 *--*/ 00772 NTSTATUS 00773 NTAPI 00774 CsrServerInitialization(IN ULONG ArgumentCount, 00775 IN PCHAR Arguments[]) 00776 { 00777 NTSTATUS Status = STATUS_SUCCESS; 00778 ULONG i = 0; 00779 PVOID ProcessData; 00780 PCSR_SERVER_DLL ServerDll; 00781 DPRINT("CSRSRV: %s called\n", __FUNCTION__); 00782 00783 /* Create the Init Event */ 00784 Status = NtCreateEvent(&CsrInitializationEvent, 00785 EVENT_ALL_ACCESS, 00786 NULL, 00787 SynchronizationEvent, 00788 FALSE); 00789 if (!NT_SUCCESS(Status)) 00790 { 00791 DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n", 00792 __FUNCTION__, Status); 00793 return Status; 00794 } 00795 00796 /* Cache System Basic Information so we don't always request it */ 00797 Status = NtQuerySystemInformation(SystemBasicInformation, 00798 &CsrNtSysInfo, 00799 sizeof(SYSTEM_BASIC_INFORMATION), 00800 NULL); 00801 if (!NT_SUCCESS(Status)) 00802 { 00803 DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n", 00804 __FUNCTION__, Status); 00805 return Status; 00806 } 00807 00808 /* Save our Heap */ 00809 CsrHeap = RtlGetProcessHeap(); 00810 00811 /* Set our Security Descriptor to protect the process */ 00812 Status = CsrSetProcessSecurity(); 00813 if (!NT_SUCCESS(Status)) 00814 { 00815 DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n", 00816 __FUNCTION__, Status); 00817 return Status; 00818 } 00819 00820 /* Set up Session Support */ 00821 Status = CsrInitializeNtSessionList(); 00822 if (!NT_SUCCESS(Status)) 00823 { 00824 DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n", 00825 __FUNCTION__, Status); 00826 return Status; 00827 } 00828 00829 /* Set up Process Support */ 00830 Status = CsrInitializeProcessStructure(); 00831 if (!NT_SUCCESS(Status)) 00832 { 00833 DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n", 00834 __FUNCTION__, Status); 00835 return Status; 00836 } 00837 00838 /* Parse the command line */ 00839 Status = CsrParseServerCommandLine(ArgumentCount, Arguments); 00840 if (!NT_SUCCESS(Status)) 00841 { 00842 DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n", 00843 __FUNCTION__, Status); 00844 return Status; 00845 } 00846 00847 /* All Server DLLs are now loaded, allocate a heap for the Root Process */ 00848 ProcessData = RtlAllocateHeap(CsrHeap, 00849 HEAP_ZERO_MEMORY, 00850 CsrTotalPerProcessDataLength); 00851 if (!ProcessData) 00852 { 00853 DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n", 00854 __FUNCTION__, STATUS_NO_MEMORY); 00855 return STATUS_NO_MEMORY; 00856 } 00857 00858 /* 00859 * Our Root Process was never officially initalized, so write the data 00860 * for each Server DLL manually. 00861 */ 00862 for (i = 0; i < CSR_SERVER_DLL_MAX; i++) 00863 { 00864 /* Get the current Server */ 00865 ServerDll = CsrLoadedServerDll[i]; 00866 00867 /* Is it loaded, and does it have per process data? */ 00868 if ((ServerDll) && (ServerDll->SizeOfProcessData)) 00869 { 00870 /* It does, give it part of our allocated heap */ 00871 CsrRootProcess->ServerData[i] = ProcessData; 00872 00873 /* Move to the next heap position */ 00874 ProcessData = (PVOID)((ULONG_PTR)ProcessData + 00875 ServerDll->SizeOfProcessData); 00876 } 00877 else 00878 { 00879 /* Nothing for this Server DLL */ 00880 CsrRootProcess->ServerData[i] = NULL; 00881 } 00882 } 00883 00884 /* Now initialize the Root Process manually as well */ 00885 for (i = 0; i < CSR_SERVER_DLL_MAX; i++) 00886 { 00887 /* Get the current Server */ 00888 ServerDll = CsrLoadedServerDll[i]; 00889 00890 /* Is it loaded, and does it a callback for new processes? */ 00891 if ((ServerDll) && (ServerDll->NewProcessCallback)) 00892 { 00893 /* Call the callback */ 00894 ServerDll->NewProcessCallback(NULL, CsrRootProcess); 00895 } 00896 } 00897 00898 /* Now initialize our API Port */ 00899 Status = CsrApiPortInitialize(); 00900 if (!NT_SUCCESS(Status)) 00901 { 00902 DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n", 00903 __FUNCTION__, Status); 00904 return Status; 00905 } 00906 00907 /* Initialize the API Port for SM communication */ 00908 Status = CsrSbApiPortInitialize(); 00909 if (!NT_SUCCESS(Status)) 00910 { 00911 DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n", 00912 __FUNCTION__, Status); 00913 return Status; 00914 } 00915 00916 /* We're all set! Connect to SM! */ 00917 Status = SmConnectToSm(&CsrSbApiPortName, 00918 CsrSbApiPort, 00919 IMAGE_SUBSYSTEM_WINDOWS_GUI, 00920 &CsrSmApiPort); 00921 if (!NT_SUCCESS(Status)) 00922 { 00923 DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n", 00924 __FUNCTION__, Status); 00925 return Status; 00926 } 00927 00928 /* Finito! Signal the event */ 00929 Status = NtSetEvent(CsrInitializationEvent, NULL); 00930 if (!NT_SUCCESS(Status)) 00931 { 00932 DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n", 00933 __FUNCTION__, Status); 00934 return Status; 00935 } 00936 00937 /* Close the event handle now */ 00938 NtClose(CsrInitializationEvent); 00939 00940 /* Have us handle Hard Errors */ 00941 Status = NtSetDefaultHardErrorPort(CsrApiPort); 00942 if (!NT_SUCCESS(Status)) 00943 { 00944 DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n", 00945 __FUNCTION__, Status); 00946 return Status; 00947 } 00948 00949 /* Return status */ 00950 return Status; 00951 } 00952 00953 /*++ 00954 * @name CsrPopulateDosDevices 00955 * @unimplemented NT5.1 00956 * 00957 * The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel 00958 * to populate the Dos Devices Object Directory for the session. 00959 * 00960 * @param None. 00961 * 00962 * @return None. 00963 * 00964 * @remarks None. 00965 * 00966 *--*/ 00967 VOID 00968 NTAPI 00969 CsrPopulateDosDevices(VOID) 00970 { 00971 DPRINT1("Deprecated API\n"); 00972 return; 00973 } 00974 00975 BOOL 00976 NTAPI 00977 DllMain(IN HANDLE hDll, 00978 IN DWORD dwReason, 00979 IN LPVOID lpReserved) 00980 { 00981 /* We don't do much */ 00982 UNREFERENCED_PARAMETER(hDll); 00983 UNREFERENCED_PARAMETER(dwReason); 00984 UNREFERENCED_PARAMETER(lpReserved); 00985 return TRUE; 00986 } 00987 00988 /* EOF */ Generated on Sun May 27 2012 04:23:32 for ReactOS by
1.7.6.1
|