diff --git a/config/alfresco/desktop/Alfresco.exe b/config/alfresco/desktop/Alfresco.exe index df18004bab..4025d6490a 100644 Binary files a/config/alfresco/desktop/Alfresco.exe and b/config/alfresco/desktop/Alfresco.exe differ diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp index 276faa7484..6cbdc2f2d9 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp @@ -42,7 +42,6 @@ BEGIN_MESSAGE_MAP(CAlfrescoApp, CWinApp) ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() - // CCAlfrescoApp construction CAlfrescoApp::CAlfrescoApp() @@ -102,9 +101,80 @@ BOOL CAlfrescoApp::InitInstance() String folderPath = appPath.substring(0, pos); String exeName = appPath.substring(pos + 1); + // Create a list of the command line arguments + + StringList argList; + bool argSetWorkDir = false; + + for ( int i = 1; i < __argc; i++) { + + // Check if the argument is a path or switch + + String arg = __wargv[i]; + + if ( arg.startsWith( "/")) { + + // Check for the set working directory switch + + if ( arg.equalsIgnoreCase( "/D")) { + argSetWorkDir = true; + + // DEBUG + + DBGOUT_TS << "/D switch specified" << endl; + } + else { + String msg = L"Invalid command line switch - "; + msg.append( arg); + AfxMessageBox( msg.data(), MB_OK | MB_ICONSTOP); + DBGOUT_TS << "Error, " << msg << endl; + return 2; + } + } + else { + + // Add the path to the argument list + + argList.addString( arg); + } + } + + // Check if the working directory should be set to the path of the first document + + if ( argSetWorkDir == true) { + + // Check if there are any document paths + + if ( argList.numberOfStrings() == 0) { + AfxMessageBox( L"Cannot set working directory, no document paths", MB_OK | MB_ICONSTOP); + DBGOUT_TS << "Error, cannot set working directory, no document paths" << endl; + return 3; + } + + // Get the first document path and remove the file name + + String docPath = argList[0]; + pos = docPath.lastIndexOf( PathSeperator); + + if ( pos < 0) { + AfxMessageBox( L"Invalid document path", MB_OK | MB_ICONSTOP); + DBGOUT_TS << "Error, invalid document path, " << docPath << endl; + return 4; + } + + // Set the document path as the working directory folder + + folderPath = docPath.substring(0, pos); + + // DEBUG + + DBGOUT_TS << "Using document path as working directory, " << folderPath << endl; + } + // Create the Alfresco interface AlfrescoInterface alfresco(folderPath); + if ( alfresco.isAlfrescoFolder()) { try { @@ -158,16 +228,9 @@ BOOL CAlfrescoApp::InitInstance() if ( actionInfo.hasAttribute(AttrMultiplePaths)) { - // Build a list of paths from the command line arguments - - StringList pathList; - - for ( int i = 1; i < __argc; i++) - pathList.addString( String(__wargv[i])); - // Run the action - runAction( alfresco, pathList, actionInfo); + runAction( alfresco, argList, actionInfo); } // Check if the action supports file/folder targets @@ -176,12 +239,12 @@ BOOL CAlfrescoApp::InitInstance() // Pass one path at a time to the action - for ( int i = 1; i < __argc; i++) { + for ( size_t i = 0; i < argList.numberOfStrings(); i++) { // Create a path list with a single path StringList pathList; - pathList.addString( String(__wargv[i])); + pathList.addString( argList[i]); // Run the action diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.rc b/source/cpp/CAlfrescoApp/CAlfrescoApp.rc index ce5908d0ca..e716621ed5 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.rc +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.rc @@ -132,6 +132,11 @@ BEGIN IDS_ABOUTBOX "&About CAlfrescoApp..." END +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE "Alfresco Desktop Action" +END + #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp b/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp index 397bd18831..46366d0c6c 100644 --- a/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp +++ b/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp @@ -169,6 +169,10 @@ public: DesktopResponse runAction(AlfrescoActionInfo& action, DesktopParams& params); + // Set the root path to be used as the working directory + + bool setRootPath( const wchar_t* rootPath); + private: // Send an I/O control request, receive and validate the response diff --git a/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp b/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp index b35d4e6922..35f5ba77ec 100644 --- a/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp +++ b/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp @@ -44,67 +44,9 @@ AlfrescoInterface::AlfrescoInterface(String& path) { m_protocolVersion = 1; - // Check if the path is to a mapped drive + // Set the working directory path - String alfPath = path; - - if ( alfPath.length() >= 3 && alfPath.substring(1,3).equals( L":\\")) { - - // Try and convert the local path to a UNC path - - m_mappedDrive = alfPath.substring(0, 2); - wchar_t remPath[MAX_PATH]; - DWORD remPathLen = MAX_PATH; - - DWORD sts = WNetGetConnection(( LPWSTR) m_mappedDrive.data(), remPath, &remPathLen); - if ( sts != NO_ERROR) - return; - - // Build the UNC path to the folder - - alfPath = remPath; - if ( alfPath.endsWith( PathSeperator) == false) - alfPath.append( PathSeperator); - - if ( path.length() > 3) - alfPath.append( path.substring( 3)); - } - - // Save the UNC path - - m_uncPath = alfPath; - - // Check if the UNC path is valid - - if ( m_uncPath.startsWith(UNCPathPrefix)) { - - // Strip any trailing separator from the path - - if ( m_uncPath.endsWith(PathSeperator)) - m_uncPath = m_uncPath.substring(0, m_uncPath.length() - 1); - - // Make sure the path is to a folder - - DWORD attr = GetFileAttributes(m_uncPath); - - if ( attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { - - // Open the path - - m_handle = CreateFile(m_uncPath, FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - } - - // Set the root path - - int pos = m_uncPath.indexOf( PathSeperator, 2); - if ( pos != -1) { - pos = m_uncPath.indexOf( PathSeperator, pos + 1); - if ( pos == -1) - m_rootPath = m_uncPath; - else - m_rootPath = m_uncPath.substring(0, pos); - } - } + setRootPath( path); } /** @@ -374,6 +316,87 @@ void AlfrescoInterface::sendIOControl( const unsigned int ctlCode, DataBuffer& r throw Exception( L"Send I/O control error", Integer::toString( GetLastError())); } +/** + * Set the root path to be used as the working directory + * + * @param rootPath const wchar_t* + * @return bool + */ +bool AlfrescoInterface::setRootPath( const wchar_t* rootPath) { + + // Close the existing folder, if valid + + if ( m_handle != INVALID_HANDLE_VALUE) + CloseHandle(m_handle); + + // Check if the path is to a mapped drive + + String path = rootPath; + String alfPath = rootPath; + + if ( alfPath.length() >= 3 && alfPath.substring(1,3).equals( L":\\")) { + + // Try and convert the local path to a UNC path + + m_mappedDrive = alfPath.substring(0, 2); + wchar_t remPath[MAX_PATH]; + DWORD remPathLen = MAX_PATH; + + DWORD sts = WNetGetConnection(( LPWSTR) m_mappedDrive.data(), remPath, &remPathLen); + if ( sts != NO_ERROR) + return false; + + // Build the UNC path to the folder + + alfPath = remPath; + if ( alfPath.endsWith( PathSeperator) == false) + alfPath.append( PathSeperator); + + if ( path.length() > 3) + alfPath.append( path.substring( 3)); + } + + // Save the UNC path + + m_uncPath = alfPath; + + // Check if the UNC path is valid + + if ( m_uncPath.startsWith(UNCPathPrefix)) { + + // Strip any trailing separator from the path + + if ( m_uncPath.endsWith(PathSeperator)) + m_uncPath = m_uncPath.substring(0, m_uncPath.length() - 1); + + // Make sure the path is to a folder + + DWORD attr = GetFileAttributes(m_uncPath); + + if ( attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { + + // Open the path + + m_handle = CreateFile(m_uncPath, FILE_WRITE_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + } + + // Set the root path + + int pos = m_uncPath.indexOf( PathSeperator, 2); + if ( pos != -1) { + pos = m_uncPath.indexOf( PathSeperator, pos + 1); + if ( pos == -1) + m_rootPath = m_uncPath; + else + m_rootPath = m_uncPath.substring(0, pos); + } + } + + // Return the folder status + + return isAlfrescoFolder(); +} + /** * Class constructor * diff --git a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java index dd932b0694..7f90e141eb 100644 --- a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java +++ b/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java @@ -41,6 +41,7 @@ import org.alfresco.filesys.smb.server.SMBSrvException; import org.alfresco.filesys.smb.server.SMBSrvPacket; import org.alfresco.filesys.smb.server.SMBSrvSession; import org.alfresco.filesys.smb.server.SecurityMode; +import org.alfresco.filesys.smb.server.VirtualCircuit; import org.alfresco.filesys.smb.server.repo.ContentContext; import org.alfresco.filesys.util.DataPacker; import org.alfresco.filesys.util.HexDump; @@ -491,8 +492,6 @@ public abstract class CifsAuthenticator // Authenticate the user - boolean isGuest = false; - int sts = authenticateUser(client, sess, CifsAuthenticator.NTLM1); if (sts > 0 && (sts & CifsAuthenticator.AUTH_GUEST) != 0) @@ -500,7 +499,7 @@ public abstract class CifsAuthenticator // Guest logon - isGuest = true; + client.setGuest( true); // DEBUG @@ -509,57 +508,55 @@ public abstract class CifsAuthenticator } else if (sts != CifsAuthenticator.AUTH_ALLOW) { + // DEBUG - // Check if the session already has valid client details and the new client details - // have null username/password values + if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("User " + user + ", access denied"); - if (sess.getClientInformation() != null && client.getUserName().length() == 0) - { + // Invalid user, reject the session setup request - // Use the existing client information details - - client = sess.getClientInformation(); - - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Null client information, reusing existing client=" + client); - } - else - { - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("User " + user + ", access denied"); - - // Invalid user, reject the session setup request - - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - } + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); } else if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) { - + // Save the current user token in the client information + + if ( client.isNullSession() == false) + client.setAuthenticationToken( m_authComponent.getCurrentAuthentication()); + else + client.setAuthenticationToken( null); + // DEBUG logger.debug("User " + user + " logged on " + (client != null ? " (type " + client.getLogonTypeString() + ")" : "")); } - // Update the client information if not already set + // Create a virtual circuit and allocate a UID to the new circuit - if (sess.getClientInformation() == null - || sess.getClientInformation().getUserName().length() == 0) + VirtualCircuit vc = new VirtualCircuit( vcNum, client); + int uid = sess.addVirtualCircuit( vc); + + if ( uid == VirtualCircuit.InvalidUID) { - - // Set the client details for the session - - sess.setClientInformation(client); + // DEBUG + + if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("Failed to allocate UID for virtual circuit, " + vc); + + // Failed to allocate a UID + + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + } + else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { + + // DEBUG + + logger.debug("Allocated UID=" + uid + " for VC=" + vc); } - // Set the guest flag for the client, indicate that the session is logged on + // Indicate that the session is logged on - client.setGuest(isGuest); sess.setLoggedOn(true); // Build the session setup response SMB @@ -567,11 +564,11 @@ public abstract class CifsAuthenticator respPkt.setParameterCount(3); respPkt.setParameter(0, 0); // No chained response respPkt.setParameter(1, 0); // Offset to chained response - respPkt.setParameter(2, isGuest ? 1 : 0); + respPkt.setParameter(2, client.isGuest() ? 1 : 0); respPkt.setByteCount(0); respPkt.setTreeId(0); - respPkt.setUserId(0); + respPkt.setUserId(uid); // Set the various flags @@ -832,8 +829,7 @@ public abstract class CifsAuthenticator client.setGuest( true); - // Create a dynamic share for the guest user - // Create the disk driver and context + // Create a dynamic share for the guest user, create the disk driver and context DiskInterface diskDrv = m_config.getDiskInterface(); DiskDeviceContext diskCtx = new ContentContext(client.getUserName(), "", "", client.getHomeFolder()); @@ -936,4 +932,33 @@ public abstract class CifsAuthenticator return personName; } + + /** + * Set the current authenticated user context for this thread + * + * @param client ClientInfo + */ + public void setCurrentUser( ClientInfo client) + { + // Check the account type and setup the authentication context + + if ( client.isNullSession()) + { + // Clear the authentication, null user should not be allowed to do any service calls + + m_authComponent.clearCurrentSecurityContext(); + } + else if ( client.isGuest() == false) + { + // Set the authentication context for the request + + m_authComponent.setCurrentAuthentication( client.getAuthenticationToken()); + } + else + { + // Enable guest access for the request + + m_authComponent.setGuestUserAsCurrentUser(); + } + } } \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/ClientInfo.java b/source/java/org/alfresco/filesys/server/auth/ClientInfo.java index ab287f7897..e267a690ee 100644 --- a/source/java/org/alfresco/filesys/server/auth/ClientInfo.java +++ b/source/java/org/alfresco/filesys/server/auth/ClientInfo.java @@ -67,6 +67,10 @@ public class ClientInfo private String m_ipAddr; + // PID of the logon process for multi-stage logons + + private int m_pid = -1; + // Authentication token private Authentication m_authToken; @@ -394,6 +398,26 @@ public class ClientInfo return m_nfsAuthType; } + /** + * Return the process id + * + * @return int + */ + public final int getProcessId() + { + return m_pid; + } + + /** + * Set the process id + * + * @param pid int + */ + public final void setProcessId( int pid) + { + m_pid = pid; + } + /** * Set the remote users domain * diff --git a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java index 4f034ee1c7..460cf77b3e 100644 --- a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java +++ b/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java @@ -60,6 +60,7 @@ import org.alfresco.filesys.smb.SMBStatus; import org.alfresco.filesys.smb.server.SMBSrvException; import org.alfresco.filesys.smb.server.SMBSrvPacket; import org.alfresco.filesys.smb.server.SMBSrvSession; +import org.alfresco.filesys.smb.server.VirtualCircuit; import org.alfresco.filesys.util.DataPacker; import org.alfresco.filesys.util.HexDump; import org.alfresco.repo.security.authentication.NTLMMode; @@ -507,29 +508,17 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if ( reqPkt.getParameterCount() == 13) { - try - { - // Process the hashed password session setup + // Process the hashed password session setup - doHashedPasswordLogon( sess, reqPkt, respPkt); - return; - } - catch (SMBSrvException ex) - { - // Cleanup any stored context - - sess.setSetupObject( null); - - // Rethrow the exception - - throw ex; - } + doHashedPasswordLogon( sess, reqPkt, respPkt); + return; } // Extract the session details int maxBufSize = reqPkt.getParameter(2); int maxMpx = reqPkt.getParameter(3); + int vcNum = reqPkt.getParameter(4); int secBlobLen = reqPkt.getParameter(7); int capabs = reqPkt.getParameterLong(10); @@ -601,9 +590,13 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca if ( sess.hasRemoteAddress()) client.setClientAddress(sess.getRemoteAddress().getHostAddress()); - // Save the setup object, if valid + // Set the process id for this client, for multi-stage logons - Object setupObj = sess.getSetupObject(); + client.setProcessId( reqPkt.getProcessId()); + + // Get the current sesion setup object, or null + + Object setupObj = sess.getSetupObject( client.getProcessId()); // Process the security blob @@ -646,7 +639,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Cleanup any stored context - sess.setSetupObject( null); + sess.removeSetupObject( client.getProcessId()); // Rethrow the exception @@ -675,15 +668,23 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Check if there is/was a session setup object stored in the session, this indicates a multi-stage session // setup so set the status code accordingly - if ( useRawNTLMSSP() || isNTLMSSP == true || sess.hasSetupObject() || setupObj != null) + boolean loggedOn = false; + + if ( useRawNTLMSSP() || isNTLMSSP == true || sess.hasSetupObject( client.getProcessId()) || setupObj != null) { // NTLMSSP has two stages, if there is a stored setup object then indicate more processing // required - if ( sess.hasSetupObject()) + if ( sess.hasSetupObject( client.getProcessId())) respPkt.setLongErrorCode( SMBStatus.NTMoreProcessingRequired); else + { respPkt.setLongErrorCode( SMBStatus.NTSuccess); + + // Indicate that the user is logged on + + loggedOn = true; + } respPkt.setParameterCount(4); respPkt.setParameter(0, 0xFF); // No chained response @@ -712,6 +713,44 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // security blob length respPkt.setParameterLong(8, 0); // reserved respPkt.setParameterLong(10, getServerCapabilities()); + + // Indicate that the user is logged on + + loggedOn = true; + } + + // If the user is logged on then allocate a virtual circuit + + int uid = 0; + + if ( loggedOn == true) { + + // Clear any stored session setup object for the logon + + sess.removeSetupObject( client.getProcessId()); + + // Create a virtual circuit for the new logon + + VirtualCircuit vc = new VirtualCircuit( vcNum, client); + uid = sess.addVirtualCircuit( vc); + + if ( uid == VirtualCircuit.InvalidUID) + { + // DEBUG + + if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("Failed to allocate UID for virtual circuit, " + vc); + + // Failed to allocate a UID + + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); + } + else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { + + // DEBUG + + logger.debug("Allocated UID=" + uid + " for VC=" + vc); + } } // Common session setup response @@ -719,8 +758,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca respPkt.setCommand( reqPkt.getCommand()); respPkt.setByteCount(0); - respPkt.setTreeId(0); - respPkt.setUserId(0); + respPkt.setTreeId( 0); + respPkt.setUserId( uid); // Set the various flags @@ -834,7 +873,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Store the type 2 message in the session until the session setup is complete - sess.setSetupObject( type2Msg); + sess.setSetupObject( client.getProcessId(), type2Msg); // Set the response blob using the type 2 message @@ -848,11 +887,11 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Make sure a type 2 message was stored in the first stage of the session setup - if ( sess.hasSetupObject() == false || sess.getSetupObject() instanceof Type2NTLMMessage == false) + if ( sess.hasSetupObject( client.getProcessId()) == false || sess.getSetupObject( client.getProcessId()) instanceof Type2NTLMMessage == false) { // Clear the setup object - sess.setSetupObject( null); + sess.removeSetupObject( client.getProcessId()); // Return a logon failure @@ -937,7 +976,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca NegTokenTarg negTarg = null; - if ( tokType == SPNEGO.NegTokenTarg && sess.hasSetupObject() && sess.getSetupObject() instanceof Type2NTLMMessage) + if ( tokType == SPNEGO.NegTokenTarg && sess.hasSetupObject( client.getProcessId()) && sess.getSetupObject( client.getProcessId()) instanceof Type2NTLMMessage) { // Get the NTLMSSP blob from the NegTokenTarg blob @@ -972,7 +1011,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca int spnegoSts = SPNEGO.AcceptCompleted; - if ( sess.hasSetupObject()) + if ( sess.hasSetupObject( client.getProcessId())) spnegoSts = SPNEGO.AcceptIncomplete; // Package the NTLMSSP response in an SPNEGO response @@ -1022,7 +1061,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca int spnegoSts = SPNEGO.AcceptCompleted; - if ( sess.hasSetupObject()) + if ( sess.hasSetupObject( client.getProcessId())) spnegoSts = SPNEGO.AcceptIncomplete; // Package the NTLMSSP response in an SPNEGO response @@ -1183,8 +1222,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca // Get the type 2 message that contains the challenge sent to the client - Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject(); - sess.setSetupObject( null); + Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId()); + sess.removeSetupObject( client.getProcessId()); // Check if we are using local MD4 password hashes or passthru authentication @@ -1432,8 +1471,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Get the type 2 message that contains the challenge sent to the client - Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject(); - sess.setSetupObject( null); + Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId()); + sess.removeSetupObject( client.getProcessId()); // Check if we are using local MD4 password hashes or passthru authentication @@ -1677,8 +1716,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca { // Get the type 2 message that contains the challenge sent to the client - Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject(); - sess.setSetupObject( null); + Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId()); + sess.removeSetupObject( client.getProcessId()); // Check if we are using local MD4 password hashes or passthru authentication @@ -1980,17 +2019,30 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca logger.debug("User " + user + ", logged on as guest"); } - // Update the client information if not already set + // Create a virtual circuit and allocate a UID to the new circuit - if (sess.getClientInformation() == null - || sess.getClientInformation().getUserName().length() == 0) + VirtualCircuit vc = new VirtualCircuit( vcNum, client); + int uid = sess.addVirtualCircuit( vc); + + if ( uid == VirtualCircuit.InvalidUID) { - - // Set the client details for the session - - sess.setClientInformation(client); + + // DEBUG + + if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("Failed to allocate UID for virtual circuit, " + vc); + + // Failed to allocate a UID + + throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); } - + else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + { + // DEBUG + + logger.debug("Allocated UID=" + uid + " for VC=" + vc); + } + // Set the guest flag for the client, indicate that the session is logged on client.setGuest(isGuest); @@ -2005,7 +2057,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca respPkt.setByteCount(0); respPkt.setTreeId(0); - respPkt.setUserId(0); + respPkt.setUserId(uid); // Set the various flags diff --git a/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java index 0824d388e3..355a2a990b 100644 --- a/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java @@ -197,7 +197,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -310,7 +310,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -416,7 +416,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -539,7 +539,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -684,7 +684,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -802,7 +802,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -843,9 +843,6 @@ class CoreProtocolHandler extends ProtocolHandler // Access the disk interface and delete the file(s) - int fid; - NetworkFile netFile = null; - try { @@ -913,7 +910,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1084,7 +1081,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1185,7 +1182,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1316,8 +1313,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1484,8 +1480,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1557,7 +1552,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1714,8 +1709,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1769,8 +1763,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1906,7 +1899,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -1971,9 +1964,6 @@ class CoreProtocolHandler extends ProtocolHandler // Access the disk interface and rename the requested file - int fid; - NetworkFile netFile = null; - try { @@ -2021,7 +2011,6 @@ class CoreProtocolHandler extends ProtocolHandler */ protected final void procSearch(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { - // Check that the received packet looks like a valid search request if (m_smbPkt.checkPacketIsValid(2, 5) == false) @@ -2030,10 +2019,18 @@ class CoreProtocolHandler extends ProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection( m_smbPkt.getTreeId()); if (conn == null) { @@ -2146,7 +2143,7 @@ class CoreProtocolHandler extends ProtocolHandler // Allocate a search slot for the new search - searchId = m_sess.allocateSearchSlot(); + searchId = vc.allocateSearchSlot(); if (searchId == -1) { @@ -2158,7 +2155,7 @@ class CoreProtocolHandler extends ProtocolHandler // is started but never continued. int idx = 0; - ctx = m_sess.getSearchContext(idx); + ctx = vc.getSearchContext(idx); while (ctx != null && searchId == -1) { @@ -2175,18 +2172,18 @@ class CoreProtocolHandler extends ProtocolHandler // Deallocate the search context - m_sess.deallocateSearchSlot(idx); + vc.deallocateSearchSlot(idx); // Allocate the slot for the new search - searchId = m_sess.allocateSearchSlot(); + searchId = vc.allocateSearchSlot(); } else { // Update the search index and get the next search context - ctx = m_sess.getSearchContext(++idx); + ctx = vc.getSearchContext(++idx); } } @@ -2216,13 +2213,13 @@ class CoreProtocolHandler extends ProtocolHandler // Store details of the search in the context - ctx.setTreeId(treeId); + ctx.setTreeId(m_smbPkt.getTreeId()); ctx.setMaximumFiles(maxFiles); } // Save the search context - m_sess.setSearchContext(searchId, ctx); + vc.setSearchContext(searchId, ctx); } else { @@ -2236,7 +2233,7 @@ class CoreProtocolHandler extends ProtocolHandler int id = CoreResumeKey.getServerArea(resumeKey, 0); searchId = (id & 0xFFFF0000) >> 16; - ctx = m_sess.getSearchContext(searchId); + ctx = vc.getSearchContext(searchId); // Check if the search context is valid @@ -2277,7 +2274,7 @@ class CoreProtocolHandler extends ProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); return; } } @@ -2293,7 +2290,7 @@ class CoreProtocolHandler extends ProtocolHandler // Check that the search context and tree connection match - if (ctx.getTreeId() != treeId) + if (ctx.getTreeId() != m_smbPkt.getTreeId()) { m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); return; @@ -2432,7 +2429,7 @@ class CoreProtocolHandler extends ProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } else { @@ -2466,7 +2463,7 @@ class CoreProtocolHandler extends ProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } } } @@ -2481,8 +2478,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -2605,8 +2601,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -2646,7 +2641,6 @@ class CoreProtocolHandler extends ProtocolHandler // Seek to the specified position within the file - byte[] buf = outPkt.getBuffer(); long pos = 0; try @@ -2702,36 +2696,9 @@ class CoreProtocolHandler extends ProtocolHandler protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException, TooManyConnectionsException { - - // Build the session setup response SMB - - outPkt.setParameterCount(3); - outPkt.setParameter(0, 0); - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 8192); - outPkt.setByteCount(0); - - outPkt.setTreeId(0); - outPkt.setUserId(0); - - // Pack the OS, dialect and domain name strings. - - int pos = outPkt.getByteOffset(); - byte[] buf = outPkt.getBuffer(); - - pos = DataPacker.putString("Java", buf, pos, true); - pos = DataPacker.putString("JLAN Server " + m_sess.getServer().isVersion(), buf, pos, true); - pos = DataPacker.putString(m_sess.getServer().getConfiguration().getDomainName(), buf, pos, true); - - outPkt.setByteCount(pos - outPkt.getByteOffset()); - - // Send the negotiate response - - m_sess.sendResponseSMB(outPkt); - - // Update the session state - - m_sess.setState(SMBSrvSessionState.SMBSESSION); + // Return an access denied error, require a logon + + m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); } /** @@ -2756,7 +2723,7 @@ class CoreProtocolHandler extends ProtocolHandler // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -2869,8 +2836,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -2998,6 +2964,15 @@ class CoreProtocolHandler extends ProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the data bytes position and length int dataPos = m_smbPkt.getByteOffset(); @@ -3126,7 +3101,7 @@ class CoreProtocolHandler extends ProtocolHandler // Allocate a tree id for the new connection - int treeId = m_sess.addConnection(shareDev); + int treeId = vc.addConnection(shareDev); // Authenticate the share connection depending upon the security mode the server is running // under @@ -3152,7 +3127,7 @@ class CoreProtocolHandler extends ProtocolHandler // Set the file permission that this user has been granted for this share - TreeConnection tree = m_sess.findConnection(treeId); + TreeConnection tree = m_sess.findTreeConnection( m_smbPkt); tree.setPermission(filePerm); // Build the tree connect response @@ -3192,11 +3167,20 @@ class CoreProtocolHandler extends ProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -3211,7 +3195,7 @@ class CoreProtocolHandler extends ProtocolHandler // Remove the specified connection from the session - m_sess.removeConnection(treeId); + vc.removeConnection(treeId, m_sess); // Build the tree disconnect response @@ -3247,8 +3231,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -3334,8 +3317,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { @@ -3470,8 +3452,7 @@ class CoreProtocolHandler extends ProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); if (conn == null) { diff --git a/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java b/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java index fd362facc9..7364cd1f40 100644 --- a/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java @@ -60,8 +60,7 @@ public class DCERPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = srvTrans.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection( srvTrans); if (conn == null) { @@ -187,12 +186,13 @@ public class DCERPCHandler * Process a DCE/RPC request * * @param sess SMBSrvSession + * @param vc VirtualCircuit * @param tbuf TransactBuffer * @param outPkt SMBSrvPacket * @exception IOException * @exception SMBSrvException */ - public static final void processDCERPCRequest(SMBSrvSession sess, TransactBuffer tbuf, SMBSrvPacket outPkt) + public static final void processDCERPCRequest(SMBSrvSession sess, VirtualCircuit vc, TransactBuffer tbuf, SMBSrvPacket outPkt) throws IOException, SMBSrvException { @@ -207,8 +207,7 @@ public class DCERPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = tbuf.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = vc.findConnection( tbuf.getTreeId()); if (conn == null) { @@ -348,8 +347,7 @@ public class DCERPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = inPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection( inPkt); if (conn == null) { @@ -482,8 +480,7 @@ public class DCERPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = inPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection( inPkt); if (conn == null) { diff --git a/source/java/org/alfresco/filesys/smb/server/IPCHandler.java b/source/java/org/alfresco/filesys/smb/server/IPCHandler.java index 0637202b4f..712dce791a 100644 --- a/source/java/org/alfresco/filesys/smb/server/IPCHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/IPCHandler.java @@ -63,8 +63,7 @@ class IPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = smbPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection(smbPkt); if (conn == null) { @@ -75,7 +74,7 @@ class IPCHandler // Debug if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ Request [" + treeId + "] - cmd = " + smbPkt.getPacketTypeString()); + logger.debug("IPC$ Request [" + smbPkt.getTreeId() + "] - cmd = " + smbPkt.getPacketTypeString()); // Determine the SMB command @@ -136,11 +135,12 @@ class IPCHandler /** * Process an IPC$ transaction request. * + * @param vc VirtualCircuit * @param tbuf SrvTransactBuffer * @param sess SMBSrvSession * @param outPkt SMBSrvPacket */ - protected static void procTransaction(SrvTransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket outPkt) + protected static void procTransaction(VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket outPkt) throws IOException, SMBSrvException { @@ -169,13 +169,13 @@ class IPCHandler // Set named pipe handle state case NamedPipeTransaction.SetNmPHandState: - procSetNamedPipeHandleState(sess, tbuf, outPkt); + procSetNamedPipeHandleState(sess, vc, tbuf, outPkt); break; // Named pipe transation request, pass the request to the DCE/RPC handler case NamedPipeTransaction.TransactNmPipe: - DCERPCHandler.processDCERPCRequest(sess, tbuf, outPkt); + DCERPCHandler.processDCERPCRequest(sess, vc, tbuf, outPkt); break; // Unknown command @@ -223,8 +223,7 @@ class IPCHandler // Get the tree connection details - int treeId = rxPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection(rxPkt); if (conn == null) { @@ -431,8 +430,7 @@ class IPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = rxPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection(rxPkt); if (conn == null) { @@ -454,7 +452,7 @@ class IPCHandler // Debug if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File close [" + treeId + "] fid=" + fid); + logger.debug("IPC$ File close [" + rxPkt.getTreeId() + "] fid=" + fid); // Remove the file from the connections list of open files @@ -474,10 +472,11 @@ class IPCHandler * Process a set named pipe handle state request * * @param sess SMBSrvSession + * @param vc VirtualCircuit * @param tbuf SrvTransactBuffer * @param outPkt SMBSrvPacket */ - protected static void procSetNamedPipeHandleState(SMBSrvSession sess, SrvTransactBuffer tbuf, SMBSrvPacket outPkt) + protected static void procSetNamedPipeHandleState(SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws IOException, SMBSrvException { @@ -492,7 +491,7 @@ class IPCHandler // Get the connection for the request - TreeConnection conn = sess.findConnection(tbuf.getTreeId()); + TreeConnection conn = vc.findConnection(tbuf.getTreeId()); // Get the IPC pipe file for the specified file id @@ -536,8 +535,7 @@ class IPCHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = rxPkt.getTreeId(); - TreeConnection conn = sess.findConnection(treeId); + TreeConnection conn = sess.findTreeConnection(rxPkt); if (conn == null) { @@ -574,7 +572,7 @@ class IPCHandler // Debug if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NT Create AndX [" + treeId + "] name=" + fileName + ", flags=0x" + logger.debug("NT Create AndX [" + rxPkt.getTreeId() + "] name=" + fileName + ", flags=0x" + Integer.toHexString(flags) + ", attr=0x" + Integer.toHexString(attrib) + ", allocSize=" + allocSize); diff --git a/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java index c956c1634f..396452b459 100644 --- a/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java @@ -191,6 +191,16 @@ class LanManProtocolHandler extends CoreProtocolHandler int flags = m_smbPkt.getAndXParameter(cmdOff, 2); int pwdLen = m_smbPkt.getAndXParameter(cmdOff, 3); + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( outPkt.getUserId()); + + if (vc == null) + { + outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return endOff; + } + // Get the data bytes position and length int dataPos = m_smbPkt.getAndXByteOffset(cmdOff); @@ -328,12 +338,12 @@ class LanManProtocolHandler extends CoreProtocolHandler // Allocate the tree id for this connection - int treeId = m_sess.addConnection(shareDev); + int treeId = vc.addConnection(shareDev); outPkt.setTreeId(treeId); // Set the file permission that this user has been granted for this share - TreeConnection tree = m_sess.findConnection(treeId); + TreeConnection tree = vc.findConnection(treeId); tree.setPermission(filePerm); // Inform the driver that a connection has been opened @@ -392,10 +402,19 @@ class LanManProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -420,7 +439,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the search context - SearchContext ctx = m_sess.getSearchContext(searchId); + SearchContext ctx = vc.getSearchContext(searchId); if (ctx == null) { @@ -438,7 +457,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search slot, close the search. - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Return a success status SMB @@ -463,8 +482,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -524,18 +542,37 @@ class LanManProtocolHandler extends CoreProtocolHandler */ protected final void procLogoffAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Check that the received packet looks like a valid logoff andX request - // Check that the received packet looks like a valid logoff andX request - - if (m_smbPkt.checkPacketIsValid(15, 1) == false) + if (m_smbPkt.checkPacketIsValid(2, 0) == false) { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; } - // Return a success status SMB + // Get the virtual circuit for the request + + int uid = m_smbPkt.getUserId(); + VirtualCircuit vc = m_sess.findVirtualCircuit( uid); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } - m_sess.sendSuccessResponseSMB(); + // DEBUG + + if ( logger.isDebugEnabled() && m_sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("Logoff vc=" + vc); + + // Close the virtual circuit + + m_sess.removeVirtualCircuit( uid); + + // Return a success status SMB + + m_sess.sendSuccessResponseSMB(); } /** @@ -556,8 +593,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -631,7 +667,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Open AndX [" + treeId + "] params=" + params); + logger.debug("File Open AndX [" + m_smbPkt.getTreeId() + "] params=" + params); // Access the disk interface and open the requested file @@ -819,8 +855,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -981,8 +1016,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -1042,13 +1076,10 @@ class LanManProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Rename [" + treeId + "] old name=" + oldName + ", new name=" + newName); + logger.debug("File Rename [" + m_smbPkt.getTreeId() + "] old name=" + oldName + ", new name=" + newName); // Access the disk interface and rename the requested file - int fid; - NetworkFile netFile = null; - try { @@ -1339,11 +1370,19 @@ class LanManProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -1414,7 +1453,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Save the partial transaction data - m_sess.setTransaction(transBuf); + vc.setTransaction(transBuf); // Send an intermediate acknowedgement response @@ -1427,14 +1466,14 @@ class LanManProtocolHandler extends CoreProtocolHandler if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) { - IPCHandler.procTransaction(transBuf, m_sess, outPkt); + IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); return; } // DEBUG if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction [" + treeId + "] tbuf=" + transBuf); + logger.debug("Transaction [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); // Process the transaction buffer @@ -1461,11 +1500,20 @@ class LanManProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -1486,9 +1534,9 @@ class LanManProtocolHandler extends CoreProtocolHandler // Check if there is an active transaction, and it is an NT transaction - if (m_sess.hasTransaction() == false - || (m_sess.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) - || (m_sess.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) + if (vc.hasTransaction() == false + || (vc.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) + || (vc.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) { // No transaction to continue, or packet does not match the existing transaction, return @@ -1502,7 +1550,7 @@ class LanManProtocolHandler extends CoreProtocolHandler SMBSrvTransPacket tpkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); byte[] buf = tpkt.getBuffer(); - SrvTransactBuffer transBuf = m_sess.getTransaction(); + SrvTransactBuffer transBuf = vc.getTransaction(); // Append the parameter data to the transaction buffer, if any @@ -1551,14 +1599,14 @@ class LanManProtocolHandler extends CoreProtocolHandler // Clear the in progress transaction - m_sess.setTransaction(null); + vc.setTransaction(null); // Check if the transaction is on the IPC$ named pipe, the request requires special // processing if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) { - IPCHandler.procTransaction(transBuf, m_sess, outPkt); + IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); return; } @@ -1644,11 +1692,18 @@ class LanManProtocolHandler extends CoreProtocolHandler protected final void procTrans2FindFirst(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -1705,7 +1760,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Allocate a search slot for the new search - searchId = m_sess.allocateSearchSlot(); + searchId = vc.allocateSearchSlot(); if (searchId == -1) { @@ -1744,7 +1799,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Save the search context - m_sess.setSearchContext(searchId, ctx); + vc.setSearchContext(searchId, ctx); // Create the reply transact buffer @@ -1859,7 +1914,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } } catch (FileNotFoundException ex) @@ -1868,12 +1923,11 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Search path does not exist m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - // m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); } catch (InvalidDeviceInterfaceException ex) { @@ -1881,7 +1935,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Failed to get/initialize the disk interface @@ -1893,7 +1947,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Requested information level is not supported @@ -1912,11 +1966,18 @@ class LanManProtocolHandler extends CoreProtocolHandler protected final void procTrans2FindNext(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -1961,7 +2022,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Retrieve the search context - ctx = m_sess.getSearchContext(searchId); + ctx = vc.getSearchContext(searchId); if (ctx == null) { @@ -2091,7 +2152,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } } catch (FileNotFoundException ex) @@ -2100,12 +2161,11 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Search path does not exist m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - // m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); } catch (InvalidDeviceInterfaceException ex) { @@ -2113,7 +2173,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Failed to get/initialize the disk interface @@ -2125,7 +2185,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Requested information level is not supported @@ -2147,8 +2207,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2317,8 +2376,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2452,6 +2510,14 @@ class LanManProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Extract the parameters int flags = m_smbPkt.getParameter(2); @@ -2590,12 +2656,12 @@ class LanManProtocolHandler extends CoreProtocolHandler // Allocate a tree id for the new connection - int treeId = m_sess.addConnection(shareDev); + int treeId = vc.addConnection(shareDev); outPkt.setTreeId(treeId); // Set the file permission that this user has been granted for this share - TreeConnection tree = m_sess.findConnection(treeId); + TreeConnection tree = vc.findConnection(treeId); tree.setPermission(filePerm); // Debug @@ -2645,8 +2711,7 @@ class LanManProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2896,7 +2961,7 @@ class LanManProtocolHandler extends CoreProtocolHandler int treeId = m_smbPkt.getTreeId(); TreeConnection conn = null; if (treeId != -1) - conn = m_sess.findConnection(treeId); + conn = m_sess.findTreeConnection(m_smbPkt); if (conn != null) { diff --git a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java index c8a6022dee..96d9e01a3e 100644 --- a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java @@ -346,7 +346,7 @@ public class NTProtocolHandler extends CoreProtocolHandler int treeId = m_smbPkt.getTreeId(); TreeConnection conn = null; if (treeId != -1) - conn = m_sess.findConnection(treeId); + conn = m_sess.findTreeConnection(m_smbPkt); if (conn != null) { @@ -577,9 +577,18 @@ public class NTProtocolHandler extends CoreProtocolHandler // Extract the parameters -// int flags = m_smbPkt.getAndXParameter(cmdOff, 2); int pwdLen = m_smbPkt.getAndXParameter(cmdOff, 3); + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( outPkt.getUserId()); + + if (vc == null) + { + outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return endOff; + } + // Reset the byte pointer for data unpacking m_smbPkt.setBytePointer(m_smbPkt.getAndXByteOffset(cmdOff), m_smbPkt.getAndXByteCount(cmdOff)); @@ -776,12 +785,12 @@ public class NTProtocolHandler extends CoreProtocolHandler // Allocate the tree id for this connection - int treeId = m_sess.addConnection(shareDev); + int treeId = vc.addConnection(shareDev); outPkt.setTreeId(treeId); // Set the file permission that this user has been granted for this share - tree = m_sess.findConnection(treeId); + tree = vc.findConnection(treeId); tree.setPermission(sharePerm); // Inform the driver that a connection has been opened @@ -881,8 +890,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -996,8 +1004,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -1008,9 +1015,6 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the file id from the request int fid = m_smbPkt.getAndXParameter(cmdOff, 0); -// int ftime = m_smbPkt.getAndXParameter(cmdOff, 1); -// int fdate = m_smbPkt.getAndXParameter(cmdOff, 2); - NetworkFile netFile = conn.findFile(fid); if (netFile == null) @@ -1022,7 +1026,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Chained File Close [" + treeId + "] fid=" + fid); + logger.debug("Chained File Close [" + m_smbPkt.getTreeId() + "] fid=" + fid); // Close the file @@ -1093,9 +1097,16 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + if ( vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } + // Extract the parameters -// int flags = m_smbPkt.getParameter(2); int pwdLen = m_smbPkt.getParameter(3); // Initialize the byte area pointer @@ -1291,12 +1302,12 @@ public class NTProtocolHandler extends CoreProtocolHandler // Allocate a tree id for the new connection - int treeId = m_sess.addConnection(shareDev); + int treeId = vc.addConnection(shareDev); outPkt.setTreeId(treeId); // Set the file permission that this user has been granted for this share - TreeConnection tree = m_sess.findConnection(treeId); + TreeConnection tree = vc.findConnection(treeId); tree.setPermission(sharePerm); // Debug @@ -1392,8 +1403,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -1415,8 +1425,6 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the file id from the request int fid = m_smbPkt.getParameter(0); -// int ftime = m_smbPkt.getParameter(1); -// int fdate = m_smbPkt.getParameter(2); NetworkFile netFile = conn.findFile(fid); @@ -1429,7 +1437,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File close [" + treeId + "] fid=" + fid); + logger.debug("File close [" + m_smbPkt.getTreeId() + "] fid=" + fid); // Close the file @@ -1513,11 +1521,19 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -1588,7 +1604,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Save the partial transaction data - m_sess.setTransaction(transBuf); + vc.setTransaction(transBuf); // Send an intermediate acknowedgement response @@ -1601,14 +1617,14 @@ public class NTProtocolHandler extends CoreProtocolHandler if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) { - IPCHandler.procTransaction(transBuf, m_sess, outPkt); + IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); return; } // DEBUG if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction [" + treeId + "] tbuf=" + transBuf); + logger.debug("Transaction [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); // Process the transaction buffer @@ -1635,11 +1651,19 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -1660,9 +1684,9 @@ public class NTProtocolHandler extends CoreProtocolHandler // Check if there is an active transaction, and it is an NT transaction - if (m_sess.hasTransaction() == false - || (m_sess.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) - || (m_sess.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) + if (vc.hasTransaction() == false + || (vc.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) + || (vc.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) { // No transaction to continue, or packet does not match the existing transaction, return @@ -1676,7 +1700,7 @@ public class NTProtocolHandler extends CoreProtocolHandler SMBSrvTransPacket tpkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); byte[] buf = tpkt.getBuffer(); - SrvTransactBuffer transBuf = m_sess.getTransaction(); + SrvTransactBuffer transBuf = vc.getTransaction(); // Append the parameter data to the transaction buffer, if any @@ -1705,7 +1729,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction Secondary [" + treeId + "] paramLen=" + plen + ", dataLen=" + dlen); + logger.debug("Transaction Secondary [" + m_smbPkt.getTreeId() + "] paramLen=" + plen + ", dataLen=" + dlen); // Check if the transaction has been received or there are more sections to be received @@ -1725,21 +1749,21 @@ public class NTProtocolHandler extends CoreProtocolHandler // Clear the in progress transaction - m_sess.setTransaction(null); + vc.setTransaction(null); // Check if the transaction is on the IPC$ named pipe, the request requires special // processing if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) { - IPCHandler.procTransaction(transBuf, m_sess, outPkt); + IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); return; } // DEBUG if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction second [" + treeId + "] tbuf=" + transBuf); + logger.debug("Transaction second [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); // Process the transaction @@ -1843,10 +1867,18 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -1871,7 +1903,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the search context - SearchContext ctx = m_sess.getSearchContext(searchId); + SearchContext ctx = vc.getSearchContext(searchId); if (ctx == null) { @@ -1889,7 +1921,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search slot, close the search. - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Return a success status SMB @@ -1914,8 +1946,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2121,10 +2152,37 @@ public class NTProtocolHandler extends CoreProtocolHandler */ protected final void procLogoffAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Check that the received packet looks like a valid logoff andX request - // Return a success status SMB + if (m_smbPkt.checkPacketIsValid(2, 0) == false) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); + return; + } - m_sess.sendSuccessResponseSMB(); + // Get the virtual circuit for the request + + int uid = m_smbPkt.getUserId(); + VirtualCircuit vc = m_sess.findVirtualCircuit( uid); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + + // DEBUG + + if ( logger.isDebugEnabled() && m_sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) + logger.debug("Logoff vc=" + vc); + + // Close the virtual circuit + + m_sess.removeVirtualCircuit( uid); + + // Return a success status SMB + + m_sess.sendSuccessResponseSMB(); } /** @@ -2145,8 +2203,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2188,7 +2245,6 @@ public class NTProtocolHandler extends CoreProtocolHandler // Extract the open file parameters -// int flags = m_smbPkt.getParameter(2); int access = m_smbPkt.getParameter(3); int srchAttr = m_smbPkt.getParameter(4); int fileAttr = m_smbPkt.getParameter(5); @@ -2217,7 +2273,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Open AndX [" + treeId + "] params=" + params); + logger.debug("File Open AndX [" + m_smbPkt.getTreeId() + "] params=" + params); // Access the disk interface and open the requested file @@ -2395,8 +2451,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2592,8 +2647,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2653,7 +2707,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Rename [" + treeId + "] old name=" + oldName + ", new name=" + newName); + logger.debug("File Rename [" + m_smbPkt.getTreeId() + "] old name=" + oldName + ", new name=" + newName); // Access the disk interface and rename the requested file @@ -2748,8 +2802,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2794,7 +2847,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Delete [" + treeId + "] name=" + fileName); + logger.debug("File Delete [" + m_smbPkt.getTreeId() + "] name=" + fileName); // Access the disk interface and delete the file(s) @@ -2871,8 +2924,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -2917,7 +2969,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Directory Delete [" + treeId + "] name=" + dirName); + logger.debug("Directory Delete [" + m_smbPkt.getTreeId() + "] name=" + dirName); // Access the disk interface and delete the directory @@ -2992,11 +3044,19 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procTrans2FindFirst(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(tbuf.getTreeId()); if (conn == null) { @@ -3073,7 +3133,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Allocate a search slot for the new search - searchId = m_sess.allocateSearchSlot(); + searchId = vc.allocateSearchSlot(); if (searchId == -1) { @@ -3111,7 +3171,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Store details of the search in the context - ctx.setTreeId(treeId); + ctx.setTreeId(m_smbPkt.getTreeId()); ctx.setMaximumFiles(maxFiles); } else @@ -3125,7 +3185,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Save the search context - m_sess.setSearchContext(searchId, ctx); + vc.setSearchContext(searchId, ctx); // Create the reply transact buffer @@ -3315,7 +3375,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } } catch (FileNotFoundException ex) @@ -3331,7 +3391,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Requested path does not exist @@ -3344,7 +3404,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Failed to get/initialize the disk interface @@ -3356,7 +3416,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Requested information level is not supported @@ -3376,10 +3436,18 @@ public class NTProtocolHandler extends CoreProtocolHandler SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(tbuf.getTreeId()); if (conn == null) { @@ -3418,7 +3486,7 @@ public class NTProtocolHandler extends CoreProtocolHandler { // Retrieve the search context - ctx = m_sess.getSearchContext(searchId); + ctx = vc.getSearchContext(searchId); if (ctx == null) { @@ -3562,7 +3630,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Release the search context - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); } } catch (FileNotFoundException ex) @@ -3571,7 +3639,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Search path does not exist @@ -3583,7 +3651,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Deallocate the search if (searchId != -1) - m_sess.deallocateSearchSlot(searchId); + vc.deallocateSearchSlot(searchId); // Requested information level is not supported @@ -3603,10 +3671,20 @@ public class NTProtocolHandler extends CoreProtocolHandler throws java.io.IOException, SMBSrvException { - // Get the tree connection details + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -3843,10 +3921,20 @@ public class NTProtocolHandler extends CoreProtocolHandler SMBSrvException { - // Get the tree connection details + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -4049,11 +4137,20 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procTrans2QueryFile(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } - // Get the tree connection details + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -4256,10 +4353,20 @@ public class NTProtocolHandler extends CoreProtocolHandler SMBSrvException { - // Get the tree connection details + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -4660,10 +4767,20 @@ public class NTProtocolHandler extends CoreProtocolHandler SMBSrvException { - // Get the tree connection details + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + + // Get the tree connection details int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -4911,8 +5028,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -5124,8 +5240,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -5246,7 +5361,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("NT Create AndX [" + treeId + "] params=" + params); + logger.debug("NT Create AndX [" + m_smbPkt.getTreeId() + "] params=" + params); // Access the disk interface and open the requested file @@ -5376,7 +5491,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug(" [" + treeId + "] name=" + fileName + " truncated"); + logger.debug(" [" + m_smbPkt.getTreeId() + "] name=" + fileName + " truncated"); } // Set the file action response @@ -5590,8 +5705,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Get the tree connection details - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); if (conn == null) { @@ -5670,11 +5784,19 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -5744,7 +5866,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + treeId + "] transbuf=" + transBuf); + logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] transbuf=" + transBuf); // Append the setup, parameter and data blocks to the transaction data @@ -5757,7 +5879,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + treeId + "] pcnt=" + ntTrans.getNTParameter(4) + ", offset=" + logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] pcnt=" + ntTrans.getNTParameter(4) + ", offset=" + ntTrans.getNTParameter(5)); cnt = ntTrans.getParameterBlockCount(); @@ -5773,7 +5895,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + treeId + "] cmd=0x" + Integer.toHexString(subCmd) + ", multiPkt=" + logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] cmd=0x" + Integer.toHexString(subCmd) + ", multiPkt=" + transBuf.isMultiPacket()); // Check for a multi-packet transaction, for a multi-packet transaction we just acknowledge @@ -5785,7 +5907,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Save the partial transaction data - m_sess.setTransaction(transBuf); + vc.setTransaction(transBuf); // Send an intermediate acknowedgement response @@ -5817,11 +5939,19 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree id from the received packet and validate that it is a valid // connection id. - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -5850,7 +5980,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Check if there is an active transaction, and it is an NT transaction - if (m_sess.hasTransaction() == false || m_sess.getTransaction().isType() != PacketType.NTTransact) + if (vc.hasTransaction() == false || vc.getTransaction().isType() != PacketType.NTTransact) { // No NT transaction to continue, return an error @@ -5863,7 +5993,7 @@ public class NTProtocolHandler extends CoreProtocolHandler NTTransPacket ntTrans = new NTTransPacket(m_smbPkt.getBuffer()); byte[] buf = ntTrans.getBuffer(); - SrvTransactBuffer transBuf = m_sess.getTransaction(); + SrvTransactBuffer transBuf = vc.getTransaction(); // Append the parameter data to the transaction buffer, if any @@ -5892,7 +6022,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction Secondary [" + treeId + "] paramLen=" + plen + ", dataLen=" + dlen); + logger.debug("NT Transaction Secondary [" + m_smbPkt.getTreeId() + "] paramLen=" + plen + ", dataLen=" + dlen); // Check if the transaction has been received or there are more sections to be received @@ -5912,7 +6042,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Clear the in progress transaction - m_sess.setTransaction(null); + vc.setTransaction(null); // Process the transaction @@ -6020,10 +6150,18 @@ public class NTProtocolHandler extends CoreProtocolHandler return; } + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree connection details - int treeId = tbuf.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { @@ -6140,7 +6278,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("NT TransactCreate [" + treeId + "] params=" + params + " secDescLen=" + sdLen + logger.debug("NT TransactCreate [" + m_smbPkt.getTreeId() + "] params=" + params + " secDescLen=" + sdLen + ", extAttribLen=" + eaLen); // Access the disk interface and open/create the requested file @@ -6254,7 +6392,7 @@ public class NTProtocolHandler extends CoreProtocolHandler // Debug if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug(" [" + treeId + "] name=" + fileName + " truncated"); + logger.debug(" [" + m_smbPkt.getTreeId() + "] name=" + fileName + " truncated"); } // Set the file action response @@ -6420,11 +6558,18 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procNTTransactIOCtl(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, SMBSrvException { + // Get the virtual circuit for the request + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree connection details - int treeId = tbuf.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); if (conn == null) { m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); @@ -6531,11 +6676,18 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procNTTransactQuerySecurityDesc(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } // Get the tree connection details - int treeId = tbuf.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(tbuf.getTreeId()); if (conn == null) { @@ -6604,10 +6756,18 @@ public class NTProtocolHandler extends CoreProtocolHandler DataBuffer paramBuf = tbuf.getParameterBuffer(); + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } + // Get the tree connection details - int treeId = tbuf.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(tbuf.getTreeId()); if (conn == null) { @@ -6653,11 +6813,19 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procNTTransactNotifyChange(NTTransPacket ntpkt, SMBSrvPacket outPkt) throws IOException, SMBSrvException { + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } - // Get the tree connection details + // Get the tree connection details int treeId = ntpkt.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { @@ -6809,15 +6977,24 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procNTTransactRename(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, SMBSrvException { + // Unpack the request details + + DataBuffer paramBuf = tbuf.getParameterBuffer(); + + // Get the virtual circuit for the request + + VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); + + if (vc == null) + { + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); + return; + } - // Unpack the request details + // Get the tree connection details -// DataBuffer paramBuf = tbuf.getParameterBuffer(); - - // Get the tree connection details - - int treeId = tbuf.getTreeId(); - TreeConnection conn = m_sess.findConnection(treeId); + int treeId = tbuf.getTreeId(); + TreeConnection conn = vc.findConnection(treeId); if (conn == null) { diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java index cad98220fc..ac61bfc44f 100644 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java +++ b/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java @@ -39,7 +39,7 @@ public class SMBSrvException extends Exception // NT 32-bit error code - protected int m_NTerror; + protected int m_NTerror = -1; /** * Construct an SMB exception with the specified error class/error code. @@ -116,6 +116,16 @@ public class SMBSrvException extends Exception return m_errorcode; } + /** + * Check if the NT error code has been set + * + * @return boolean + */ + public final boolean hasNTErrorCode() + { + return m_NTerror != -1 ? true : false; + } + /** * Return the NT error code * diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java index fa924a6944..a9560a8ad9 100644 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java +++ b/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java @@ -31,12 +31,8 @@ import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; import org.alfresco.filesys.server.SrvSession; import org.alfresco.filesys.server.auth.AuthenticatorException; import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.core.DeviceInterface; -import org.alfresco.filesys.server.core.SharedDevice; import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.SearchContext; import org.alfresco.filesys.server.filesys.TooManyConnectionsException; import org.alfresco.filesys.server.filesys.TreeConnection; import org.alfresco.filesys.smb.Capability; @@ -80,15 +76,6 @@ public class SMBSrvSession extends SrvSession implements Runnable public static final int DefaultConnections = 4; public static final int MaxConnections = 16; - // Tree ids are 16bit values - - private static final int TreeIdMask = 0x0000FFFF; - - // Default and maximum number of search slots - - private static final int DefaultSearches = 8; - private static final int MaxSearches = 256; - // Maximum multiplexed packets allowed (client can send up to this many SMBs before waiting for // a response) // @@ -131,20 +118,6 @@ public class SMBSrvSession extends SrvSession implements Runnable private String m_callerNBName; private String m_targetNBName; - // Connected share list and next tree id - - private Hashtable m_connections; - private int m_treeId; - - // Active search list for this session - - private SearchContext[] m_search; - private int m_searchCount; - - // Active transaction details - - private SrvTransactBuffer m_transact; - // Notify change requests and notifications pending flag private NotifyRequestList m_notifyList; @@ -173,9 +146,13 @@ public class SMBSrvSession extends SrvSession implements Runnable private int m_clientCaps; - // Session setup object, temporarily stored by an authenticator when the authentication is multi-stage + // Virtual circuit list - private Object m_setupObject; + private VirtualCircuitList m_vcircuits; + + // Setup objects used during two stage session setup before the virtual circuit is allocated + + private Hashtable m_setupObjects; // Debug flag values @@ -233,6 +210,10 @@ public class SMBSrvSession extends SrvSession implements Runnable if (handler.hasClientName()) m_callerNBName = handler.getClientName(); } + + // Allocate the virtual circuit list + + m_vcircuits = new VirtualCircuitList(); } /** @@ -246,201 +227,127 @@ public class SMBSrvSession extends SrvSession implements Runnable } /** - * Add a new connection to this session. Return the allocated tree id for the new connection. + * Find the tree connection for the request * - * @return int Allocated tree id (connection id). - * @param shrDev SharedDevice + * @param smbPkt SMBSrvPacket + * @return TreeConnection */ - protected int addConnection(SharedDevice shrDev) throws TooManyConnectionsException - { + public final TreeConnection findTreeConnection(SMBSrvPacket smbPkt) { - // Check if the connection array has been allocated + // Find the virtual circuit for the request - if (m_connections == null) - m_connections = new Hashtable(DefaultConnections); + TreeConnection tree = null; + VirtualCircuit vc = findVirtualCircuit( smbPkt.getUserId()); - // Allocate an id for the tree connection + if (vc != null) { - int treeId = 0; + // Find the tree connection - synchronized (m_connections) - { + tree = vc.findConnection(smbPkt.getTreeId()); + } - // Check if the tree connection table is full - - if (m_connections.size() == MaxConnections) - throw new TooManyConnectionsException(); - - // Find a free slot in the connection array - - treeId = (m_treeId++ & TreeIdMask); - Integer key = new Integer(treeId); - - while (m_connections.contains(key)) - { - - // Try another tree id for the new connection - - treeId = (m_treeId++ & TreeIdMask); - key = new Integer(treeId); - } - - // Store the new tree connection - - m_connections.put(key, new TreeConnection(shrDev)); - } - - // Return the allocated tree id - - return treeId; - } + // Return the tree connection, or null if invalid UID or TID + return tree; + } + /** - * Allocate a slot in the active searches list for a new search. - * - * @return int Search slot index, or -1 if there are no more search slots available. - */ - protected final int allocateSearchSlot() - { - - // Check if the search array has been allocated - - if (m_search == null) - m_search = new SearchContext[DefaultSearches]; - - // Find a free slot for the new search - - int idx = 0; - - while (idx < m_search.length && m_search[idx] != null) - idx++; - - // Check if we found a free slot - - if (idx == m_search.length) - { - - // The search array needs to be extended, check if we reached the limit. - - if (m_search.length >= MaxSearches) - return -1; - - // Extend the search array - - SearchContext[] newSearch = new SearchContext[m_search.length * 2]; - System.arraycopy(m_search, 0, newSearch, 0, m_search.length); - m_search = newSearch; - } - - // Return the allocated search slot index - - m_searchCount++; - return idx; + * Add a new virtual circuit, return the allocated UID + * + * @param vc + * VirtualCircuit + * @return int + */ + public final int addVirtualCircuit( VirtualCircuit vc) { + + // Add the new virtual circuit + + return m_vcircuits.addCircuit( vc); } - + /** - * Cleanup any resources owned by this session, close files, searches and change notification - * requests. - */ + * Find a virtual circuit with the allocated UID + * + * @param uid int + * @return VirtualCircuit + */ + public final VirtualCircuit findVirtualCircuit(int uid) { + + // Find the virtual circuit with the specified UID + + VirtualCircuit vc = m_vcircuits.findCircuit(uid); + if (vc != null) { + + // Set the session client information from the virtual circuit + + setClientInformation(vc.getClientInformation()); + + // Set the current authenticated user for this request + + getSMBServer().getAuthenticator().setCurrentUser( vc.getClientInformation()); + } + + // Return the virtual circuit + + return vc; + } + + /** + * Remove a virtual circuit + * + * @param uid + * int + */ + public final void removeVirtualCircuit(int uid) { + + // Remove the virtual circuit with the specified UID + + m_vcircuits.removeCircuit(uid, this); + } + + /** + * Cleanup any resources owned by this session, close files, searches and + * change notification requests. + */ protected final void cleanupSession() { - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Cleanup session, searches=" + getSearchCount() + ", treeConns=" + getConnectionCount() - + ", changeNotify=" + getNotifyChangeCount()); - - // Check if there are any active searches - - if (m_search != null) - { - - // Close all active searches - - for (int idx = 0; idx < m_search.length; idx++) - { - - // Check if the current search slot is active - - if (m_search[idx] != null) - deallocateSearchSlot(idx); - } - - // Release the search context list, clear the search count - - m_search = null; - m_searchCount = 0; - } - - // Check if there are open tree connections - - if (m_connections != null) - { - - synchronized (m_connections) - { - - // Close all active tree connections - - Enumeration enm = m_connections.elements(); - - while (enm.hasMoreElements()) - { - - // Get the current tree connection - - TreeConnection tree = enm.nextElement(); - DeviceInterface devIface = tree.getInterface(); - - // Check if there are open files on the share - - if (tree.openFileCount() > 0) - { - - // Close the open files, release locks - - for (int i = 0; i < tree.getFileTableLength(); i++) - { - - // Get an open file - - NetworkFile curFile = tree.findFile(i); - if (curFile != null && devIface instanceof DiskInterface) - { - - // Access the disk share interface - - DiskInterface diskIface = (DiskInterface) devIface; - - try - { - - // Remove the file from the tree connection list - - tree.removeFile(i, this); - - // Close the file - - diskIface.closeFile(this, tree, curFile); - } - catch (Exception ex) - { - } - } - } - } - // Inform the driver that the connection has been closed - - if (devIface != null) - devIface.treeClosed(this, tree); - } - - // Clear the tree connection list - - m_connections.clear(); - } - } + // Debug + + if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) + logger.debug("Cleanup session, vcircuits=" + m_vcircuits.getCircuitCount() + ", changeNotify=" + getNotifyChangeCount()); + + // Close the virtual circuits + + if ( m_vcircuits.getCircuitCount() > 0) { + + // Enumerate the virtual circuits and close all circuits + + Enumeration uidEnum = m_vcircuits.enumerateUIDs(); + + while ( uidEnum.hasMoreElements()) { + + // Get the UID for the current circuit + + Integer uid = (Integer) uidEnum.nextElement(); + + // Close the virtual circuit + + VirtualCircuit vc = m_vcircuits.findCircuit( uid); + if ( vc != null) { + + // DEBUG + + if ( logger.isDebugEnabled() && hasDebug(DBG_STATE)) + logger.debug(" Cleanup vc=" + vc); + + vc.closeCircuit( this); + } + } + + // Clear the virtual circuit list + + m_vcircuits.clearCircuitList(); + } // Commit, or rollback, any active user transaction @@ -530,30 +437,6 @@ public class SMBSrvSession extends SrvSession implements Runnable } - /** - * Deallocate the specified search context/slot. - * - * @param ctxId int - */ - protected final void deallocateSearchSlot(int ctxId) - { - - // Check if the search array has been allocated and that the index is valid - - if (m_search == null || ctxId >= m_search.length) - return; - - // Close the search - - if (m_search[ctxId] != null) - m_search[ctxId].closeSearch(); - - // Free the specified search context slot - - m_searchCount--; - m_search[ctxId] = null; - } - /** * Finalize, object is about to be garbage collected. Make sure resources are released. */ @@ -569,25 +452,6 @@ public class SMBSrvSession extends SrvSession implements Runnable closeSocket(); } - /** - * Return the tree connection details for the specified tree id. - * - * @param treeId int - * @return TreeConnection - */ - protected final TreeConnection findConnection(int treeId) - { - - // Check if the tree id and connection array are valid - - if (m_connections == null) - return null; - - // Get the required tree connection details - - return (TreeConnection) m_connections.get(new Integer(treeId)); - } - /** * Return the input/output metwork buffer for this session. * @@ -598,16 +462,6 @@ public class SMBSrvSession extends SrvSession implements Runnable return m_buf; } - /** - * Return the count of active connections for this session. - * - * @return int - */ - public final int getConnectionCount() - { - return m_connections != null ? m_connections.size() : 0; - } - /** * Return the default flags SMB header value * @@ -763,35 +617,6 @@ public class SMBSrvSession extends SrvSession implements Runnable return m_pktHandler.getRemoteAddress(); } - /** - * Return the search context for the specified search id. - * - * @param srchId int - * @return SearchContext - */ - protected final SearchContext getSearchContext(int srchId) - { - - // Check if the search array is valid and the search index is valid - - if (m_search == null || srchId >= m_search.length) - return null; - - // Return the required search context - - return m_search[srchId]; - } - - /** - * Return the number of active tree searches. - * - * @return int - */ - public final int getSearchCount() - { - return m_searchCount; - } - /** * Return the server that this session is associated with. * @@ -812,26 +637,6 @@ public class SMBSrvSession extends SrvSession implements Runnable return getSMBServer().getServerName(); } - /** - * Determine if the session has a setup object - * - * @return boolean - */ - public final boolean hasSetupObject() - { - return m_setupObject != null; - } - - /** - * Return the session setup object - * - * @return Object - */ - public final Object getSetupObject() - { - return m_setupObject; - } - /** * Return the session state * @@ -871,10 +676,59 @@ public class SMBSrvSession extends SrvSession implements Runnable } /** - * Check if there is a change notification update pending - * - * @return boolean - */ + * Determine if the session has a setup object for the specified PID + * + * @param pid int + * @return boolean + */ + public final boolean hasSetupObject(int pid) { + if (m_setupObjects == null) + return false; + return m_setupObjects.get(new Integer(pid)) != null ? true : false; + } + + /** + * Return the session setup object for the specified PID + * + * @param pid int + * @return Object + */ + public final Object getSetupObject(int pid) { + if (m_setupObjects == null) + return null; + return m_setupObjects.get(new Integer(pid)); + } + + /** + * Store the setup object for the specified PID + * + * @param pid int + * @param obj Object + */ + public final void setSetupObject(int pid, Object obj) { + if (m_setupObjects == null) + m_setupObjects = new Hashtable(); + m_setupObjects.put(new Integer(pid), obj); + } + + /** + * Remove the session setup object for the specified PID + * + * @param pid + * int + * @return Object + */ + public final Object removeSetupObject(int pid) { + if (m_setupObjects == null) + return null; + return m_setupObjects.remove(new Integer(pid)); + } + + /** + * Check if there is a change notification update pending + * + * @return boolean + */ public final boolean hasNotifyPending() { return m_notifyPending; @@ -951,25 +805,6 @@ public class SMBSrvSession extends SrvSession implements Runnable m_buf = pkt.getBuffer(); } - /** - * Store the seach context in the specified slot. - * - * @param slot Slot to store the search context. - * @param srch SearchContext - */ - protected final void setSearchContext(int slot, SearchContext srch) - { - - // Check if the search slot id is valid - - if (m_search == null || slot > m_search.length) - return; - - // Store the context - - m_search[slot] = srch; - } - /** * Set the session state. * @@ -977,32 +812,16 @@ public class SMBSrvSession extends SrvSession implements Runnable */ protected void setState(int state) { - // Debug if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) logger.debug("State changed to " + SMBSrvSessionState.getStateAsString(state)); - // Clear the setup object if the new state is the main session state - - if ( state == SMBSrvSessionState.SMBSESSION) - m_setupObject = null; - // Change the session state m_state = state; } - /** - * Set the setup object - * - * @param obj Object - */ - public final void setSetupObject( Object obj) - { - m_setupObject = obj; - } - /** * Process the NetBIOS session request message, either accept the session request and send back * a NetBIOS accept or reject the session and send back a NetBIOS reject and hangup the session. @@ -1444,45 +1263,6 @@ public class SMBSrvSession extends SrvSession implements Runnable getSMBServer().sessionOpened(this); } - /** - * Remove the specified tree connection from the active connection list. - * - * @param treeId int - */ - protected void removeConnection(int treeId) - { - - // Check if the tree id is valid - - if (m_connections == null) - return; - - // Close the connection and remove from the connection list - - synchronized (m_connections) - { - - // Get the connection - - Integer key = new Integer(treeId); - TreeConnection tree = (TreeConnection) m_connections.get(key); - - // Close the connection, release resources - - if (tree != null) - { - - // Close the connection - - tree.closeConnection(this); - - // Remove the connection from the connection list - - m_connections.remove(key); - } - } - } - /** * Start the SMB server session in a seperate thread. */ @@ -1780,10 +1560,20 @@ public class SMBSrvSession extends SrvSession implements Runnable if (m_smbPkt.isLongErrorCode()) { - - // Return the long/NT status code - - sendErrorResponseSMB(ntCode, SMBStatus.NTErr); + // Return the long/NT status code + + if ( ntCode != -1) { + + // Use the 32bit NT error code + + sendErrorResponseSMB( ntCode, SMBStatus.NTErr); + } + else { + + // Use the DOS error code + + sendErrorResponseSMB( stdCode, stdClass); + } } else { @@ -2035,34 +1825,4 @@ public class SMBSrvSession extends SrvSession implements Runnable if (req.getDiskContext() != null) req.getDiskContext().removeNotifyRequest(req); } - - /** - * Check if there is an active transaction - * - * @return boolean - */ - protected final boolean hasTransaction() - { - return m_transact != null ? true : false; - } - - /** - * Return the active transaction buffer - * - * @return TransactBuffer - */ - protected final SrvTransactBuffer getTransaction() - { - return m_transact; - } - - /** - * Set the active transaction buffer - * - * @param buf TransactBuffer - */ - protected final void setTransaction(SrvTransactBuffer buf) - { - m_transact = buf; - } } \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java b/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java new file mode 100644 index 0000000000..b84555356d --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server; + +import java.util.Enumeration; +import java.util.Hashtable; + +import org.alfresco.filesys.server.SrvSession; +import org.alfresco.filesys.server.auth.ClientInfo; +import org.alfresco.filesys.server.core.DeviceInterface; +import org.alfresco.filesys.server.core.SharedDevice; +import org.alfresco.filesys.server.filesys.DiskInterface; +import org.alfresco.filesys.server.filesys.NetworkFile; +import org.alfresco.filesys.server.filesys.SearchContext; +import org.alfresco.filesys.server.filesys.TooManyConnectionsException; +import org.alfresco.filesys.server.filesys.TreeConnection; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Virtual Circuit Class + * + *

