Windows: AFSGetConnectionInfo partial match validation
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSNetworkProviderSupport.cpp
index 51eab1e..37f6175 100644 (file)
@@ -63,6 +63,16 @@ AFSAddConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
 
             ConnectCB->AuthenticationId = AFSGetAuthenticationId();
 
+           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSAddConnection Unable to retrieve authentication id\n"));
+
+               return STATUS_ACCESS_DENIED;
+           }
+
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSAddConnection Retrieved authentication id %I64X\n",
@@ -428,6 +438,16 @@ AFSCancelConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
 
             ConnectCB->AuthenticationId = AFSGetAuthenticationId();
 
+           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSCancelConnection Unable to retrieve authentication id\n"));
+
+               return STATUS_ACCESS_DENIED;
+           }
+
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSCancelConnection Retrieved authentication id %I64X\n",
@@ -553,6 +573,16 @@ AFSGetConnection( IN AFSNetworkProviderConnectionCB *ConnectCB,
 
            ConnectCB->AuthenticationId = AFSGetAuthenticationId();
 
+           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSGetConnection Unable to retrieve authentication id\n"));
+
+               return STATUS_ACCESS_DENIED;
+           }
+
            AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSGetConnection Retrieved authentication id %I64X\n",
@@ -693,6 +723,16 @@ AFSListConnections( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
 
             ConnectCB->AuthenticationId = AFSGetAuthenticationId();
 
+           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSListConnections Unable to retrieve authentication id\n"));
+
+               return STATUS_ACCESS_DENIED;
+           }
+
             AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSListConnections Retrieved authentication id %I64X\n",
@@ -1443,7 +1483,6 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSProviderConnectionCB *pConnection = NULL, *pBestMatch = NULL;
     UNICODE_STRING uniRemoteName, uniServerName, uniShareName, uniRemainingPath, uniFullName, uniRemainingPathLocal;
-    USHORT usNameLen = 0, usMaxNameLen = 0;
     BOOLEAN bEnumerationEntry = FALSE;
     AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
@@ -1466,6 +1505,27 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
         uniRemoteName.MaximumLength = uniRemoteName.Length + sizeof( WCHAR);
         uniRemoteName.Buffer = (WCHAR *)ConnectCB->RemoteName;
 
+       if( ConnectCB->AuthenticationId.QuadPart == 0)
+       {
+
+           ConnectCB->AuthenticationId = AFSGetAuthenticationId();
+
+           if ( ConnectCB->AuthenticationId.QuadPart == 0)
+           {
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSGetConnectionInfo Unable to retrieve authentication id\n"));
+
+               return STATUS_ACCESS_DENIED;
+           }
+
+           AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                         AFS_TRACE_LEVEL_VERBOSE,
+                         "AFSGetConnectionInfo Retrieved authentication id %I64X\n",
+                         ConnectCB->AuthenticationId.QuadPart));
+       }
+
         if( ConnectCB->LocalName != L'\0')
         {
 
@@ -1604,9 +1664,22 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
         else
         {
 
-            //
-            // See if we can locate it on our connection list
-            //
+           USHORT usNameLen = 0, usMaxNameLen = 0;
+
+           //
+           // AFSGetConnectionInfo() is called to generate responses for
+           // NPGetResourceInformation and NPGetConnectionPerformance.
+           // The former can be called with a Connection->RemoteName that
+           // consists of \\server\share\dir1\dir2\...\dirN where one or
+           // all of the directories do not have to be processed by the
+           // network provider.  For example, one of the directories might
+           // be a reparse point that redirects to another network provider.
+           // It might also be the case that a directory might be in the
+           // \\afs file namespace but not be accessible with the current
+           // credentials.  That doesn't make the connection invalid.
+           // As such the network provider is not required to validate the
+           // entire RemoteName.  This can result in false positives.
+           //
 
             pConnection = pRDRDevExt->Specific.RDR.ProviderConnectionList;
 
@@ -1615,19 +1688,27 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
                           "AFSGetConnectionInfo Searching for full name %wZ\n",
                           &uniFullName));
 
-            while( pConnection != NULL)
+           while (pConnection != NULL)
             {
 
-                if( usMaxNameLen < pConnection->RemoteName.Length &&
-                    pConnection->RemoteName.Length <= uniFullName.Length)
+               //
+               // A partial match can be valid but it must occur on a
+               // component boundary.
+               //
+
+               if (pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
+                    usMaxNameLen < pConnection->RemoteName.Length &&
+                    (pConnection->RemoteName.Length == uniFullName.Length ||
+                      pConnection->RemoteName.Length < uniFullName.Length &&
+                      (uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'\\' ||
+                        uniFullName.Buffer[pConnection->RemoteName.Length/sizeof(WCHAR)] == L'/')))
                 {
 
                     usNameLen = uniFullName.Length;
 
                     uniFullName.Length = pConnection->RemoteName.Length;
 
-                    if( pConnection->AuthenticationId.QuadPart == ConnectCB->AuthenticationId.QuadPart &&
-                        RtlCompareUnicodeString( &uniFullName,
+                   if (RtlCompareUnicodeString( &uniFullName,
                                                  &pConnection->RemoteName,
                                                  TRUE) == 0)
                     {
@@ -1660,8 +1741,7 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
                               "AFSGetConnectionInfo Using best match for %wZ\n",
                               &pConnection->RemoteName));
             }
-
-            if( pConnection == NULL)
+           else
             {
 
                 //
@@ -1669,7 +1749,16 @@ AFSGetConnectionInfo( IN AFSNetworkProviderConnectionCB *ConnectCB,
                 //
 
                 pConnection = AFSLocateEnumRootEntry( &uniShareName);
-            }
+
+               if (pConnection != NULL)
+               {
+
+                   AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                                 AFS_TRACE_LEVEL_VERBOSE,
+                                 "AFSGetConnectionInfo Using share connection %wZ\n",
+                                 &pConnection->RemoteName));
+               }
+           }
         }
 
         if( pConnection == NULL)