static NTSTATUS V2vkConnectorProcessInternalSyncTx(V2VK_CONNECTOR_CONTEXT *vcc) { NTSTATUS status; unsigned available; volatile UCHAR *msg; size_t msize; V2V_FRAME_HEADER *header; V2V_POST_INTERNAL *vpi; DbgPrint("%s connector(%p) sending internal message #%d\n", V2VDRV_LOGTAG, vcc, vcc->txCounter + 1); available = v2v_nc2_producer_bytes_available(vcc->channel); DbgPrint("%s connector(%p) channel indicates minimum bytes available: 0x%x\n", V2VDRV_LOGTAG, vcc, available); if ((vcc->flags & V2V_KERNEL_FASTRX) && v2v_nc2_remote_requested_fast_wakeup(vcc->channel)) msize = MIN(vcc->xferSize, vcc->xferMaxFastRx); else msize = vcc->xferSize; status = v2v_nc2_prep_message(vcc->channel, msize, V2V_MESSAGE_TYPE_INTERNAL, 0, &msg); if (!NT_SUCCESS(status)) { if (status == STATUS_RETRY) { /* No room right now, return and try again later */ DbgPrint("%s connector(%p) not enough buffer space to send message #%d; retry\n", V2VDRV_LOGTAG, vcc, vcc->txCounter + 1); return STATUS_RETRY; } DbgPrint("%s connector(%p) transmit internal data failure; abort processing - error: 0x%x\n", V2VDRV_LOGTAG, vcc, status); return status; /* failure */ } vcc->txCounter++; /* next message */ header = (V2V_FRAME_HEADER*)msg; header->id = (USHORT)vcc->txCounter; header->type = V2V_MESSAGE_TYPE_INTERNAL; header->cs = 0; header->length = vcc->xferSize; vpi = (V2V_POST_INTERNAL*)msg; status = ExUuidCreate(&vpi->guid); if (!NT_SUCCESS(status)) { DbgPrint("%s connector(%p) ExUuidCreate() failed - error: 0x%x; using NULL GUID\n", V2VDRV_LOGTAG, vcc, status); memset((void*)(msg + sizeof(V2V_FRAME_HEADER)), 0, sizeof(GUID)); } /* Fill it up with some data and send it */ memset((void*)(msg + sizeof(V2V_POST_INTERNAL)), 'X', (vcc->xferSize - sizeof(V2V_POST_INTERNAL))); header->cs = V2vChecksum((const UCHAR*)msg, vcc->xferSize); v2v_nc2_send_messages(vcc->channel); /* Keep the send loop going by setting the event. If there is no more room, the prep message call will return ERROR_RETRY and just land us back in the wait. */ KeSetEvent(v2v_get_send_event(vcc->channel), IO_NO_INCREMENT, FALSE); return STATUS_SUCCESS; }
/* * @implemented */ VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId) { UUID Guid; PWCHAR String; UNICODE_STRING GuidString; /* Entry with no drive letter are made that way: * Instead of having a path with the letter, * you have GUID with the unique ID. */ if (!NT_SUCCESS(ExUuidCreate(&Guid))) { return; } /* Convert to string */ if (!NT_SUCCESS(RtlStringFromGUID(&Guid, &GuidString))) { return; } /* No letter entries must start with #, so allocate a proper string */ String = AllocatePool(GuidString.Length + 2 * sizeof(WCHAR)); if (!String) { ExFreePoolWithTag(GuidString.Buffer, 0); return; } /* Write the complete string */ String[0] = L'#'; RtlCopyMemory(String + 1, GuidString.Buffer, GuidString.Length); String[GuidString.Length / sizeof(WCHAR)] = UNICODE_NULL; /* Don't need that one anymore */ ExFreePoolWithTag(GuidString.Buffer, 0); /* Write the entry */ RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, DatabasePath, String, REG_BINARY, UniqueId->UniqueId, UniqueId->UniqueIdLength); FreePool(String); return; }
NTSTATUS FspCreateGuid(GUID *Guid) { PAGED_CODE(); NTSTATUS Result; int Retries = 3; do { Result = ExUuidCreate(Guid); } while (!NT_SUCCESS(Result) && 0 < --Retries); return Result; }
/* * @implemented */ NTSTATUS CreateNewVolumeName(OUT PUNICODE_STRING VolumeName, IN PGUID VolumeGuid OPTIONAL) { GUID Guid; NTSTATUS Status; UNICODE_STRING GuidString; /* If no GUID was provided, then create one */ if (!VolumeGuid) { Status = ExUuidCreate(&Guid); if (!NT_SUCCESS(Status)) { return Status; } } else { RtlCopyMemory(&Guid, VolumeGuid, sizeof(GUID)); } /* Convert GUID to string */ Status = RtlStringFromGUID(&Guid, &GuidString); if (!NT_SUCCESS(Status)) { return Status; } /* Size for volume namespace, litteral GUID, and null char */ VolumeName->MaximumLength = 0x14 + 0x4C + sizeof(UNICODE_NULL); VolumeName->Buffer = AllocatePool(0x14 + 0x4C + sizeof(UNICODE_NULL)); if (!VolumeName->Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; } else { RtlCopyUnicodeString(VolumeName, &Volume); RtlAppendUnicodeStringToString(VolumeName, &GuidString); VolumeName->Buffer[VolumeName->Length / sizeof(WCHAR)] = UNICODE_NULL; Status = STATUS_SUCCESS; } ExFreePoolWithTag(GuidString.Buffer, 0); return Status; }
void rnd_reseed_now() { seed_data seed; KeQuerySystemTime(&seed.seed20); seed.seed1 = PsGetCurrentProcess(); seed.seed2 = PsGetCurrentProcessId(); seed.seed3 = KeGetCurrentThread(); seed.seed4 = PsGetCurrentThreadId(); seed.seed5 = KeGetCurrentProcessorNumber(); seed.seed6 = KeQueryInterruptTime(); seed.seed10 = KeQueryPerformanceCounter(NULL); seed.seed11 = __rdtsc(); seed.seed12 = ExGetPreviousMode(); seed.seed14 = IoGetTopLevelIrp(); seed.seed15 = MmQuerySystemSize(); seed.seed24 = KeGetCurrentIrql(); if (KeGetCurrentIrql() == PASSIVE_LEVEL) { seed.seed7 = KeQueryPriorityThread(seed.seed3); seed.seed17 = ExUuidCreate(&seed.seed18); seed.seed19 = RtlRandom(&seed.seed8); } if (KeGetCurrentIrql() <= APC_LEVEL) { seed.seed13 = IoGetInitialStack(); seed.seed16 = PsGetProcessExitTime(); IoGetStackLimits(&seed.seed22, &seed.seed23); } KeQueryTickCount(&seed.seed21); rnd_add_buff(&seed, sizeof(seed)); /* Prevent leaks */ zeroauto(&seed, sizeof(seed)); }
NTSTATUS NTAPI IntCreateNewRegistryPath( PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension) { static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId"); static UNICODE_STRING ControlVideoPathName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"); HANDLE DevInstRegKey, SettingsKey, NewKey; UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH]; UNICODE_STRING VideoIdString; UUID VideoId; PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ; NTSTATUS Status; ULONG ResultLength; USHORT KeyMaxLength; OBJECT_ATTRIBUTES ObjectAttributes; /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */ Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &DevInstRegKey); if (Status != STATUS_SUCCESS) { ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status); return Status; } /* Query the VideoId value */ ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer; Status = ZwQueryValueKey(DevInstRegKey, &VideoIdValueName, KeyValuePartialInformation, ValueInformation, sizeof(VideoIdBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Create a new video Id */ Status = ExUuidCreate(&VideoId); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Convert the GUID into a string */ Status = RtlStringFromGUID(&VideoId, &VideoIdString); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Copy the GUID String to our buffer */ ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH); RtlCopyMemory(ValueInformation->Data, VideoIdString.Buffer, ValueInformation->DataLength); /* Free the GUID string */ RtlFreeUnicodeString(&VideoIdString); /* Write the VideoId registry value */ Status = ZwSetValueKey(DevInstRegKey, &VideoIdValueName, 0, REG_SZ, ValueInformation->Data, ValueInformation->DataLength); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } } /* Initialize the VideoId string from the registry data */ VideoIdString.Buffer = (PWCHAR)ValueInformation->Data; VideoIdString.Length = (USHORT)ValueInformation->DataLength; VideoIdString.MaximumLength = VideoIdString.Length; /* Close the hardware key */ ObCloseHandle(DevInstRegKey, KernelMode); /* Calculate the size needed for the new registry path name */ KeyMaxLength = ControlVideoPathName.Length + VideoIdString.Length + sizeof(L"\\0000"); /* Allocate the path name buffer */ DeviceExtension->NewRegistryPath.Length = 0; DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength; DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, KeyMaxLength, TAG_VIDEO_PORT); if (DeviceExtension->NewRegistryPath.Buffer == NULL) { ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n"); return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the root key name and append the VideoId string */ RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath, &ControlVideoPathName); RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath, &VideoIdString); /* Check if we have the key already */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); } /* Append a the instance path */ /// \todo HACK RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\"); RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000"); /* Check this key again */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath); return Status; } /* Open the new key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->NewRegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); return Status; } /* Open the device profile key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->RegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); ObCloseHandle(NewKey, KernelMode); return Status; } /* Copy the registry data from the legacy key */ Status = IntCopyRegistryKey(SettingsKey, NewKey); } return Status; }
NTSTATUS CreateKTMResourceManager( __in PTM_RM_NOTIFICATION CallbackRoutine, __in_opt PVOID RMKey ) /*++ Routine Description: This method will create a volatile Transaction Manager (TM) and a volatile Resource Manager (RM) and enable callback notification through them. The RM created here is used to enlist onto a transaction so that the RMCallback routine will be called when the transaction commits or aborts. Arguments: CallbackRoutine - Pointer to a ResourceManagerNotification Routine RMKey - A caller-defined context value that uniquely identifies the resource manager. The callback routine receives this value as input. Note: When you are enlisting to a transaction, you can pass in a context that is specific to that particular enlistment. Return Value: NTSTATUS --*/ { OBJECT_ATTRIBUTES ObjAttributes; PKRESOURCEMANAGER RMObject; NTSTATUS Status = STATUS_SUCCESS; HANDLE TMHandle = NULL; HANDLE RMHandle = NULL; GUID RMGuid; InfoPrint("Creating KTM Resource Manager"); // // Create the volatile TM // InitializeObjectAttributes(&ObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateTransactionManager(&TMHandle, TRANSACTIONMANAGER_ALL_ACCESS, &ObjAttributes, NULL, TRANSACTION_MANAGER_VOLATILE, 0); if (!NT_SUCCESS(Status)) { ErrorPrint("CreateTransactionManager failed. Status 0x%x", Status); goto Exit; } // // Create the volatile RM // Status = ExUuidCreate(&RMGuid); if (!NT_SUCCESS(Status)) { ErrorPrint("ExUuidCreate failed. Status 0x%x", Status); goto Exit; } InitializeObjectAttributes(&ObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateResourceManager(&RMHandle, RESOURCEMANAGER_ALL_ACCESS, TMHandle, &RMGuid, &ObjAttributes, RESOURCE_MANAGER_VOLATILE, NULL); if (!NT_SUCCESS(Status)) { ErrorPrint("CreateResourceManager failed. Status 0x%x", Status); goto Exit; } // // Grab the RM object from the handle // Status = ObReferenceObjectByHandle(RMHandle, 0, NULL, KernelMode, (PVOID *) &RMObject, NULL); if (!NT_SUCCESS(Status)) { ErrorPrint("ObReferenceObjectbyHandle failed. Status 0x%x", Status); goto Exit; } // // Enable callbacks and pass in our notification routine // Status = TmEnableCallbacks(RMObject, CallbackRoutine, RMKey); ObDereferenceObject(RMObject); if (!NT_SUCCESS(Status)) { ErrorPrint("TmEnableCallbacks failed. Status 0x%x", Status); goto Exit; } Exit: if (!NT_SUCCESS(Status)) { if (RMHandle != NULL) { ZwClose(RMHandle); } if (TMHandle!= NULL) { ZwClose(TMHandle); } } else { ResourceManager = RMHandle; TransactionManager = TMHandle; } return Status; }
GUID * AFSValidateProcessEntry( IN HANDLE ProcessId, IN BOOLEAN bProcessTreeLocked) { GUID *pAuthGroup = NULL; NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)ProcessId; UNICODE_STRING uniSIDString; ULONG ulSIDHash = 0; AFSSIDEntryCB *pSIDEntryCB = NULL; ULONG ulSessionId = 0; ULONGLONG ullTableHash = 0; AFSThreadCB *pParentThreadCB = NULL; UNICODE_STRING uniGUID; BOOLEAN bImpersonation = FALSE; __Enter { uniSIDString.Length = 0; uniSIDString.MaximumLength = 0; uniSIDString.Buffer = NULL; if ( !bProcessTreeLocked) { AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n", pDeviceExt->Specific.Control.ProcessTree.TreeLock, PsGetCurrentThread())); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); } AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { if ( !bProcessTreeLocked) { AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); } ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSProcessCreate( 0, ProcessId, 0, 0); } if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus = STATUS_UNSUCCESSFUL); } if ( !bProcessTreeLocked) { AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock); } } // // Locate and lock the ParentProcessCB if we have one // if( pProcessCB->ParentProcessId != 0) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Locating process entry for Parent ProcessID %I64X\n", __FUNCTION__, pProcessCB->ParentProcessId)); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)pProcessCB->ParentProcessId, (AFSBTreeEntry **)&pParentProcessCB); if( NT_SUCCESS( ntStatus) && pParentProcessCB != NULL) { AFSAcquireExcl( &pParentProcessCB->Lock, TRUE); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located process entry for Parent ProcessID %I64X\n", __FUNCTION__, pProcessCB->ParentProcessId)); } } else { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No parent ID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); } AFSAcquireExcl( &pProcessCB->Lock, TRUE); #if defined(_WIN64) // // Mark the process as 64-bit if it is. // if( !IoIs32bitProcess( NULL)) { SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); } else { ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); } #endif // // Locate the SID for the caller // ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate callers SID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus); } ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve session ID for ProcessID %I64X\n", __FUNCTION__, ullProcessID)); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId)); // // If there is an Auth Group for the current process, // our job is finished. // if ( bImpersonation == FALSE) { pAuthGroup = pProcessCB->ActiveAuthGroup; if( pAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pAuthGroup)) { uniGUID.Buffer = NULL; RtlStringFromGUID( *pAuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_return( ntStatus = STATUS_SUCCESS); } // // The current process does not yet have an Auth Group. Try to inherit // one from the parent process thread that created this process. // if( pParentProcessCB != NULL) { for ( pParentThreadCB = pParentProcessCB->ThreadList; pParentThreadCB != NULL; pParentThreadCB = pParentThreadCB->Next) { if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId) { break; } } // // If the creating thread was found and it has a thread specific // Auth Group, use that even if it is the No PAG // if( pParentThreadCB != NULL && pParentThreadCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup)) { pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n", __FUNCTION__, ullProcessID, ulSessionId, &uniGUID, pParentThreadCB->ThreadId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } } // // If the parent thread was not found or does not have an auth group // else if( pParentProcessCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) { pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n", __FUNCTION__, ullProcessID, ulSessionId, &uniGUID, pParentProcessCB->TreeEntry.HashIndex)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } } // // If an Auth Group was inherited, set it to be the active group // if( pProcessCB->ActiveAuthGroup != NULL && !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) { pAuthGroup = pProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_return( ntStatus); } } } // // If no Auth Group was inherited, assign one based upon the Session and SID // ntStatus = RtlHashUnicodeString( &uniSIDString, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &ulSIDHash); if( !NT_SUCCESS( ntStatus)) { AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, ntStatus)); try_return( ntStatus); } ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( !NT_SUCCESS( ntStatus) || pSIDEntryCB == NULL) { AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( !NT_SUCCESS( ntStatus) || pSIDEntryCB == NULL) { pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSSIDEntryCB), AFS_AG_ENTRY_CB_TAG); if( pSIDEntryCB == NULL) { AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pSIDEntryCB, sizeof( AFSSIDEntryCB)); pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash; while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, &uniGUID)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL) { pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB; } else { AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, &pSIDEntryCB->TreeEntry); } } AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); } AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); // // Store the auth group into the process cb // pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n", __FUNCTION__, &uniSIDString, ullProcessID, ulSessionId, &uniGUID)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } // // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID // is LOCAL_SYSTEM // if( AFSIsLocalSystemSID( &uniSIDString)) { SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n", __FUNCTION__, ullProcessID, ulSessionId)); } // // Return the auth group // pAuthGroup = pProcessCB->ActiveAuthGroup; uniGUID.Buffer = NULL; RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), &uniGUID); AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ullProcessID, ulSessionId)); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_exit: if( pProcessCB != NULL) { if( bImpersonation == FALSE && !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) && NT_SUCCESS( ntStatus)) { ntStatus = AFSProcessSetProcessDacl( pProcessCB); if( !NT_SUCCESS( ntStatus)) { pAuthGroup = NULL; } else { SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET); } } AFSReleaseResource( &pProcessCB->Lock); } if( pParentProcessCB != NULL) { AFSReleaseResource( &pParentProcessCB->Lock); } if( uniSIDString.Length > 0) { RtlFreeUnicodeString( &uniSIDString); } if ( !bProcessTreeLocked) { AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); } } return pAuthGroup; }