+ * Represents an authenticated circuit on an SMB/CIFS session. There may be + * multiple virtual circuits opened on a single session/socket connection. + */ +public class VirtualCircuit { + + // Debug logging + + private static Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); + + // Default and maximum number of connection slots + + public static final int DefaultConnections = 4; + public static final int MaxConnections = 16; + + // Tree ids are 16bit values + + private static final int TreeIdMask = 0x0000FFFF; + + // Default and maximum number of search slots + + private static final int DefaultSearches = 8; + private static final int MaxSearches = 256; + + // Invalid UID value + + public static final int InvalidUID = -1; + + // Virtual circuit UID value + // + // Allocated by the server and sent by the client to identify the virtual circuit + + private int m_uid = -1; + + // Virtual circuit number + + private int m_vcNum; + + // Client information for this virtual circuit + + private ClientInfo m_clientInfo; + + // Active tree connections + + private Hashtable m_connections; + + private int m_treeId; + + // List of active searches + + private SearchContext[] m_search; + + private int m_searchCount; + + // Active transaction details + + private SrvTransactBuffer m_transact; + + /** + * Class constructor + * + * @param vcNum + * int + * @param cInfo + * ClientInfo + */ + public VirtualCircuit(int vcNum, ClientInfo cInfo) { + m_vcNum = vcNum; + m_clientInfo = cInfo; + } + + /** + * Return the virtual circuit UID + * + * @return int + */ + public final int getUID() { + return m_uid; + } + + /** + * Return the virtual circuit number + * + * @return int + */ + public final int getVCNumber() { + return m_vcNum; + } + + /** + * Return the client information + * + * @return ClientInfo + */ + public final ClientInfo getClientInformation() { + return m_clientInfo; + } + + /** + * Add a new connection to this virtual circuit. Return the allocated tree + * id for the new connection. + * + * @param shrDev SharedDevice + * @return int Allocated tree id (connection id). + */ + public int addConnection(SharedDevice shrDev) + throws TooManyConnectionsException { + + // Check if the connection array has been allocated + + if (m_connections == null) + m_connections = new Hashtable(DefaultConnections); + + // Allocate an id for the tree connection + + int treeId = 0; + + synchronized (m_connections) { + + // Check if the tree connection table is full + + if (m_connections.size() == MaxConnections) + throw new TooManyConnectionsException(); + + // Find a free slot in the connection array + + treeId = (m_treeId++ & TreeIdMask); + Integer key = new Integer(treeId); + + while (m_connections.contains(key)) { + + // Try another tree id for the new connection + + treeId = (m_treeId++ & TreeIdMask); + key = new Integer(treeId); + } + + // Store the new tree connection + + m_connections.put(key, new TreeConnection(shrDev)); + } + + // Return the allocated tree id + + return treeId; + } + + /** + * Return the tree connection details for the specified tree id. + * + * @return com.starla.smbsrv.TreeConnection + * @param treeId + * int + */ + public final TreeConnection findConnection(int treeId) { + + // Check if the tree id and connection array are valid + + if (m_connections == null) + return null; + + // Get the required tree connection details + + return m_connections.get(new Integer(treeId)); + } + + /** + * Remove the specified tree connection from the active connection list. + * + * @param treeId + * int + * @param srvSession + * SrvSession + */ + protected void removeConnection(int treeId, SrvSession sess) { + + // Check if the tree id is valid + + if (m_connections == null) + return; + + // Close the connection and remove from the connection list + + synchronized (m_connections) { + + // Get the connection + + Integer key = new Integer(treeId); + TreeConnection tree = m_connections.get(key); + + // Close the connection, release resources + + if (tree != null) { + + // Close the connection + + tree.closeConnection(sess); + + // Remove the connection from the connection list + + m_connections.remove(key); + } + } + } + + /** + * Return the active tree connection count + * + * @return int + */ + public final int getConnectionCount() { + return m_connections != null ? m_connections.size() : 0; + } + + /** + * Allocate a slot in the active searches list for a new search. + * + * @return int Search slot index, or -1 if there are no more search slots + * available. + */ + public final int allocateSearchSlot() { + + // Check if the search array has been allocated + + if (m_search == null) + m_search = new SearchContext[DefaultSearches]; + + // Find a free slot for the new search + + int idx = 0; + + while (idx < m_search.length && m_search[idx] != null) + idx++; + + // Check if we found a free slot + + if (idx == m_search.length) { + + // The search array needs to be extended, check if we reached the + // limit. + + if (m_search.length >= MaxSearches) + return -1; + + // Extend the search array + + SearchContext[] newSearch = new SearchContext[m_search.length * 2]; + System.arraycopy(m_search, 0, newSearch, 0, m_search.length); + m_search = newSearch; + } + + // Return the allocated search slot index + + m_searchCount++; + return idx; + } + + /** + * Deallocate the specified search context/slot. + * + * @param ctxId + * int + */ + public final void deallocateSearchSlot(int ctxId) { + + // Check if the search array has been allocated and that the index is + // valid + + if (m_search == null || ctxId >= m_search.length) + return; + + // Close the search + + if (m_search[ctxId] != null) + m_search[ctxId].closeSearch(); + + // Free the specified search context slot + + m_searchCount--; + m_search[ctxId] = null; + } + + /** + * Return the search context for the specified search id. + * + * @return com.starla.smbsrv.SearchContext + * @param srchId + * int + */ + public final SearchContext getSearchContext(int srchId) { + + // Check if the search array is valid and the search index is valid + + if (m_search == null || srchId >= m_search.length) + return null; + + // Return the required search context + + return m_search[srchId]; + } + + /** + * Store the seach context in the specified slot. + * + * @param slot + * Slot to store the search context. + * @param srch + * com.starla.smbsrv.SearchContext + */ + public final void setSearchContext(int slot, SearchContext srch) { + + // Check if the search slot id is valid + + if (m_search == null || slot > m_search.length) + return; + + // Store the context + + m_search[slot] = srch; + } + + /** + * Return the number of active tree searches. + * + * @return int + */ + public final int getSearchCount() { + return m_searchCount; + } + + /** + * Check if there is an active transaction + * + * @return boolean + */ + public final boolean hasTransaction() { + return m_transact != null ? true : false; + } + + /** + * Return the active transaction buffer + * + * @return TransactBuffer + */ + public final SrvTransactBuffer getTransaction() { + return m_transact; + } + + /** + * Set the active transaction buffer + * + * @param buf + * TransactBuffer + */ + public final void setTransaction(SrvTransactBuffer buf) { + m_transact = buf; + } + + /** + * Set the UID for the circuit + * + * @param uid + * int + */ + public final void setUID(int uid) { + m_uid = uid; + } + + /** + * Close the virtual circuit, close active tree connections + * + * @param sess + * SrvSession + */ + public final void closeCircuit(SrvSession sess) { + + // Debug + + if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_STATE)) + logger.debug("Cleanup vc=" + getVCNumber() + ", UID=" + getUID() + ", searches=" + getSearchCount() + + ", treeConns=" + getConnectionCount()); + + // Check if there are any active searches + + if (m_search != null) { + + // Close all active searches + + for (int idx = 0; idx < m_search.length; idx++) { + + // Check if the current search slot is active + + if (m_search[idx] != null) + deallocateSearchSlot(idx); + } + + // Release the search context list, clear the search count + + m_search = null; + m_searchCount = 0; + } + + // Check if there are open tree connections + + if (m_connections != null) { + + synchronized (m_connections) { + + // Close all active tree connections + + Enumeration enm = m_connections.elements(); + + while (enm.hasMoreElements()) { + + // Get the current tree connection + + TreeConnection tree = (TreeConnection) enm.nextElement(); + DeviceInterface devIface = tree.getInterface(); + + // Check if there are open files on the share + + if (tree.openFileCount() > 0) { + + // Close the open files, release locks + + for (int i = 0; i < tree.getFileTableLength(); i++) { + + // Get an open file + + NetworkFile curFile = tree.findFile(i); + if (curFile != null && devIface instanceof DiskInterface) { + + // Access the disk share interface + + DiskInterface diskIface = (DiskInterface) devIface; + + try { + + // Remove the file from the tree connection list + + tree.removeFile(i, sess); + + // Close the file + + diskIface.closeFile(sess, tree, curFile); + } + catch (Exception ex) { + } + } + } + } + + // Inform the driver that the connection has been closed + + if (devIface != null) + devIface.treeClosed(sess, tree); + } + + // Clear the tree connection list + + m_connections.clear(); + } + } + } + + /** + * Return the virtual circuit details as a string + * + * @return String + */ + public String toString() { + StringBuffer str = new StringBuffer(); + + str.append("["); + str.append(getVCNumber()); + str.append(":"); + str.append(getUID()); + str.append(","); + str.append(getClientInformation()); + str.append(",Tree="); + str.append(getConnectionCount()); + str.append(",Searches="); + str.append(getSearchCount()); + str.append("]"); + + return str.toString(); + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java b/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java new file mode 100644 index 0000000000..f6042baf4b --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server; + +import java.util.Enumeration; +import java.util.Hashtable; + +import org.alfresco.filesys.server.SrvSession; + +/** + * Virtual Circuit List Class + * + *

+ * Contains a list of virtual circuits that belong to a session. + */ +public class VirtualCircuitList { + + // Default and maximum number of virtual circuits + + public static final int DefaultCircuits = 4; + public static final int MaxCircuits = 16; + + // UIDs are 16bit values + + private static final int UIDMask = 0x0000FFFF; + + // Active virtual circuits + + private Hashtable m_vcircuits; + + // Next available UID + + private int m_UID; + + /** + * Default constructor + */ + public VirtualCircuitList() { + + } + + /** + * Add a new virtual circuit to this session. Return the allocated UID for + * the new circuit. + * + * @param vcircuit + * VirtualCircuit + * @return int Allocated UID. + */ + public int addCircuit(VirtualCircuit vcircuit) { + + // Check if the circuit table has been allocated + + if (m_vcircuits == null) + m_vcircuits = new Hashtable(DefaultCircuits); + + // Allocate an id for the tree connection + + int uid = 0; + + synchronized (m_vcircuits) { + + // Check if the virtual circuit table is full + + if (m_vcircuits.size() == MaxCircuits) + return VirtualCircuit.InvalidUID; + + // Find a free slot in the circuit table + + uid = (m_UID++ & UIDMask); + Integer key = new Integer(uid); + + while (m_vcircuits.contains(key)) { + + // Try another user id for the new virtual circuit + + uid = (m_UID++ & UIDMask); + key = new Integer(uid); + } + + // Store the new virtual circuit + + vcircuit.setUID(uid); + m_vcircuits.put(key, vcircuit); + } + + // Return the allocated UID + + return uid; + } + + /** + * Return the virtual circuit details for the specified UID. + * + * @param uid + * int + * @return VirtualCircuit + */ + public final VirtualCircuit findCircuit(int uid) { + + // Check if the circuit table is valid + + if (m_vcircuits == null) + return null; + + // Get the required tree connection details + + return m_vcircuits.get(new Integer(uid)); + } + + /** + * Return the virtual circuit details for the specified UID. + * + * @param uid + * Integer + * @return VirtualCircuit + */ + public final VirtualCircuit findCircuit(Integer uid) { + + // Check if the circuit table is valid + + if (m_vcircuits == null) + return null; + + // Get the required tree connection details + + return m_vcircuits.get(uid); + } + + /** + * Enumerate the virtual circiuts + * + * @return Enumeration + */ + public final Enumeration enumerateUIDs() { + return m_vcircuits.keys(); + } + + /** + * Remove the specified virtual circuit from the active circuit list. + * + * @param uid int + * @param srvSession SrvSession + */ + public void removeCircuit(int uid, SrvSession sess) { + + // Check if the circuit table is valid + + if (m_vcircuits == null) + return; + + // Close the circuit and remove from the circuit table + + synchronized (m_vcircuits) { + + // Get the circuit + + Integer key = new Integer(uid); + VirtualCircuit vc = (VirtualCircuit) m_vcircuits.get(key); + + // Close the virtual circuit, release resources + + if (vc != null) { + + // Close the circuit + + vc.closeCircuit(sess); + + // Remove the circuit from the circuit table + + m_vcircuits.remove(key); + } + } + } + + /** + * Return the active tree connection count + * + * @return int + */ + public final int getCircuitCount() { + return m_vcircuits != null ? m_vcircuits.size() : 0; + } + + /** + * Clear the virtual circuit list + */ + public final void clearCircuitList() { + m_vcircuits.clear(); + } + + /** + * Return the virtual circuit list details as a string + * + * @return String + */ + public String toString() { + StringBuffer str = new StringBuffer(); + + str.append("[VCs="); + str.append(getCircuitCount()); + str.append("]"); + + return str.toString(); + } +}