Windows: Move GetAuthenticationId to Worker Thread
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 28 Jun 2015 17:12:13 +0000 (13:12 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 24 Sep 2015 04:19:17 +0000 (00:19 -0400)
When PsReferenceImpersonationToken(), PsReferencePrimaryToken(), and
SeQueryInformationToken() are called in the kernel from a user process
thread the restrictions on the userland process still apply.  Since we do
not want to be restricted we must obtain the token and query the token
information from a SYSTEM thread.

This change restructures the AFSGetAuthenticationId() process to queue a
synchronous task to the worker thread.

This should address the problem that has been seen during system boot when
the Group Policy Service attempts to query, remove or create a drive
letter mapping.

Change-Id: Ib8772e185aa1e4e52979ec847bbc18a9878bcaca
Reviewed-on: http://gerrit.openafs.org/11909
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h
src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h
src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h

index 5ad8fe6..0081fb3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -7700,8 +7700,100 @@ try_exit:
     return;
 }
 
-LARGE_INTEGER
-AFSGetAuthenticationId()
+NTSTATUS
+AFSGetAuthenticationId( OUT LARGE_INTEGER *pliAuthId)
+{
+    AFSWorkItem *pWorkItem = NULL;
+    NTSTATUS ntStatus;
+
+    __try
+    {
+
+       RtlZeroMemory( pliAuthId, sizeof(LARGE_INTEGER));
+
+       pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool,
+                                                             sizeof(AFSWorkItem),
+                                                             AFS_WORK_ITEM_TAG);
+       if (NULL == pWorkItem)
+       {
+
+           AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                         AFS_TRACE_LEVEL_ERROR,
+                         "AFSGetAuthenticationId Failed to allocate work item\n"));
+
+           try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
+       }
+
+       RtlZeroMemory( pWorkItem,
+                      sizeof(AFSWorkItem));
+
+       pWorkItem->Size = sizeof( AFSWorkItem);
+
+       pWorkItem->RequestType = AFS_WORK_GET_AUTH_ID;
+
+       pWorkItem->RequestFlags = AFS_SYNCHRONOUS_REQUEST;
+
+       KeInitializeEvent(&pWorkItem->Event,
+                         NotificationEvent,
+                         FALSE);
+
+       pWorkItem->Specific.GetAuthId.peProcess = PsGetCurrentProcess();
+
+       pWorkItem->Specific.GetAuthId.peThread = PsGetCurrentThread();
+
+       AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
+                     AFS_TRACE_LEVEL_VERBOSE,
+                     "AFSGetAuthenticationId Workitem %p\n",
+                     pWorkItem));
+
+       ntStatus = AFSQueueWorkerRequest( pWorkItem);
+
+try_exit:
+
+       if( NT_SUCCESS( ntStatus))
+       {
+
+           *pliAuthId = pWorkItem->Specific.GetAuthId.AuthId;
+
+           ntStatus = pWorkItem->Status;
+
+           AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
+                         AFS_TRACE_LEVEL_VERBOSE,
+                         "AFSGetAuthenticationId Request complete Status %08lX\n",
+                         ntStatus));
+       }
+       else {
+
+           AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                         AFS_TRACE_LEVEL_ERROR,
+                         "AFSGetAuthenticationId Failed to queue request Status %08lX\n",
+                         ntStatus));
+       }
+
+       if( pWorkItem != NULL)
+       {
+
+           AFSExFreePoolWithTag( pWorkItem,
+                                 AFS_WORK_ITEM_TAG);
+       }
+    }
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+    {
+
+       AFSDbgTrace(( 0,
+                     0,
+                     "EXCEPTION - AFSGetAuthenticationId\n"));
+
+       AFSDumpTraceFilesFnc();
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSPerformGetAuthId( IN PEPROCESS peProcess,
+                    IN PETHREAD peThread,
+                    OUT LARGE_INTEGER *outAuthId)
 {
 
     LARGE_INTEGER liAuthId = {0,0};
@@ -7716,7 +7808,7 @@ AFSGetAuthenticationId()
     __Enter
     {
 
-        hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
+       hToken = PsReferenceImpersonationToken( peThread,
                                                 &bCopyOnOpen,
                                                 &bEffectiveOnly,
                                                 &stImpersonationLevel);
@@ -7724,14 +7816,14 @@ AFSGetAuthenticationId()
         if( hToken == NULL)
         {
 
-            hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
+           hToken = PsReferencePrimaryToken( peProcess);
 
             if( hToken == NULL)
             {
 
                 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
+                             "AFSPerformGetAuthId Failed to retrieve impersonation or primary token\n"));
 
                 try_return( ntStatus);
             }
@@ -7748,7 +7840,7 @@ AFSGetAuthenticationId()
 
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
+                         "AFSPerformGetAuthId Failed to retrieve information Status %08lX\n",
                           ntStatus));
 
             try_return( ntStatus);
@@ -7759,7 +7851,7 @@ AFSGetAuthenticationId()
 
         AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
+                     "AFSPerformGetAuthId Successfully retrieved authentication ID %I64X\n",
                       liAuthId.QuadPart));
 
 try_exit:
@@ -7784,9 +7876,11 @@ try_exit:
 
             ExFreePool( pTokenInfo);    // Allocated by SeQueryInformationToken
         }
+
+       *outAuthId = liAuthId;
     }
 
-    return liAuthId;
+    return ntStatus;
 }
 
 void
index 37f6175..8921d29 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -61,16 +61,17 @@ AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
         if( ConnectCB->AuthenticationId.QuadPart == 0)
         {
 
-            ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+           ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
 
-           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           if ( !NT_SUCCESS( ntStatus))
            {
 
                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                              AFS_TRACE_LEVEL_ERROR,
-                             "AFSAddConnection Unable to retrieve authentication id\n"));
+                             "AFSAddConnection Unable to retrieve authentication id %08lX\n",
+                             ntStatus));
 
