/* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. * Copyright (c) 2009, 2010, 2011 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, * this list of conditions and the following disclaimer in the * documentation * and/or other materials provided with the distribution. * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. * nor the names of their contributors may be used to endorse or promote * products derived from this software without specific prior written * permission from Kernel Drivers, LLC and Your File System, Inc. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // File: AFSAuthGroupSupport.cpp // #include "AFSCommon.h" void AFSRetrieveAuthGroup( IN ULONGLONG ProcessId, IN ULONGLONG ThreadId, OUT GUID *AuthGroup) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL; AFSThreadCB *pThreadCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; GUID *pAuthGroup = NULL; UNICODE_STRING uniGUIDString; ULONG ulSessionId = 0; BOOLEAN bImpersonation = FALSE; __Enter { ulSessionId = AFSGetSessionId( (HANDLE)ProcessId, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve session ID for PID %I64X\n", __FUNCTION__, ProcessId); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, ulSessionId, ProcessId, ThreadId); ntStatus = AFSCheckThreadDacl( AuthGroup); if( NT_SUCCESS( ntStatus)) { uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; RtlStringFromGUID( *AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located AuthGroup %wZ via DACL for Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, &uniGUIDString, ulSessionId, ProcessId, ThreadId); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } try_return( ntStatus = STATUS_SUCCESS); } AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "AFSRetrieveAuthGroup Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n", pDeviceExt->Specific.Control.ProcessTree.TreeLock, PsGetCurrentThread()); ntStatus = STATUS_SUCCESS; AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ProcessId, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process entry for Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, ulSessionId, ProcessId, ThreadId); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); try_return( ntStatus); } for ( pThreadCB = pProcessCB->ThreadList; pThreadCB != NULL; pThreadCB = pThreadCB->Next) { if( pThreadCB->ThreadId == ThreadId) { break; } } if( pThreadCB != NULL && pThreadCB->ActiveAuthGroup != NULL) { pAuthGroup = pThreadCB->ActiveAuthGroup; RtlCopyMemory( AuthGroup, pAuthGroup, sizeof( GUID)); uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; RtlStringFromGUID( *AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located AuthGroup %wZ in thread Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, &uniGUIDString, ulSessionId, ProcessId, ThreadId); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } else if( pProcessCB->ActiveAuthGroup != NULL) { pAuthGroup = pProcessCB->ActiveAuthGroup; RtlCopyMemory( AuthGroup, pAuthGroup, sizeof( GUID)); uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; RtlStringFromGUID( *AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located AuthGroup %wZ in process Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, &uniGUIDString, ulSessionId, ProcessId, ThreadId); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); if( pAuthGroup == NULL || AFSIsNoPAGAuthGroup( pAuthGroup)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No AuthGroup located, validating process for Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, ulSessionId, ProcessId, ThreadId); pAuthGroup = AFSValidateProcessEntry(); if( pAuthGroup != NULL) { RtlCopyMemory( AuthGroup, pAuthGroup, sizeof( GUID)); uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; RtlStringFromGUID( *AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located AuthGroup %wZ after validation Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, &uniGUIDString, ulSessionId, ProcessId, ThreadId); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } else { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate AuthGroup for Session %08lX PID %I64X TID %I64X\n", __FUNCTION__, ulSessionId, ProcessId, ThreadId); } } try_exit: NOTHING; } return; } // // AFSIsLocalSystemAuthGroup returns TRUE if the AuthGroup matches // the AuthGroup associated with the first process that communicates // with the redirector which will always be "System" (PID 4). // BOOLEAN AFSIsLocalSystemAuthGroup( IN GUID *AuthGroup) { BOOLEAN bIsLocalSys = FALSE; AFSProcessCB *pProcessCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; UNICODE_STRING uniGUIDString; __Enter { uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; uniGUIDString.Buffer = NULL; RtlStringFromGUID( *AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE_2, "%s Checking AuthGroup %wZ\n", __FUNCTION__, &uniGUIDString); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); pProcessCB = (AFSProcessCB *)pDeviceExt->Specific.Control.ProcessTree.TreeHead; if( pProcessCB->ActiveAuthGroup != NULL && RtlCompareMemory( pProcessCB->ActiveAuthGroup, AuthGroup, sizeof( GUID)) == sizeof( GUID)) { bIsLocalSys = TRUE; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s AuthGroup %wZ is LOCAL SYSTEM\n", __FUNCTION__, &uniGUIDString); } AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } return bIsLocalSys; } BOOLEAN AFSIsLocalSystemSID( IN UNICODE_STRING *SIDString) { BOOLEAN bIsLocalSys = FALSE; UNICODE_STRING uniSysLocal; __Enter { RtlInitUnicodeString( &uniSysLocal, L"S-1-5-18"); if( RtlCompareUnicodeString( &uniSysLocal, SIDString, TRUE) == 0) { bIsLocalSys = TRUE; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE_2, "%s AuthGroup SID %wZ is %sLOCAL SYSTEM\n", __FUNCTION__, SIDString, bIsLocalSys ? "" : "not "); } return bIsLocalSys; } BOOLEAN AFSIsNoPAGAuthGroup( IN GUID *AuthGroup) { BOOLEAN bIsNoPAG = FALSE; UNICODE_STRING uniGUIDString; __Enter { uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; uniGUIDString.Buffer = NULL; RtlStringFromGUID( *AuthGroup, &uniGUIDString); if( RtlCompareMemory( AuthGroup, &AFSNoPAGAuthGroup, sizeof( GUID)) == sizeof( GUID)) { bIsNoPAG = TRUE; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE_2, "%s AuthGroup %wZ is %sNoPAG\n", __FUNCTION__, &uniGUIDString, bIsNoPAG ? "" : "not "); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } return bIsNoPAG; } // // Creates a new AuthGroup and either activates it for // the process or the current thread. If set as the // new process AuthGroup, the prior AuthGroup list is // cleared. // NTSTATUS AFSCreateSetProcessAuthGroup( AFSAuthGroupRequestCB *CreateSetAuthGroup) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL; AFSThreadCB *pThreadCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); UNICODE_STRING uniSIDString, uniPassedSIDString; ULONG ulSIDHash = 0; AFSProcessAuthGroupCB *pAuthGroup = NULL, *pLastAuthGroup = NULL; ULONG ulSessionId = 0; ULONGLONG ullTableHash = 0; GUID stAuthGroup; UNICODE_STRING uniCallerSID; BOOLEAN bImpersonation = FALSE; __Enter { uniCallerSID.Length = 0; uniCallerSID.MaximumLength = 0; uniCallerSID.Buffer = NULL; AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process CB for PID %I64X\n", __FUNCTION__, ullProcessID); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); try_return( ntStatus = STATUS_UNSUCCESSFUL); } AFSAcquireExcl( &pProcessCB->Lock, TRUE); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate caller SID for PID %I64X Status %08lX\n", __FUNCTION__, ullProcessID, ntStatus); try_return( ntStatus); } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved caller SID %wZ for PID %I64X\n", __FUNCTION__, &uniCallerSID, ullProcessID); if( CreateSetAuthGroup->SIDLength != 0) { uniPassedSIDString.Length = CreateSetAuthGroup->SIDLength; uniPassedSIDString.MaximumLength = uniPassedSIDString.Length; uniPassedSIDString.Buffer = CreateSetAuthGroup->SIDString; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Validating passed SID %wZ for PID %I64X\n", __FUNCTION__, &uniPassedSIDString, ullProcessID); if( RtlCompareUnicodeString( &uniCallerSID, &uniPassedSIDString, TRUE) != 0) { if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Caller specified SID %wZ for PID %I64X but caller is not LOCAL SYSTEM AUTHORITY\n", __FUNCTION__, &uniPassedSIDString, ullProcessID); try_return( ntStatus = STATUS_ACCESS_DENIED); } uniSIDString = uniPassedSIDString; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SID %wZ for PID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID); } else { uniSIDString = uniCallerSID; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Caller and passed SID are equal SID %wZ for PID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID); } } else { uniSIDString = uniCallerSID; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No SID passed, using callers SID %wZ for PID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID); } ntStatus = RtlHashUnicodeString( &uniSIDString, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &ulSIDHash); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to hash SID %wZ for PID %I64X Status %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ntStatus); try_return( ntStatus); } ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve SessionID PID %I64X Status %08lX\n", __FUNCTION__, ullProcessID, ntStatus); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } if( CreateSetAuthGroup->SessionId != (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Checking passed SessionID %08lX for PID %I64X\n", __FUNCTION__, CreateSetAuthGroup->SessionId, ullProcessID); if( ulSessionId != CreateSetAuthGroup->SessionId) { if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Passed SessionID %08lX for PID %I64X, failed because caller is not LOCAL SYSTEM AUTHORITY\n", __FUNCTION__, CreateSetAuthGroup->SessionId, ullProcessID); try_return( ntStatus = STATUS_ACCESS_DENIED); } ulSessionId = CreateSetAuthGroup->SessionId; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SessionID %08lX for PID %I64X\n", __FUNCTION__, ulSessionId, ullProcessID); } } else { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using callers SessionID %08lX for PID %I64X\n", __FUNCTION__, ulSessionId, ullProcessID); } ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); pAuthGroup = pProcessCB->AuthGroupList; while( pAuthGroup != NULL) { if( pAuthGroup->AuthGroupHash == ullTableHash) { break; } pLastAuthGroup = pAuthGroup; pAuthGroup = pAuthGroup->Next; } if( pAuthGroup != NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Located AuthGroup for SID %wZ SessionID %08lX for PID %I64X, failing request\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID); try_return( ntStatus = STATUS_INVALID_PARAMETER); } pAuthGroup = (AFSProcessAuthGroupCB *)AFSExAllocatePoolWithTag( NonPagedPool, sizeof( AFSProcessAuthGroupCB), AFS_AG_ENTRY_CB_TAG); if( pAuthGroup == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory( pAuthGroup, sizeof( AFSProcessAuthGroupCB)); pAuthGroup->AuthGroupHash = (ULONGLONG)ullTableHash; while( ExUuidCreate( &pAuthGroup->AuthGroup) == STATUS_RETRY); if( pLastAuthGroup == NULL) { pProcessCB->AuthGroupList = pAuthGroup; } else { pLastAuthGroup->Next = pAuthGroup; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Allocated new AuthGroup for SID %wZ SessionID %08lX for PID %I64X\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID); if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) { pThreadCB = pProcessCB->ThreadList; while( pThreadCB != NULL) { if( pThreadCB->ThreadId == ullThreadId) { pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; break; } pThreadCB = pThreadCB->Next; } if( pThreadCB == NULL) { pThreadCB = AFSInitializeThreadCB( pProcessCB, ullThreadId); if( pThreadCB == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on thread ID %I64X\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID, ullThreadId); } else if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_SET_AS_ACTIVE)) { pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on process\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID); } try_exit: if( pProcessCB != NULL) { AFSReleaseResource( &pProcessCB->Lock); } if( uniCallerSID.Length > 0) { RtlFreeUnicodeString( &uniCallerSID); } } return ntStatus; } // // Returns a list of the AuthGroup GUIDS associated // with the current process, the current process GUID, // and the current thread GUID. // NTSTATUS AFSQueryProcessAuthGroupList( IN GUID *GUIDList, IN ULONG BufferLength, OUT ULONG_PTR *ReturnLength) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); ULONG ulRequiredLength = 0; AFSProcessAuthGroupCB *pAuthGroup = NULL; GUID *pCurrentGUID = GUIDList; UNICODE_STRING uniGUIDString; __Enter { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for PID %I64X\n", __FUNCTION__, ullProcessID); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process entry PID %I64X\n", __FUNCTION__, ullProcessID); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); try_return( ntStatus = STATUS_UNSUCCESSFUL); } AFSAcquireShared( &pProcessCB->Lock, TRUE); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); pAuthGroup = pProcessCB->AuthGroupList; ulRequiredLength = 0; while( pAuthGroup != NULL) { ulRequiredLength += sizeof( GUID); pAuthGroup = pAuthGroup->Next; } if( BufferLength == 0 || BufferLength < ulRequiredLength || GUIDList == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Buffer too small for query, required %08lX for PID %I64X\n", __FUNCTION__, ulRequiredLength, ullProcessID); *ReturnLength = ulRequiredLength; try_return( ntStatus = STATUS_BUFFER_OVERFLOW); } pAuthGroup = pProcessCB->AuthGroupList; *ReturnLength = 0; while( pAuthGroup != NULL) { RtlCopyMemory( pCurrentGUID, &pAuthGroup->AuthGroup, sizeof( GUID)); uniGUIDString.Buffer = NULL; uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; RtlStringFromGUID( pAuthGroup->AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Adding AuthGroup %wZ for PID %I64X\n", __FUNCTION__, &uniGUIDString, ullProcessID); if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } pCurrentGUID = (GUID *)((char *)pCurrentGUID + sizeof( GUID)); *ReturnLength += sizeof( GUID); pAuthGroup = pAuthGroup->Next; } try_exit: if( pProcessCB != NULL) { AFSReleaseResource( &pProcessCB->Lock); } } return ntStatus; } // // Permits the current AuthGroup for the process or // thread to be set to the specified GUID. The GUID // must be in the list of current values for the process. // NTSTATUS AFSSetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSProcessCB *pProcessCB = NULL; AFSThreadCB *pThreadCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); AFSProcessAuthGroupCB *pAuthGroup = NULL; UNICODE_STRING uniGUIDString; __Enter { uniGUIDString.Length = 0; uniGUIDString.MaximumLength = 0; uniGUIDString.Buffer = NULL; RtlStringFromGUID( ActiveAuthGroup->AuthGroup, &uniGUIDString); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X AuthGroup GUID %wZ\n", __FUNCTION__, ullProcessID, &uniGUIDString); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate process entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); try_return( ntStatus = STATUS_UNSUCCESSFUL); } AFSAcquireExcl( &pProcessCB->Lock, TRUE); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); pAuthGroup = pProcessCB->AuthGroupList; while( pAuthGroup != NULL) { if( RtlCompareMemory( &ActiveAuthGroup->AuthGroup, &pAuthGroup->AuthGroup, sizeof( GUID)) == sizeof( GUID)) { break; } pAuthGroup = pAuthGroup->Next; } if( pAuthGroup == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Failed to locate AuthGroup for ProcessID %I64X AuthGroup GUID %wZ\n", __FUNCTION__, ullProcessID, &uniGUIDString); try_return( ntStatus = STATUS_INVALID_PARAMETER); } if( BooleanFlagOn( ActiveAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) { pThreadCB = pProcessCB->ThreadList; while( pThreadCB != NULL) { if( pThreadCB->ThreadId == ullThreadId) { pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; break; } pThreadCB = pThreadCB->Next; } if( pThreadCB == NULL) { pThreadCB = AFSInitializeThreadCB( pProcessCB, ullThreadId); if( pThreadCB == NULL) { try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on thread %I64X\n", __FUNCTION__, ullProcessID, &uniGUIDString, ullThreadId); } else { pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on process\n", __FUNCTION__, ullProcessID, &uniGUIDString); } try_exit: if( pProcessCB != NULL) { AFSReleaseResource( &pProcessCB->Lock); } if( uniGUIDString.Buffer != NULL) { RtlFreeUnicodeString( &uniGUIDString); } } return ntStatus; } // // Resets the current AuthGroup for the process or // thread to the SID-AuthGroup // NTSTATUS AFSResetActiveProcessAuthGroup( IN IN AFSAuthGroupRequestCB *AuthGroup) { NTSTATUS ntStatus = STATUS_SUCCESS; GUID *pAuthGroup = NULL; AFSProcessCB *pProcessCB = NULL; AFSThreadCB *pThreadCB = NULL; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); __Enter { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID); AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, (ULONGLONG)ullProcessID, (AFSBTreeEntry **)&pProcessCB); if( !NT_SUCCESS( ntStatus) || pProcessCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate AuthGroup for ProcessID %I64X\n", __FUNCTION__, ullProcessID); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); try_return( ntStatus = STATUS_UNSUCCESSFUL); } AFSAcquireExcl( &pProcessCB->Lock, TRUE); AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); if( BooleanFlagOn( AuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) { pThreadCB = pProcessCB->ThreadList; while( pThreadCB != NULL) { if( pThreadCB->ThreadId == ullThreadId) { pThreadCB->ActiveAuthGroup = NULL; break; } pThreadCB = pThreadCB->Next; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Reset AuthGroup list on thread %I64X for ProcessID %I64X\n", __FUNCTION__, ullThreadId, ullProcessID); } else { pProcessCB->ActiveAuthGroup = NULL; pThreadCB = pProcessCB->ThreadList; while( pThreadCB != NULL) { pThreadCB->ActiveAuthGroup = NULL; pThreadCB = pThreadCB->Next; } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Reset AuthGroup list on process for ProcessID %I64X\n", __FUNCTION__, ullProcessID); } AFSReleaseResource( &pProcessCB->Lock); try_exit: NOTHING; } return ntStatus; } // // When bLogonSession == FALSE, the SID must not be specified // and the SessionId must be -1. A new AuthGroup GUID is // assigned to the SID and SessionId of the calling Process. // // When bLogonSession == TRUE, the SID must be specified and // the SessionId must not be -1. The SID of the calling process // must be LOCAL_SYSTEM and a new AuthGroup GUID is assigned to // the specified SID and logon session. // NTSTATUS AFSCreateAuthGroupForSIDorLogonSession( IN AFSAuthGroupRequestCB *AuthGroupRequestCB, IN BOOLEAN bLogonSession) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); UNICODE_STRING uniSIDString, uniPassedSIDString; ULONG ulSIDHash = 0; AFSSIDEntryCB *pSIDEntryCB = NULL; ULONG ulSessionId = 0; ULONGLONG ullTableHash = 0; GUID stAuthGroup; UNICODE_STRING uniCallerSID; UNICODE_STRING uniGUID; BOOLEAN bLocalSystem = FALSE; BOOLEAN bImpersonation = FALSE; __Enter { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, ullProcessID, ullThreadId); ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve callers SID for ProcessID %I64X ThreadID %I64X Status %08lX\n", __FUNCTION__, ullProcessID, ullThreadId, ntStatus); try_return( ntStatus); } bLocalSystem = AFSIsLocalSystemSID( &uniCallerSID); if( bLogonSession == TRUE && bLocalSystem == FALSE) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s caller is %wZ and LOCAL SYSTEM AUTHORITY required\n", __FUNCTION__, uniCallerSID); try_return( ntStatus = STATUS_ACCESS_DENIED); } if ( bLogonSession == TRUE && ( AuthGroupRequestCB == NULL || AuthGroupRequestCB->SIDLength == 0 || AuthGroupRequestCB->SessionId == (ULONG)-1)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s SID and SessionId are mandatory\n", __FUNCTION__); try_return( ntStatus = STATUS_INVALID_PARAMETER); } if ( bLogonSession == FALSE && AuthGroupRequestCB != NULL && ( AuthGroupRequestCB->SIDLength > 0 || AuthGroupRequestCB->SessionId != (ULONG)-1)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s SID and SessionId must not be specified\n", __FUNCTION__); try_return( ntStatus = STATUS_INVALID_PARAMETER); } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, &uniCallerSID, ullProcessID, ullThreadId); if( AuthGroupRequestCB != NULL && AuthGroupRequestCB->SIDLength != 0) { uniPassedSIDString.Length = AuthGroupRequestCB->SIDLength; uniPassedSIDString.MaximumLength = uniPassedSIDString.Length; uniPassedSIDString.Buffer = AuthGroupRequestCB->SIDString; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Checking passed SID %wZ for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, &uniPassedSIDString, ullProcessID, ullThreadId); if( RtlCompareUnicodeString( &uniCallerSID, &uniPassedSIDString, TRUE) != 0) { if( !bLocalSystem) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Not using passed SID %wZ for ProcessID %I64X ThreadID %I64X caller is not LOCAL SYSTEM AUTHORITY\n", __FUNCTION__, &uniPassedSIDString, ullProcessID, ullThreadId); try_return( ntStatus = STATUS_ACCESS_DENIED); } uniSIDString = uniPassedSIDString; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SID %wZ for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID, ullThreadId); } else { uniSIDString = uniCallerSID; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Both SIDs are equal, using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID, ullThreadId); } } else { uniSIDString = uniCallerSID; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID, ullThreadId); } ntStatus = RtlHashUnicodeString( &uniSIDString, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &ulSIDHash); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to hash SID %wZ for ProcessID %I64X ThreadID %I64X Status %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ullThreadId, ntStatus); try_return( ntStatus); } ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve session ID for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, ullProcessID, ullThreadId); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } if( bLogonSession == TRUE && AuthGroupRequestCB != NULL && AuthGroupRequestCB->SessionId != (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Checking passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, AuthGroupRequestCB->SessionId, ullProcessID, ullThreadId); if( ulSessionId != AuthGroupRequestCB->SessionId) { ulSessionId = AuthGroupRequestCB->SessionId; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, AuthGroupRequestCB->SessionId, ullProcessID, ullThreadId); } } else { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using callers SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", __FUNCTION__, ulSessionId, ullProcessID, ullThreadId); } ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( NT_SUCCESS( ntStatus) && pSIDEntryCB != NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Located SID entry for SID %wZ SessionID %08lX ProcessID %I64X ThreadID %I64X, updating GUID\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID, ullThreadId); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Updating existing AuthGroup GUID %wZ\n", __FUNCTION__, &uniGUID); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Updated existing AuthGroup GUID %wZ\n", __FUNCTION__, &uniGUID); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); try_return( ntStatus); } 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); if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL) { pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB; } else { AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, &pSIDEntryCB->TreeEntry); } AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Created new AuthGroup GUID %wZ SID %wZ Session %08lX\n", __FUNCTION__, &uniGUID, &uniSIDString, ulSessionId); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } try_exit: if( uniCallerSID.Length > 0) { RtlFreeUnicodeString( &uniCallerSID); } } return ntStatus; } // // Given a SID and SessionId as input, returns the associated AuthGroup GUID. // If SID or SessionId are not specified, the current process values are used. // NTSTATUS AFSQueryAuthGroup( IN AFSAuthGroupRequestCB *AuthGroup, OUT GUID *AuthGroupGUID, OUT ULONG_PTR *ReturnLength) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); UNICODE_STRING uniSIDString; ULONG ulSIDHash = 0; AFSSIDEntryCB *pSIDEntryCB = NULL; ULONG ulSessionId = 0; ULONGLONG ullTableHash = 0; BOOLEAN bReleaseSID = FALSE; UNICODE_STRING uniGUID; BOOLEAN bImpersonation = FALSE; __Enter { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Entry for ProcessID %I64X\n", __FUNCTION__, ullProcessID); if( AuthGroup == NULL || AuthGroup->SIDLength == 0) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No SID specified, retrieving callers SID for ProcessID %I64X\n", __FUNCTION__, ullProcessID); ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve callers SID for ProcessID %I64X Status %08lX\n", __FUNCTION__, ullProcessID, ntStatus); try_return( ntStatus); } bReleaseSID = TRUE; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved callers SID %wZ for ProcessID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID); } else { uniSIDString.Length = AuthGroup->SIDLength; uniSIDString.MaximumLength = uniSIDString.Length; uniSIDString.Buffer = AuthGroup->SIDString; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SID %wZ for ProcessID %I64X\n", __FUNCTION__, &uniSIDString, ullProcessID); } ntStatus = RtlHashUnicodeString( &uniSIDString, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &ulSIDHash); if( !NT_SUCCESS( ntStatus)) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to hash SID %wZ for ProcessID %I64X Status %08lX\n", __FUNCTION__, &uniSIDString, ullProcessID, ntStatus); try_return( ntStatus); } if( AuthGroup == NULL || AuthGroup->SessionId == -1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s No SessionID specified, retrieving callers for ProcessID %I64X\n", __FUNCTION__, ullProcessID); ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); if( ulSessionId == (ULONG)-1) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to retrieve callers Session ID for ProcessID %I64X\n", __FUNCTION__, ullProcessID); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved callers SessionID %08lX for ProcessID %I64X\n", __FUNCTION__, ulSessionId, ullProcessID); } else { ulSessionId = AuthGroup->SessionId; AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Using passed SessionID %08lX for ProcessID %I64X\n", __FUNCTION__, ulSessionId, ullProcessID); } ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, TRUE); ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, (ULONGLONG)ullTableHash, (AFSBTreeEntry **)&pSIDEntryCB); if( pSIDEntryCB == NULL) { AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_ERROR, "%s Failed to locate SID entry for SID %wZ SessionID %08lX ProcessID %I64X\n", __FUNCTION__, &uniSIDString, ulSessionId, ullProcessID); AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); try_return( ntStatus = STATUS_NOT_FOUND); } RtlCopyMemory( AuthGroupGUID, &pSIDEntryCB->AuthGroup, sizeof( GUID)); *ReturnLength = sizeof( GUID); uniGUID.Buffer = NULL; RtlStringFromGUID( pSIDEntryCB->AuthGroup, &uniGUID); AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, "%s Retrieved AuthGroup GUID %wZ for ProcessID %I64X\n", __FUNCTION__, &uniGUID, ullProcessID); if( uniGUID.Buffer != NULL) { RtlFreeUnicodeString( &uniGUID); } AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); try_exit: if( bReleaseSID && uniSIDString.Length > 0) { RtlFreeUnicodeString( &uniSIDString); } } return ntStatus; }