mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.0 to HEAD
5450: (from V1.4) 5423 (V1.4): CIFS authentication 5451: (from V1.4) 5432 (V1.4): 'No root node' fix 5437 (V1.4): EHCache upgrade 5440 (V1.4): AR-1355 - Ticket cache config fix 5442 (V1.4): Bootstrap reorganization 5446 (V1.4): AR-1353 5452: (from V1.4) 5391: AR-1310 (script rename fix) 5453: Win32NetBIOS LANA 5454: CIFS unused code git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5483 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
@@ -32,6 +33,7 @@ import org.alfresco.filesys.server.auth.AuthContext;
|
||||
import org.alfresco.filesys.server.auth.CifsAuthenticator;
|
||||
import org.alfresco.filesys.server.auth.ClientInfo;
|
||||
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
||||
import org.alfresco.filesys.util.HexDump;
|
||||
import org.alfresco.repo.security.authentication.NTLMMode;
|
||||
@@ -190,6 +192,25 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
return authSts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate a connection to a share.
|
||||
*
|
||||
* @param client User/client details from the tree connect request.
|
||||
* @param share Shared device the client wants to connect to.
|
||||
* @param pwd Share password.
|
||||
* @param sess Server session.
|
||||
* @return int Granted file permission level or disallow status if negative. See the
|
||||
* FilePermission class.
|
||||
*/
|
||||
public int authenticateShareConnect(ClientInfo client, SharedDevice share, String sharePwd, SrvSession sess)
|
||||
{
|
||||
// Allow write access
|
||||
//
|
||||
// Main authentication is handled by authenticateUser()
|
||||
|
||||
return CifsAuthenticator.Writeable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an authentication context for the new session
|
||||
*
|
||||
@@ -278,7 +299,9 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
// Generate the local encrypted password using the challenge that was sent to the client
|
||||
|
||||
byte[] p21 = new byte[21];
|
||||
byte[] md4byts = m_md4Encoder.decodeHash(md4hash);
|
||||
byte[] md4byts = null;
|
||||
|
||||
md4byts = m_md4Encoder.decodeHash(md4hash);
|
||||
System.arraycopy(md4byts, 0, p21, 0, 16);
|
||||
|
||||
// Get the challenge that was sent to the client
|
||||
@@ -321,6 +344,11 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
return CifsAuthenticator.AUTH_BADPASSWORD;
|
||||
}
|
||||
|
||||
// Logging
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Logged on user " + client.getUserName() + " (" + sess.getRemoteAddress() + ") using auto-logon shared password");
|
||||
|
||||
// Set the current user to be authenticated, save the authentication token
|
||||
|
||||
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName()));
|
||||
@@ -368,6 +396,10 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
|
||||
sess.beginReadTransaction( m_transactionService);
|
||||
|
||||
// Default logon status to disallow
|
||||
|
||||
int authSts = CifsAuthenticator.AUTH_DISALLOW;
|
||||
|
||||
// Get the authentication token for the session
|
||||
|
||||
NTLMPassthruToken authToken = (NTLMPassthruToken) sess.getAuthenticationToken();
|
||||
@@ -377,7 +409,6 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
|
||||
// Get the appropriate hashed password for the algorithm
|
||||
|
||||
int authSts = CifsAuthenticator.AUTH_DISALLOW;
|
||||
byte[] hashedPassword = null;
|
||||
|
||||
if ( alg == NTLM1)
|
||||
|
@@ -495,7 +495,7 @@ public abstract class CifsAuthenticator
|
||||
|
||||
// Check if this is a null session logon
|
||||
|
||||
if (user.length() == 0 && domain.length() == 0 && uniPwdLen == 0 && ascPwdLen == 1)
|
||||
if (user.length() == 0 && uniPwdLen == 0 && ascPwdLen <= 1)
|
||||
client.setLogonType(ClientInfo.LogonNull);
|
||||
|
||||
// Authenticate the user
|
||||
|
@@ -136,10 +136,11 @@ public final class AuthSessionFactory
|
||||
* @param pkt SMBPacket to build the negotiate request
|
||||
* @param dlct SMB dialects to negotiate
|
||||
* @param pid Process id to be used by this new session
|
||||
* @param extSec Enable/disable extended security negotiation
|
||||
* @return StringList
|
||||
*/
|
||||
|
||||
private final static StringList BuildNegotiatePacket(SMBPacket pkt, DialectSelector dlct, int pid)
|
||||
private final static StringList BuildNegotiatePacket(SMBPacket pkt, DialectSelector dlct, int pid, boolean extSec)
|
||||
{
|
||||
|
||||
// Initialize the SMB packet header fields
|
||||
@@ -147,14 +148,14 @@ public final class AuthSessionFactory
|
||||
pkt.setCommand(PacketType.Negotiate);
|
||||
pkt.setProcessId(pid);
|
||||
|
||||
// If the NT dialect is enabled set the Unicode flag in the request flags
|
||||
// If the NT dialect is enabled set the Unicode flag
|
||||
|
||||
int flags2 = 0;
|
||||
|
||||
if (dlct.hasDialect(Dialect.NT))
|
||||
flags2 += SMBPacket.FLG2_UNICODE;
|
||||
|
||||
if ( useExtendedSecurity())
|
||||
if ( useExtendedSecurity() && extSec == true)
|
||||
flags2 += SMBPacket.FLG2_EXTENDEDSECURITY;
|
||||
|
||||
pkt.setFlags2(flags2);
|
||||
@@ -486,7 +487,7 @@ public final class AuthSessionFactory
|
||||
|
||||
// Build the negotiate SMB dialect packet and exchange with the remote server
|
||||
|
||||
StringList diaList = BuildNegotiatePacket(pkt, selDialect, pid);
|
||||
StringList diaList = BuildNegotiatePacket(pkt, selDialect, pid, shr.hasExtendedSecurityFlags());
|
||||
pkt.ExchangeLowLevelSMB(netSession, pkt, true);
|
||||
|
||||
// Determine the selected SMB dialect
|
||||
|
@@ -1016,7 +1016,7 @@ public class AuthenticateSession
|
||||
*/
|
||||
public final void doSessionSetup(String userName, byte[] ascPwd, byte[] uniPwd) throws IOException, SMBException
|
||||
{
|
||||
doSessionSetup(null, userName, null, ascPwd, uniPwd);
|
||||
doSessionSetup(null, userName, null, ascPwd, uniPwd, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1029,7 +1029,7 @@ public class AuthenticateSession
|
||||
public final void doSessionSetup(Type3NTLMMessage type3Msg) throws IOException, SMBException
|
||||
{
|
||||
doSessionSetup(type3Msg.getDomain(), type3Msg.getUserName(), type3Msg.getWorkstation(),
|
||||
type3Msg.getLMHash(), type3Msg.getNTLMHash());
|
||||
type3Msg.getLMHash(), type3Msg.getNTLMHash(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1040,11 +1040,13 @@ public class AuthenticateSession
|
||||
* @param wksName String
|
||||
* @param ascPwd ASCII password hash
|
||||
* @param uniPwd Unicode password hash
|
||||
* @param vcNum Virtual circuit number
|
||||
* @exception IOException If a network error occurs
|
||||
* @exception SMBException If a CIFS error occurs
|
||||
*/
|
||||
public final void doSessionSetup(String domain, String userName, String wksName,
|
||||
byte[] ascPwd, byte[] uniPwd) throws IOException, SMBException
|
||||
byte[] ascPwd, byte[] uniPwd, int vcNum)
|
||||
throws IOException, SMBException
|
||||
{
|
||||
// Check if we are using extended security
|
||||
|
||||
@@ -1052,7 +1054,7 @@ public class AuthenticateSession
|
||||
{
|
||||
// Run the second phase of the extended security session setup
|
||||
|
||||
doExtendedSessionSetupPhase2(domain, userName, wksName, ascPwd, uniPwd);
|
||||
doExtendedSessionSetupPhase2(domain, userName, wksName, ascPwd, uniPwd, vcNum);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1074,7 +1076,7 @@ public class AuthenticateSession
|
||||
pkt.setParameter(1, 0); // offset to next command
|
||||
pkt.setParameter(2, DefaultPacketSize);
|
||||
pkt.setParameter(3, 1);
|
||||
pkt.setParameter(4, 0); // virtual circuit number
|
||||
pkt.setParameter(4, vcNum);
|
||||
pkt.setParameterLong(5, 0); // session key
|
||||
|
||||
// Set the share password length(s)
|
||||
@@ -1121,7 +1123,7 @@ public class AuthenticateSession
|
||||
pkt.packString("?", false);
|
||||
|
||||
pkt.packString("Java VM", false);
|
||||
pkt.packString("JLAN", false);
|
||||
pkt.packString("Alfresco CIFS", false);
|
||||
|
||||
// Set the packet length
|
||||
|
||||
@@ -1175,7 +1177,7 @@ public class AuthenticateSession
|
||||
clbuf.append("Java VM");
|
||||
clbuf.append((char) 0x00);
|
||||
|
||||
clbuf.append("JLAN");
|
||||
clbuf.append("Alfresco CIFS");
|
||||
clbuf.append((char) 0x00);
|
||||
|
||||
// Copy the remaining data to the SMB packet
|
||||
@@ -1275,7 +1277,6 @@ public class AuthenticateSession
|
||||
|
||||
if (getDialect() == Dialect.NT)
|
||||
{
|
||||
|
||||
// Read the returned negotiate parameters, for NT dialect the parameters are not aligned
|
||||
|
||||
m_pkt.resetParameterPointer();
|
||||
@@ -1324,7 +1325,7 @@ public class AuthenticateSession
|
||||
|
||||
// Set the default flags for subsequent SMB requests
|
||||
|
||||
defFlags2 = SMBPacket.FLG2_LONGFILENAMES + SMBPacket.FLG2_UNICODE + SMBPacket.FLG2_LONGERRORCODE;
|
||||
defFlags2 = SMBPacket.FLG2_LONGFILENAMES + SMBPacket.FLG2_UNICODE + SMBPacket.FLG2_LONGERRORCODE + SMBPacket.FLG2_SECURITYSIG;
|
||||
|
||||
if ( isUsingExtendedSecurity())
|
||||
defFlags2 += SMBPacket.FLG2_EXTENDEDSECURITY;
|
||||
@@ -1485,7 +1486,7 @@ public class AuthenticateSession
|
||||
// Pack the OS details
|
||||
|
||||
pkt.packString("Java VM", true);
|
||||
pkt.packString("JLAN", true);
|
||||
pkt.packString("Alfresco CIFS", true);
|
||||
|
||||
pkt.packString("", true);
|
||||
|
||||
@@ -1555,11 +1556,12 @@ public class AuthenticateSession
|
||||
* @param wksName String
|
||||
* @param lmPwd byte[]
|
||||
* @param ntlmPwd byte[]
|
||||
* @param vcNum int
|
||||
* @exception IOException If a network error occurs
|
||||
* @eception SMBException If a CIFS error occurs
|
||||
*/
|
||||
private final void doExtendedSessionSetupPhase2(String domain, String userName, String wksName,
|
||||
byte[] lmPwd, byte[] ntlmPwd) throws IOException, SMBException
|
||||
byte[] lmPwd, byte[] ntlmPwd, int vcNum) throws IOException, SMBException
|
||||
{
|
||||
// Check if the domain name has been specified, if not then use the domain name from the
|
||||
// original connection details or the servers domain name
|
||||
@@ -1590,7 +1592,7 @@ public class AuthenticateSession
|
||||
pkt.setParameter(1, 0); // offset to next command
|
||||
pkt.setParameter(2, DefaultPacketSize);
|
||||
pkt.setParameter(3, 1);
|
||||
pkt.setParameter(4, 0); // virtual circuit number
|
||||
pkt.setParameter(4, vcNum);
|
||||
pkt.setParameterLong(5, 0); // session key
|
||||
|
||||
// Clear the security blob length and reserved area
|
||||
@@ -1629,7 +1631,7 @@ public class AuthenticateSession
|
||||
// Pack the OS details
|
||||
|
||||
pkt.packString("Java VM", true);
|
||||
pkt.packString("JLAN", true);
|
||||
pkt.packString("Alfresco CIFS", true);
|
||||
|
||||
pkt.packString("", true);
|
||||
|
||||
@@ -1645,4 +1647,5 @@ public class AuthenticateSession
|
||||
|
||||
setGuest(pkt.getParameter(2) != 0 ? true : false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -24,7 +24,10 @@
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.passthru;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
@@ -33,14 +36,28 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.filesys.server.SessionListener;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.auth.AuthContext;
|
||||
import org.alfresco.filesys.server.auth.AuthenticatorException;
|
||||
import org.alfresco.filesys.server.auth.ClientInfo;
|
||||
import org.alfresco.filesys.server.auth.CifsAuthenticator;
|
||||
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
|
||||
import org.alfresco.filesys.server.auth.ntlm.NTLM;
|
||||
import org.alfresco.filesys.server.auth.ntlm.NTLMMessage;
|
||||
import org.alfresco.filesys.server.auth.ntlm.TargetInfo;
|
||||
import org.alfresco.filesys.server.auth.ntlm.Type1NTLMMessage;
|
||||
import org.alfresco.filesys.server.auth.ntlm.Type2NTLMMessage;
|
||||
import org.alfresco.filesys.server.auth.ntlm.Type3NTLMMessage;
|
||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.smb.Capability;
|
||||
import org.alfresco.filesys.smb.SMBStatus;
|
||||
import org.alfresco.filesys.smb.server.SMBServer;
|
||||
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.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -66,6 +83,18 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
public final static int MinSessionTmo = 2000; // 2 seconds
|
||||
public final static int MaxSessionTmo = 30000; // 30 seconds
|
||||
|
||||
// Passthru keep alive interval
|
||||
|
||||
public final static long PassthruKeepAliveInterval = 60000L; // 60 seconds
|
||||
|
||||
// NTLM flags mask, used to mask out features that are not supported
|
||||
|
||||
private static final int NTLM_FLAGS = NTLM.Flag56Bit +
|
||||
NTLM.Flag128Bit +
|
||||
NTLM.FlagLanManKey +
|
||||
NTLM.FlagNegotiateNTLM +
|
||||
NTLM.FlagNegotiateUnicode;
|
||||
|
||||
// Passthru servers used to authenticate users
|
||||
|
||||
private PassthruServers m_passthruServers;
|
||||
@@ -192,7 +221,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
// using the session that has already been setup.
|
||||
|
||||
AuthenticateSession authSess = passDetails.getAuthenticateSession();
|
||||
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword());
|
||||
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword(), 0);
|
||||
|
||||
// Check if the user has been logged on as a guest
|
||||
|
||||
@@ -311,51 +340,43 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
*/
|
||||
public AuthContext getAuthContext( SMBSrvSession sess)
|
||||
{
|
||||
// Make sure the SMB server listener is installed
|
||||
|
||||
// Check for an SMB session
|
||||
if ( m_server == null && sess instanceof SMBSrvSession)
|
||||
{
|
||||
SMBSrvSession smbSess = (SMBSrvSession) sess;
|
||||
m_server = smbSess.getSMBServer();
|
||||
|
||||
// Install the server listener
|
||||
|
||||
m_server.addSessionListener(this);
|
||||
}
|
||||
|
||||
// Open a connection to the authentication server, use normal session setup
|
||||
|
||||
AuthContext authCtx = null;
|
||||
|
||||
// Check if the client is already authenticated, and it is not a null logon
|
||||
|
||||
if ( sess.hasAuthenticationContext() && sess.hasClientInformation() &&
|
||||
sess.getClientInformation().getAuthenticationToken() != null &&
|
||||
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Re-using existing challenge, already authenticated");
|
||||
|
||||
// Return the previous challenge, user is already authenticated
|
||||
|
||||
return sess.getAuthenticationContext();
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Open a connection to the authentication server
|
||||
|
||||
AuthenticateSession authSess = m_passthruServers.openSession();
|
||||
if (authSess != null)
|
||||
{
|
||||
|
||||
// Create an entry in the active sessions table for the new session
|
||||
|
||||
PassthruDetails passDetails = new PassthruDetails(sess, authSess);
|
||||
m_sessions.put(sess.getUniqueId(), passDetails);
|
||||
|
||||
// Use the challenge key returned from the authentication server
|
||||
|
||||
authCtx = new NTLanManAuthContext( authSess.getEncryptionKey());
|
||||
sess.setAuthenticationContext( authCtx);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru sessId=" + authSess.getSessionId() + ", auth ctx=" + authCtx);
|
||||
}
|
||||
AuthenticateSession authSess = m_passthruServers.openSession();
|
||||
if (authSess != null)
|
||||
{
|
||||
|
||||
// Create an entry in the active sessions table for the new session
|
||||
|
||||
PassthruDetails passDetails = new PassthruDetails(sess, authSess, false);
|
||||
m_sessions.put(sess.getUniqueId(), passDetails);
|
||||
|
||||
// Use the challenge key returned from the authentication server
|
||||
|
||||
authCtx = new NTLanManAuthContext( authSess.getEncryptionKey());
|
||||
sess.setAuthenticationContext( authCtx);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru sessId=" + authSess.getSessionId() + ", auth ctx=" + authCtx);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -370,6 +391,685 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
return authCtx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the CIFS negotiate response packet, the authenticator should add authentication specific fields
|
||||
* to the response.
|
||||
*
|
||||
* @param sess SMBSrvSession
|
||||
* @param respPkt SMBSrvPacket
|
||||
* @param extendedSecurity boolean
|
||||
* @exception AuthenticatorException
|
||||
*/
|
||||
public void generateNegotiateResponse(SMBSrvSession sess, SMBSrvPacket respPkt, boolean extendedSecurity)
|
||||
throws AuthenticatorException
|
||||
{
|
||||
// If the client does not support extended security then return a standard negotiate response
|
||||
// with an 8 byte challenge
|
||||
|
||||
if ( extendedSecurity == false)
|
||||
{
|
||||
super.generateNegotiateResponse( sess, respPkt, extendedSecurity);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the extended security negotiation flag is set
|
||||
|
||||
if (( respPkt.getFlags2() & SMBSrvPacket.FLG2_EXTENDEDSECURITY) == 0)
|
||||
respPkt.setFlags2( respPkt.getFlags2() + SMBSrvPacket.FLG2_EXTENDEDSECURITY);
|
||||
|
||||
// Get the negotiate response byte area position
|
||||
|
||||
int pos = respPkt.getByteOffset();
|
||||
byte[] buf = respPkt.getBuffer();
|
||||
|
||||
// Pack the CIFS server GUID into the negotiate response
|
||||
|
||||
UUID serverGUID = sess.getSMBServer().getServerGUID();
|
||||
|
||||
DataPacker.putIntelLong( serverGUID.getLeastSignificantBits(), buf, pos);
|
||||
DataPacker.putIntelLong( serverGUID.getMostSignificantBits(), buf, pos + 8);
|
||||
|
||||
pos += 16;
|
||||
|
||||
// Set the negotiate response length
|
||||
|
||||
respPkt.setByteCount(pos - respPkt.getByteOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the CIFS session setup request packet and build the session setup response
|
||||
*
|
||||
* @param sess SMBSrvSession
|
||||
* @param reqPkt SMBSrvPacket
|
||||
* @param respPkt SMBSrvPacket
|
||||
* @exception SMBSrvException
|
||||
*/
|
||||
public void processSessionSetup(SMBSrvSession sess, SMBSrvPacket reqPkt, SMBSrvPacket respPkt)
|
||||
throws SMBSrvException
|
||||
{
|
||||
// Check that the received packet looks like a valid NT session setup andX request
|
||||
|
||||
if (reqPkt.checkPacketIsValid(12, 0) == false)
|
||||
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
||||
|
||||
// Check if the request is using security blobs or the older hashed password format
|
||||
|
||||
if ( reqPkt.getParameterCount() == 13)
|
||||
{
|
||||
// Process the standard password session setup
|
||||
|
||||
super.processSessionSetup( 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);
|
||||
|
||||
// Extract the client details from the session setup request
|
||||
|
||||
int dataPos = reqPkt.getByteOffset();
|
||||
byte[] buf = reqPkt.getBuffer();
|
||||
|
||||
// Determine if ASCII or unicode strings are being used
|
||||
|
||||
boolean isUni = reqPkt.isUnicode();
|
||||
|
||||
// Make a note of the security blob position
|
||||
|
||||
int secBlobPos = dataPos;
|
||||
|
||||
// Extract the clients primary domain name string
|
||||
|
||||
dataPos += secBlobLen;
|
||||
reqPkt.setPosition( dataPos);
|
||||
|
||||
String domain = "";
|
||||
|
||||
if (reqPkt.hasMoreData()) {
|
||||
|
||||
// Extract the callers domain name
|
||||
|
||||
domain = reqPkt.unpackString(isUni);
|
||||
|
||||
if (domain == null)
|
||||
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
||||
}
|
||||
|
||||
// Extract the clients native operating system
|
||||
|
||||
String clientOS = "";
|
||||
|
||||
if (reqPkt.hasMoreData()) {
|
||||
|
||||
// Extract the callers operating system name
|
||||
|
||||
clientOS = reqPkt.unpackString(isUni);
|
||||
|
||||
if (clientOS == null)
|
||||
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
||||
}
|
||||
|
||||
// Store the client maximum buffer size, maximum multiplexed requests count and client capability flags
|
||||
|
||||
sess.setClientMaximumBufferSize(maxBufSize != 0 ? maxBufSize : SMBSrvSession.DefaultBufferSize);
|
||||
sess.setClientMaximumMultiplex(maxMpx);
|
||||
sess.setClientCapabilities(capabs);
|
||||
|
||||
// Create the client information and store in the session
|
||||
|
||||
ClientInfo client = new ClientInfo();
|
||||
client.setDomain(domain);
|
||||
client.setOperatingSystem(clientOS);
|
||||
|
||||
client.setLogonType( ClientInfo.LogonNormal);
|
||||
|
||||
// Set the remote address, if available
|
||||
|
||||
if ( sess.hasRemoteAddress())
|
||||
client.setClientAddress(sess.getRemoteAddress().getHostAddress());
|
||||
|
||||
// Set the process id for this client, for multi-stage logons
|
||||
|
||||
client.setProcessId( reqPkt.getProcessId());
|
||||
|
||||
// Get the current sesion setup object, or null
|
||||
|
||||
Object setupObj = sess.getSetupObject( client.getProcessId());
|
||||
|
||||
// Process the security blob
|
||||
|
||||
byte[] respBlob = null;
|
||||
boolean isNTLMSSP = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Check if the blob has the NTLMSSP signature
|
||||
|
||||
if ( secBlobLen >= NTLM.Signature.length) {
|
||||
|
||||
// Check for the NTLMSSP signature
|
||||
|
||||
int idx = 0;
|
||||
while ( idx < NTLM.Signature.length && buf[secBlobPos + idx] == NTLM.Signature[ idx])
|
||||
idx++;
|
||||
|
||||
if ( idx == NTLM.Signature.length)
|
||||
isNTLMSSP = true;
|
||||
}
|
||||
|
||||
// Process the security blob
|
||||
|
||||
if ( isNTLMSSP == true)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("NT Session setup NTLMSSP, MID=" + reqPkt.getMultiplexId() + ", UID=" + reqPkt.getUserId() + ", PID=" + reqPkt.getProcessId());
|
||||
|
||||
// Process an NTLMSSP security blob
|
||||
|
||||
respBlob = doNtlmsspSessionSetup( sess, client, buf, secBlobPos, secBlobLen, isUni);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid blob type
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
|
||||
}
|
||||
}
|
||||
catch (SMBSrvException ex)
|
||||
{
|
||||
// Cleanup any stored context
|
||||
|
||||
sess.removeSetupObject( client.getProcessId());
|
||||
|
||||
// Rethrow the exception
|
||||
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE))
|
||||
logger.debug("User " + client.getUserName() + " logged on " + (client != null ? " (type " + client.getLogonTypeString() + ")" : ""));
|
||||
|
||||
// Update the client information if not already set
|
||||
|
||||
if ( sess.getClientInformation() == null ||
|
||||
sess.getClientInformation().getUserName().length() == 0) {
|
||||
|
||||
// Set the client details for the session
|
||||
|
||||
sess.setClientInformation(client);
|
||||
}
|
||||
|
||||
// Get the response blob length, it can be null
|
||||
|
||||
int respLen = respBlob != null ? respBlob.length : 0;
|
||||
|
||||
// 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
|
||||
|
||||
boolean loggedOn = false;
|
||||
|
||||
if ( 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( 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
|
||||
respPkt.setParameter(1, 0); // Offset to chained response
|
||||
|
||||
respPkt.setParameter(2, 0); // Action
|
||||
respPkt.setParameter(3, respLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build a completed session setup response
|
||||
|
||||
respPkt.setLongErrorCode( SMBStatus.NTSuccess);
|
||||
|
||||
// Build the session setup response SMB
|
||||
|
||||
respPkt.setParameterCount(12);
|
||||
respPkt.setParameter(0, 0xFF); // No chained response
|
||||
respPkt.setParameter(1, 0); // Offset to chained response
|
||||
|
||||
respPkt.setParameter(2, SMBSrvSession.DefaultBufferSize);
|
||||
respPkt.setParameter(3, SMBSrvSession.NTMaxMultiplexed);
|
||||
respPkt.setParameter(4, 0); // virtual circuit number
|
||||
respPkt.setParameterLong(5, 0); // session key
|
||||
respPkt.setParameter(7, respLen);
|
||||
// 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
|
||||
|
||||
respPkt.setCommand( reqPkt.getCommand());
|
||||
respPkt.setByteCount(0);
|
||||
|
||||
respPkt.setTreeId( 0);
|
||||
respPkt.setUserId( uid);
|
||||
|
||||
// Set the various flags
|
||||
|
||||
int flags = respPkt.getFlags();
|
||||
flags &= ~SMBSrvPacket.FLG_CASELESS;
|
||||
respPkt.setFlags(flags);
|
||||
|
||||
int flags2 = SMBSrvPacket.FLG2_LONGFILENAMES + SMBSrvPacket.FLG2_EXTENDEDSECURITY + SMBSrvPacket.FLG2_LONGERRORCODE;
|
||||
if ( isUni)
|
||||
flags2 += SMBSrvPacket.FLG2_UNICODE;
|
||||
respPkt.setFlags2( flags2);
|
||||
|
||||
// Pack the security blob
|
||||
|
||||
int pos = respPkt.getByteOffset();
|
||||
buf = respPkt.getBuffer();
|
||||
|
||||
if ( respBlob != null)
|
||||
{
|
||||
System.arraycopy( respBlob, 0, buf, pos, respBlob.length);
|
||||
pos += respBlob.length;
|
||||
}
|
||||
|
||||
// Pack the OS, dialect and domain name strings
|
||||
|
||||
if ( isUni)
|
||||
pos = DataPacker.wordAlign(pos);
|
||||
|
||||
pos = DataPacker.putString("Java", buf, pos, true, isUni);
|
||||
pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni);
|
||||
pos = DataPacker.putString(sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni);
|
||||
|
||||
respPkt.setByteCount(pos - respPkt.getByteOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an NTLMSSP security blob
|
||||
*
|
||||
* @param sess SMBSrvSession
|
||||
* @param client ClientInfo
|
||||
* @param secbuf byte[]
|
||||
* @param secpos int
|
||||
* @param seclen int
|
||||
* @param unicode boolean
|
||||
* @exception SMBSrvException
|
||||
*/
|
||||
private final byte[] doNtlmsspSessionSetup( SMBSrvSession sess, ClientInfo client,
|
||||
byte[] secbuf, int secpos, int seclen, boolean unicode) throws SMBSrvException
|
||||
{
|
||||
// Determine the NTLmSSP message type
|
||||
|
||||
int msgType = NTLMMessage.isNTLMType( secbuf, secpos);
|
||||
byte[] respBlob = null;
|
||||
|
||||
if ( msgType == -1)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Invalid NTLMSSP token received");
|
||||
logger.debug(" Token=" + HexDump.hexString( secbuf, secpos, seclen, " "));
|
||||
}
|
||||
|
||||
// Return a logon failure status
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
|
||||
}
|
||||
|
||||
// Check for a type 1 NTLMSSP message
|
||||
|
||||
else if ( msgType == NTLM.Type1)
|
||||
{
|
||||
// Create the type 1 NTLM message from the token
|
||||
|
||||
Type1NTLMMessage type1Msg = new Type1NTLMMessage( secbuf, secpos, seclen);
|
||||
|
||||
// Build the type 2 NTLM response message
|
||||
//
|
||||
// Get the flags from the client request and mask out unsupported features
|
||||
|
||||
int ntlmFlags = type1Msg.getFlags() & NTLM_FLAGS;
|
||||
|
||||
// Generate a challenge for the response
|
||||
|
||||
NTLanManAuthContext ntlmCtx = (NTLanManAuthContext) getAuthContext( sess);
|
||||
|
||||
// Build a type2 message to send back to the client, containing the challenge
|
||||
|
||||
String domain = sess.getSMBServer().getServerName();
|
||||
|
||||
List<TargetInfo> tList = new ArrayList<TargetInfo>();
|
||||
|
||||
tList.add(new TargetInfo(NTLM.TargetDomain, domain));
|
||||
tList.add(new TargetInfo(NTLM.TargetServer, sess.getServerName()));
|
||||
tList.add(new TargetInfo(NTLM.TargetDNSDomain, domain));
|
||||
tList.add(new TargetInfo(NTLM.TargetFullDNS, domain));
|
||||
|
||||
ntlmFlags = NTLM.FlagChallengeAccept + NTLM.FlagRequestTarget +
|
||||
NTLM.FlagNegotiateNTLM + NTLM.FlagNegotiateUnicode +
|
||||
NTLM.FlagKeyExchange + NTLM.FlagTargetInfo + NTLM.Flag56Bit;
|
||||
|
||||
// NTLM.FlagAlwaysSign + NTLM.FlagNegotiateSign +
|
||||
|
||||
Type2NTLMMessage type2Msg = new Type2NTLMMessage();
|
||||
|
||||
type2Msg.buildType2(ntlmFlags, domain, ntlmCtx.getChallenge(), null, tList);
|
||||
|
||||
// Store the type 2 message in the session until the session setup is complete
|
||||
|
||||
sess.setSetupObject( client.getProcessId(), type2Msg);
|
||||
|
||||
// Set the response blob using the type 2 message
|
||||
|
||||
respBlob = type2Msg.getBytes();
|
||||
}
|
||||
else if ( msgType == NTLM.Type3)
|
||||
{
|
||||
// Create the type 3 NTLM message from the token
|
||||
|
||||
Type3NTLMMessage type3Msg = new Type3NTLMMessage( secbuf, secpos, seclen, unicode);
|
||||
|
||||
// Make sure a type 2 message was stored in the first stage of the session setup
|
||||
|
||||
if ( sess.hasSetupObject( client.getProcessId()) == false || sess.getSetupObject( client.getProcessId()) instanceof Type2NTLMMessage == false)
|
||||
{
|
||||
// Clear the setup object
|
||||
|
||||
sess.removeSetupObject( client.getProcessId());
|
||||
|
||||
// Return a logon failure
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
|
||||
}
|
||||
|
||||
// Determine if the client sent us NTLMv1 or NTLMv2
|
||||
|
||||
if ( type3Msg.hasFlag( NTLM.Flag128Bit) && type3Msg.hasFlag( NTLM.FlagNTLM2Key))
|
||||
{
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Received NTLMSSP/NTLMv2, not supported");
|
||||
|
||||
// Return a logon failure
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Looks like an NTLMv1 blob
|
||||
|
||||
doNTLMv1Logon( sess, client, type3Msg);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Logged on using NTLMSSP/NTLMv1");
|
||||
}
|
||||
}
|
||||
|
||||
// Return the response blob
|
||||
|
||||
return respBlob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an NTLMv1 logon using the NTLMSSP type3 message
|
||||
*
|
||||
* @param sess SMBSrvSession
|
||||
* @param client ClientInfo
|
||||
* @param type3Msg Type3NTLMMessage
|
||||
* @exception SMBSrvException
|
||||
*/
|
||||
private final void doNTLMv1Logon(SMBSrvSession sess, ClientInfo client, Type3NTLMMessage type3Msg)
|
||||
throws SMBSrvException
|
||||
{
|
||||
// Get the type 2 message that contains the challenge sent to the client
|
||||
|
||||
Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId());
|
||||
sess.removeSetupObject( client.getProcessId());
|
||||
|
||||
// Get the NTLM logon details
|
||||
|
||||
String userName = type3Msg.getUserName();
|
||||
|
||||
// Check for a null logon
|
||||
|
||||
if ( userName.length() == 0)
|
||||
{
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Null logon");
|
||||
|
||||
// Indicate a null logon in the client information
|
||||
|
||||
client.setLogonType( ClientInfo.LogonNull);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the active authentication session details for the server session
|
||||
|
||||
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
|
||||
|
||||
if (passDetails != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Authenticate the user by passing the hashed password to the authentication server
|
||||
// using the session that has already been setup.
|
||||
|
||||
AuthenticateSession authSess = passDetails.getAuthenticateSession();
|
||||
authSess.doSessionSetup( type3Msg.getDomain(), userName, null, type3Msg.getLMHash(), type3Msg.getNTLMHash(), 0);
|
||||
|
||||
// Check if the user has been logged on as a guest
|
||||
|
||||
if (authSess.isGuest())
|
||||
{
|
||||
// Check if the local server allows guest access
|
||||
|
||||
if (allowGuest() == true)
|
||||
{
|
||||
// Get a guest authentication token
|
||||
|
||||
doGuestLogon( client, sess);
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru authenticate user=" + userName + ", GUEST");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrap the service calls in a transaction
|
||||
|
||||
UserTransaction tx = m_transactionService.getUserTransaction( false);
|
||||
|
||||
try
|
||||
{
|
||||
// Start the transaction
|
||||
|
||||
tx.begin();
|
||||
|
||||
// Map the passthru username to an Alfresco person
|
||||
|
||||
NodeRef userNode = m_personService.getPerson(userName);
|
||||
if ( userNode != null)
|
||||
{
|
||||
// Get the person name and use that as the current user to line up with permission checks
|
||||
|
||||
String personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
|
||||
m_authComponent.setCurrentUser(personName);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Setting current user using person " + personName + " (username " + userName + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set using the user name
|
||||
|
||||
m_authComponent.setCurrentUser( userName);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Setting current user using username " + userName);
|
||||
}
|
||||
|
||||
// Get the authentication token and store
|
||||
|
||||
client.setAuthenticationToken( m_authComponent.getCurrentAuthentication());
|
||||
|
||||
// Indicate that the client is logged on
|
||||
|
||||
client.setLogonType( ClientInfo.LogonNormal);
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru authenticate user=" + userName + ", FULL");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Commit the transaction
|
||||
|
||||
if ( tx != null)
|
||||
{
|
||||
try {
|
||||
tx.commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Sink it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the client details
|
||||
|
||||
client.setDomain( type3Msg.getDomain());
|
||||
client.setUserName( userName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
// Debug
|
||||
|
||||
logger.error(ex.getMessage());
|
||||
|
||||
// Indicate logon failure
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTErr, SMBStatus.NTLogonFailure);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Remove the passthru session from the active list
|
||||
|
||||
m_sessions.remove(sess.getUniqueId());
|
||||
|
||||
// Close the passthru authentication session
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Close the authentication session
|
||||
|
||||
AuthenticateSession authSess = passDetails.getAuthenticateSession();
|
||||
authSess.CloseSession();
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Closed auth session, sessId=" + authSess.getSessionId());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
// Debug
|
||||
|
||||
logger.error("Passthru error closing session (auth user)", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug(" No PassthruDetails for " + sess.getUniqueId());
|
||||
|
||||
// Indicate logon failure
|
||||
|
||||
throw new SMBSrvException( SMBStatus.NTErr, SMBStatus.NTLogonFailure);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialzie the authenticator
|
||||
*
|
||||
@@ -510,6 +1210,18 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
smbServer.addSessionListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the server capability flags
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int getServerCapabilities()
|
||||
{
|
||||
return Capability.Unicode + Capability.RemoteAPIs + Capability.NTSMBs + Capability.NTFind +
|
||||
Capability.NTStatus + Capability.LargeFiles + Capability.LargeRead + Capability.LargeWrite +
|
||||
Capability.ExtendedSecurity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the authenticator, perform cleanup
|
||||
*/
|
||||
@@ -520,7 +1232,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
if ( m_passthruServers != null)
|
||||
m_passthruServers.shutdown();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SMB server session closed notification
|
||||
*
|
||||
@@ -582,48 +1294,37 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
*/
|
||||
public void sessionLoggedOn(SrvSession sess)
|
||||
{
|
||||
// Check if there is an active session to the authentication server for this local
|
||||
// session
|
||||
|
||||
// Check if the client information has an empty user name, if so then do not close the
|
||||
// authentication session
|
||||
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
|
||||
|
||||
if (sess.hasClientInformation() && sess.getClientInformation().getUserName() != null
|
||||
&& sess.getClientInformation().getUserName().length() > 0)
|
||||
if (passDetails != null && passDetails.hasKeepAlive() == false)
|
||||
{
|
||||
// Remove the passthru session from the active list
|
||||
|
||||
// Check if there is an active session to the authentication server for this local
|
||||
// session
|
||||
m_sessions.remove(sess.getUniqueId());
|
||||
|
||||
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
|
||||
// Close the passthru authentication session
|
||||
|
||||
if (passDetails != null)
|
||||
try
|
||||
{
|
||||
// Close the authentication session
|
||||
|
||||
AuthenticateSession authSess = passDetails.getAuthenticateSession();
|
||||
authSess.CloseSession();
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Closed auth session, sessId=" + authSess.getSessionId());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
// Remove the passthru session from the active list
|
||||
// Debug
|
||||
|
||||
m_sessions.remove(sess.getUniqueId());
|
||||
|
||||
// Close the passthru authentication session
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Close the authentication session
|
||||
|
||||
AuthenticateSession authSess = passDetails.getAuthenticateSession();
|
||||
authSess.CloseSession();
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Closed auth session, sessId=" + authSess.getSessionId());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
// Debug
|
||||
|
||||
logger.error("Passthru error closing session (logon)", ex);
|
||||
}
|
||||
logger.error("Passthru error closing session (logon)", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,6 @@ import org.alfresco.filesys.server.SrvSession;
|
||||
*/
|
||||
class PassthruDetails
|
||||
{
|
||||
|
||||
// Server session
|
||||
|
||||
private SrvSession m_sess;
|
||||
@@ -43,6 +42,10 @@ class PassthruDetails
|
||||
|
||||
private AuthenticateSession m_authSess;
|
||||
|
||||
// Flag to indicate if session should be kept alive
|
||||
|
||||
private boolean m_keepAlive;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
@@ -55,6 +58,21 @@ class PassthruDetails
|
||||
m_authSess = authSess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param authSess AuthenticateSession
|
||||
* @param keepAlive boolean
|
||||
*/
|
||||
public PassthruDetails(SrvSession sess, AuthenticateSession authSess, boolean keepAlive)
|
||||
{
|
||||
m_sess = sess;
|
||||
m_authSess = authSess;
|
||||
|
||||
m_keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the session details
|
||||
*
|
||||
@@ -74,4 +92,14 @@ class PassthruDetails
|
||||
{
|
||||
return m_authSess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the authentication session should be kept alive
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasKeepAlive()
|
||||
{
|
||||
return m_keepAlive;
|
||||
}
|
||||
}
|
||||
|
@@ -306,16 +306,16 @@ public class PassthruServers
|
||||
*/
|
||||
public final AuthenticateSession openSession()
|
||||
{
|
||||
return openSession( 0);
|
||||
return openSession( false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new session to an authentication server
|
||||
*
|
||||
* @param extFlags int
|
||||
* @param useExtSec boolean
|
||||
* @return AuthenticateSession
|
||||
*/
|
||||
public final AuthenticateSession openSession(int extFlags)
|
||||
public final AuthenticateSession openSession(boolean useExtSec)
|
||||
{
|
||||
// Get the details of an authentication server to connect to
|
||||
|
||||
@@ -331,7 +331,8 @@ public class PassthruServers
|
||||
// Open a new authentication session to the server
|
||||
|
||||
PCShare authShare = new PCShare(passthruServer.getAddress().getHostAddress(), "IPC$", "", "");
|
||||
authShare.setExtendedSecurityFlags( extFlags);
|
||||
if ( useExtSec == true)
|
||||
authShare.setExtendedSecurityFlags( SMBPacket.FLG2_EXTENDEDSECURITY);
|
||||
|
||||
AuthenticateSession authSess = null;
|
||||
|
||||
|
@@ -88,6 +88,7 @@ public class SMBPacket
|
||||
|
||||
public static final int FLG2_LONGFILENAMES = 0x0001;
|
||||
public static final int FLG2_EXTENDEDATTRIB = 0x0002;
|
||||
public static final int FLG2_SECURITYSIG = 0x0004;
|
||||
public static final int FLG2_EXTENDEDSECURITY = 0x0800;
|
||||
public static final int FLG2_READIFEXE = 0x2000;
|
||||
public static final int FLG2_LONGERRORCODE = 0x4000;
|
||||
@@ -589,6 +590,16 @@ public class SMBPacket
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SMB signing value, as a long value
|
||||
*
|
||||
* @return long
|
||||
*/
|
||||
public final long getSignature()
|
||||
{
|
||||
return DataPacker.getIntelLong( m_smbbuf, SIGNATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree identifier (TID)
|
||||
*
|
||||
* @return Tree identifier (TID)
|
||||
@@ -1131,6 +1142,16 @@ public class SMBPacket
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a long error code (NT status code)
|
||||
*
|
||||
* @param sts int
|
||||
*/
|
||||
public final void setLongErrorCode(int lsts)
|
||||
{
|
||||
DataPacker.putIntelInt(lsts, m_smbbuf, ERRORCODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SMB flags value.
|
||||
*
|
||||
* @param flg SMB flags value.
|
||||
@@ -1225,6 +1246,38 @@ public class SMBPacket
|
||||
DataPacker.putIntelShort(sid, m_smbbuf, SID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SMB signing signature
|
||||
*
|
||||
* @param ival int
|
||||
*/
|
||||
public final void setSignature( int ival)
|
||||
{
|
||||
DataPacker.putIntelInt( ival, m_smbbuf, SIGNATURE);
|
||||
DataPacker.putZeros( m_smbbuf, SIGNATURE + 4, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SMB signing signature
|
||||
*
|
||||
* @param lval long
|
||||
*/
|
||||
public final void setSignature( long lval)
|
||||
{
|
||||
DataPacker.putIntelLong( lval, m_smbbuf, SIGNATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SMB signing signature
|
||||
*
|
||||
* @param byts byte[]
|
||||
* @param offset int
|
||||
*/
|
||||
public final void setSignature( byte[] byts, int offset)
|
||||
{
|
||||
System.arraycopy( byts, offset, m_smbbuf, SIGNATURE, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tree identifier (TID)
|
||||
*
|
||||
|
Reference in New Issue
Block a user