-               return STATUS_ACCESS_DENIED;
+               return ntStatus;
            }
 
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
@@ -436,16 +437,17 @@ AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
         if( ConnectCB->AuthenticationId.QuadPart == 0)
         {
 
-            ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+           ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
 
-           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           if ( !NT_SUCCESS( ntStatus))
            {
 
                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                              AFS_TRACE_LEVEL_ERROR,
-                             "AFSCancelConnection Unable to retrieve authentication id\n"));
+                             "AFSCancelConnection Unable to retrieve authentication id %08lX\n",
+                             ntStatus));
 
-               return STATUS_ACCESS_DENIED;
+               return ntStatus;
            }
 
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
@@ -571,16 +573,17 @@ AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
        if( ConnectCB->AuthenticationId.QuadPart == 0)
        {
 
-           ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+           ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
 
-           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           if ( !NT_SUCCESS( ntStatus))
            {
 
                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                              AFS_TRACE_LEVEL_ERROR,
-                             "AFSGetConnection Unable to retrieve authentication id\n"));
+                             "AFSGetConnection Unable to retrieve authentication id %08lX\n",
+                             ntStatus));
 
-               return STATUS_ACCESS_DENIED;
+               return ntStatus;
            }
 
            AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
@@ -721,16 +724,17 @@ AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
         if( ConnectCB->AuthenticationId.QuadPart == 0)
         {
 
-            ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+           ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
 
-           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           if ( !NT_SUCCESS( ntStatus))
            {
 
                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                              AFS_TRACE_LEVEL_ERROR,
-                             "AFSListConnections Unable to retrieve authentication id\n"));
+                             "AFSListConnection Unable to retrieve authentication id %08lX\n",
+                             ntStatus));
 
-               return STATUS_ACCESS_DENIED;
+               return ntStatus;
            }
 
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
@@ -1508,16 +1512,17 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
        if( ConnectCB->AuthenticationId.QuadPart == 0)
        {
 
-           ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+           ntStatus = AFSGetAuthenticationId(&ConnectCB->AuthenticationId);
 
-           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           if ( !NT_SUCCESS( ntStatus))
            {
 
                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                              AFS_TRACE_LEVEL_ERROR,
-                             "AFSGetConnectionInfo Unable to retrieve authentication id\n"));
+                             "AFSGetConnectionInfo Unable to retrieve authentication id %08lX\n",
+                             ntStatus));
 
-               return STATUS_ACCESS_DENIED;
+               return ntStatus;
            }
 
            AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
index 5335413..ee43f05 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -708,7 +708,7 @@ AFSWorkerThread( IN PVOID Context)
             else
             {
 
-                freeWorkItem = TRUE;
+               freeWorkItem = !(pWorkItem->RequestFlags & AFS_SYNCHRONOUS_REQUEST);
 
                 //
                 // Switch on the type of work item to process
@@ -755,19 +755,26 @@ AFSWorkerThread( IN PVOID Context)
                         AFSPerformObjectInvalidate( pWorkItem->Specific.Invalidate.ObjectInfo,
                                                     pWorkItem->Specific.Invalidate.InvalidateReason);
 
-                        freeWorkItem = TRUE;
-
                         break;
                     }
 
                     case AFS_WORK_START_IOS:
                     {
 
-                        freeWorkItem = TRUE;
-
                         break;
                     }
 
+                   case AFS_WORK_GET_AUTH_ID:
+                   {
+
+                       pWorkItem->Status =
+                           AFSPerformGetAuthId( pWorkItem->Specific.GetAuthId.peProcess,
+                                                pWorkItem->Specific.GetAuthId.peThread,
+                                                &pWorkItem->Specific.GetAuthId.AuthId);
+
+                       break;
+                   }
+
                     default:
 
                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -784,6 +791,13 @@ AFSWorkerThread( IN PVOID Context)
                    AFSExFreePoolWithTag( pWorkItem,
                                          AFS_WORK_ITEM_TAG);
                 }
+               else
+               {
+
+                   KeSetEvent( &pWorkItem->Event,
+                               0,
+                               FALSE);
+               }
 
                 ntStatus = STATUS_SUCCESS;
             }
index d81f288..509894f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1370,8 +1370,13 @@ void
 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                     IN AFSDirectoryCB *DirEntry);
 
-LARGE_INTEGER
-AFSGetAuthenticationId( void);
+NTSTATUS
+AFSGetAuthenticationId( OUT LARGE_INTEGER *pliAuthId);
+
+NTSTATUS
+AFSPerformGetAuthId( IN PEPROCESS peProcess,
+                    IN PETHREAD peThread,
+                    OUT LARGE_INTEGER *outAuthId);
 
 void
 AFSUnwindFileInfo( IN AFSFcb *Fcb,
index 3547e8c..517b8e5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2014, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,7 +110,7 @@ NTSTATUS
 // Worker Thread codes
 //
 
-#define AFS_WORK_UNUSED_1                       0x0001
+#define AFS_WORK_GET_AUTH_ID                    0x0001
 #define AFS_WORK_FLUSH_FCB                      0x0002
 #define AFS_WORK_UNUSED_3                       0x0003
 #define AFS_WORK_UNUSED_4                       0x0004
index f881e75..9251ed3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2015 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -666,6 +666,16 @@ typedef struct _AFS_WORK_ITEM
 
         } Invalidate;
 
+       struct
+       {
+           PETHREAD    peThread;
+
+           PEPROCESS   peProcess;
+
+           LARGE_INTEGER AuthId;
+
+       } GetAuthId;
+
         struct
         {
             char     Context[ 1];