Merged V3.2 to HEAD

15940: Merged V3.1 to V3.2 (record only)
      15939: Merged V3.2 to V3.1
         15936: ETHREEOH-2498: Fixed problems with auto-creation of users in CIFS Authenticators (including Kerberos)
   15936: ETHREEOH-2498: Fixed problems with auto-creation of users in CIFS Authenticators (including Kerberos)
      - Converted to using RetryingTransactionHelper and avoid problems with nested transactionService
      - Will trigger LDAP sync if enabled
      - Also switched on disableNTLM in kerberos-authentication-context.xml to force Kerberos CIFS authentication in Kerberos subsystem


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15941 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2009-08-26 19:15:18 +00:00
parent 49cb56a412
commit e184c83df5
5 changed files with 360 additions and 547 deletions

View File

@@ -87,6 +87,9 @@
<property name="jaasConfigEntryName"> <property name="jaasConfigEntryName">
<value>${kerberos.authentication.cifs.configEntryName}</value> <value>${kerberos.authentication.cifs.configEntryName}</value>
</property> </property>
<property name="disableNTLM">
<value>true</value>
</property>
</bean> </bean>
</beans> </beans>

View File

@@ -26,9 +26,6 @@ package org.alfresco.filesys.auth.cifs;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo; import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
@@ -42,6 +39,7 @@ import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.util.HexDump; import org.alfresco.jlan.util.HexDump;
import org.alfresco.repo.security.authentication.NTLMMode; import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken; import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
/** /**
* Alfresco Authenticator Class * Alfresco Authenticator Class
@@ -94,7 +92,7 @@ public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
* @param sess Server session * @param sess Server session
* @param alg Encryption algorithm * @param alg Encryption algorithm
*/ */
public int authenticateUser(ClientInfo client, SrvSession sess, int alg) public int authenticateUser(final ClientInfo client, final SrvSession sess, final int alg)
{ {
// Check that the client is an Alfresco client // Check that the client is an Alfresco client
@@ -138,7 +136,6 @@ public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
// Check if this is a guest logon // Check if this is a guest logon
int authSts = AUTH_DISALLOW; int authSts = AUTH_DISALLOW;
UserTransaction tx = null;
try try
{ {
@@ -172,24 +169,30 @@ public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
else if ( getNTLMAuthenticator().getNTLMMode() == NTLMMode.MD4_PROVIDER) else if ( getNTLMAuthenticator().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{ {
// Start a transaction // Start a transaction
authSts = doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Integer>()
{
tx = createTransaction(); public Integer execute() throws Throwable
tx.begin(); {
// Perform local MD4 password check
return doMD4UserAuthentication(client, sess, alg);
}
});
// Perform local MD4 password check
authSts = doMD4UserAuthentication(client, sess, alg);
} }
else else
{ {
// Start a transaction // Start a transaction
authSts = doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Integer>()
{
tx = createTransaction(); public Integer execute() throws Throwable
tx.begin(); {
// Perform passthru authentication password check
return doPassthruUserAuthentication(client, sess, alg);
}
});
// Perform passthru authentication password check
authSts = doPassthruUserAuthentication(client, sess, alg);
} }
// Check if the logon status indicates a guest logon // Check if the logon status indicates a guest logon
@@ -217,34 +220,6 @@ public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
if ( logger.isDebugEnabled()) if ( logger.isDebugEnabled())
logger.debug( ex); logger.debug( ex);
} }
finally
{
// Commit the transaction
if ( tx != null)
{
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
}
}
catch ( Exception ex)
{
}
}
}
// Check for an administrator logon // Check for an administrator logon

View File

@@ -24,8 +24,6 @@
*/ */
package org.alfresco.filesys.auth.cifs; package org.alfresco.filesys.auth.cifs;
import javax.transaction.UserTransaction;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
@@ -48,6 +46,7 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MD4PasswordEncoder; import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl; import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator; import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
@@ -348,49 +347,28 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
* @param client * @param client
* ClientInfo * ClientInfo
*/ */
protected final void getHomeFolderForUser(ClientInfo client) protected final void getHomeFolderForUser(final ClientInfo client)
{ {
// Check if the client is an Alfresco client, and not a null logon // Check if the client is an Alfresco client, and not a null logon
if ( client instanceof AlfrescoClientInfo == false || if (client instanceof AlfrescoClientInfo == false || client.isNullSession() == true)
client.isNullSession() == true) return;
return;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client; final AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Get the home folder for the user // Get the home folder for the user
UserTransaction tx = getTransactionService().getUserTransaction(); doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
NodeRef homeSpaceRef = null;
try
{ {
tx.begin();
homeSpaceRef = (NodeRef) getNodeService().getProperty(getPersonService().getPerson(client.getUserName()), ContentModel.PROP_HOMEFOLDER);
alfClient.setHomeFolder( homeSpaceRef);
tx.commit();
}
catch (Throwable ex)
{
try
{
tx.rollback();
}
catch (Throwable ex2)
{
logger.error("Failed to rollback transaction", ex2);
}
// Re-throw the exception public Object execute() throws Throwable
if (ex instanceof RuntimeException)
{ {
throw (RuntimeException) ex; NodeRef homeSpaceRef = (NodeRef) getNodeService().getProperty(
getPersonService().getPerson(client.getUserName()), ContentModel.PROP_HOMEFOLDER);
alfClient.setHomeFolder(homeSpaceRef);
return null;
} }
else });
{
throw new RuntimeException("Error during execution of transaction.", ex);
}
}
} }
/** /**
@@ -400,58 +378,29 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
* String * String
* @return String * @return String
*/ */
protected final String mapUserNameToPerson(String userName) protected final String mapUserNameToPerson(final String userName)
{ {
// Get the home folder for the user return doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<String>()
UserTransaction tx = getTransactionService().getUserTransaction();
String personName = null;
try
{ {
tx.begin();
personName = getPersonService().getUserIdentifier( userName);
tx.commit();
// Check if the person exists public String execute() throws Throwable
if (personName == null) {
tx = getTransactionService().getNonPropagatingUserTransaction( false);
tx.begin();
getPersonService().getPerson( userName);
personName = getPersonService().getUserIdentifier( userName);
tx.commit();
}
}
catch (Throwable ex)
{
try
{ {
tx.rollback(); // Get the home folder for the user
}
catch (Throwable ex2)
{
logger.error("Failed to rollback transaction", ex2);
}
// Re-throw the exception String personName = getPersonService().getUserIdentifier(userName);
if (ex instanceof RuntimeException) // Check if the person exists
{
throw (RuntimeException) ex; if (personName == null)
{
// Force creation of a person if possible
getPersonService().getPerson(userName);
personName = getPersonService().getUserIdentifier(userName);
return personName == null ? userName : personName;
}
return personName;
} }
else });
{
throw new RuntimeException("Error during execution of transaction.", ex);
}
}
// Return the person name
return personName;
} }
/** /**
@@ -545,7 +494,7 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
* *
* @return TransactionService * @return TransactionService
*/ */
protected final TransactionService getTransactionService() private final TransactionService getTransactionService()
{ {
return this.transactionService; return this.transactionService;
} }
@@ -565,49 +514,37 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
* @param cInfo * @param cInfo
* ClientInfo * ClientInfo
*/ */
protected final void checkForAdminUserName(ClientInfo cInfo) { protected final void checkForAdminUserName(final ClientInfo cInfo)
{
// Check if the user name is an administrator // Check if the user name is an administrator
UserTransaction tx = createTransaction(); doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{
try { public Object execute() throws Throwable
tx.begin(); {
if (cInfo.getLogonType() == ClientInfo.LogonNormal
&& getAuthorityService().isAdminAuthority(cInfo.getUserName()))
{
if ( cInfo.getLogonType() == ClientInfo.LogonNormal && getAuthorityService().isAdminAuthority(cInfo.getUserName())) { // Indicate that this is an administrator logon
// Indicate that this is an administrator logon cInfo.setLogonType(ClientInfo.LogonAdmin);
}
cInfo.setLogonType(ClientInfo.LogonAdmin); return null;
} }
tx.commit(); });
}
catch (Throwable ex) {
try {
tx.rollback();
}
catch (Throwable ex2) {
logger.error("Failed to rollback transaction", ex2);
}
// Re-throw the exception
if ( ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new RuntimeException("Error during execution of transaction.", ex);
}
}
} }
/** /**
* Create a transaction, this will be a wrteable transaction unless the system is in read-only mode. return * Does work in a transaction. This will be a writeable transaction unless the system is in read-only mode.
* UserTransaction
* *
* @return the user transaction * @param callback
* a callback that does the work
* @return the result, or <code>null</code> if not applicable
*/ */
protected final UserTransaction createTransaction() protected <T> T doInTransaction(RetryingTransactionHelper.RetryingTransactionCallback<T> callback)
{ {
// Get the transaction service // Get the transaction service
@@ -615,12 +552,10 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator implements
// DEBUG // DEBUG
if ( logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Using " + (txService.isReadOnly() ? "ReadOnly" : "Write") + " transaction"); logger.debug("Using " + (txService.isReadOnly() ? "ReadOnly" : "Write") + " transaction");
// Create the transaction return txService.getRetryingTransactionHelper().doInTransaction(callback, txService.isReadOnly());
return txService.getUserTransaction( txService.isReadOnly() ? true : false);
} }
/** /**

View File

@@ -41,8 +41,6 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import javax.security.sasl.RealmCallback; import javax.security.sasl.RealmCallback;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
@@ -80,6 +78,7 @@ import org.alfresco.jlan.util.DataPacker;
import org.alfresco.jlan.util.HexDump; import org.alfresco.jlan.util.HexDump;
import org.alfresco.repo.security.authentication.NTLMMode; import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator; import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.ietf.jgss.Oid; import org.ietf.jgss.Oid;
/** /**
@@ -634,7 +633,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
* @param reqPkt SMBSrvPacket * @param reqPkt SMBSrvPacket
* @exception SMBSrvException * @exception SMBSrvException
*/ */
public void processSessionSetup(SMBSrvSession sess, SMBSrvPacket reqPkt) public void processSessionSetup(final SMBSrvSession sess, final SMBSrvPacket reqPkt)
throws SMBSrvException throws SMBSrvException
{ {
// Check that the received packet looks like a valid NT session setup andX request // Check that the received packet looks like a valid NT session setup andX request
@@ -646,18 +645,21 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
if ( reqPkt.getParameterCount() == 13) if ( reqPkt.getParameterCount() == 13)
{ {
UserTransaction tx = null;
try try
{ {
// Start a transaction // Start a transaction
tx = createTransaction(); doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
tx.begin(); {
// Process the hashed password session setup public Object execute() throws Throwable
{
// Process the hashed password session setup
doHashedPasswordLogon( sess, reqPkt); doHashedPasswordLogon(sess, reqPkt);
return null;
}
});
} }
catch ( Exception ex) catch ( Exception ex)
{ {
@@ -665,34 +667,6 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
throw new SMBSrvException( SMBStatus.NTAccessDenied, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); throw new SMBSrvException( SMBStatus.NTAccessDenied, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
} }
finally
{
// Commit the transaction
if ( tx != null)
{
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
}
}
catch ( Exception ex)
{
}
}
}
// Hashed password processing complete // Hashed password processing complete
@@ -704,21 +678,21 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
int maxBufSize = reqPkt.getParameter(2); int maxBufSize = reqPkt.getParameter(2);
int maxMpx = reqPkt.getParameter(3); int maxMpx = reqPkt.getParameter(3);
int vcNum = reqPkt.getParameter(4); int vcNum = reqPkt.getParameter(4);
int secBlobLen = reqPkt.getParameter(7); final int secBlobLen = reqPkt.getParameter(7);
int capabs = reqPkt.getParameterLong(10); int capabs = reqPkt.getParameterLong(10);
// Extract the client details from the session setup request // Extract the client details from the session setup request
int dataPos = reqPkt.getByteOffset(); int dataPos = reqPkt.getByteOffset();
byte[] buf = reqPkt.getBuffer(); final byte[] buf = reqPkt.getBuffer();
// Determine if ASCII or unicode strings are being used // Determine if ASCII or unicode strings are being used
boolean isUni = reqPkt.isUnicode(); final boolean isUni = reqPkt.isUnicode();
// Make a note of the security blob position // Make a note of the security blob position
int secBlobPos = dataPos; final int secBlobPos = dataPos;
// Extract the clients primary domain name string // Extract the clients primary domain name string
@@ -764,7 +738,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
// Create the client information and store in the session // Create the client information and store in the session
ClientInfo client = new AlfrescoClientInfo(); final ClientInfo client = new AlfrescoClientInfo();
client.setDomain(domain); client.setDomain(domain);
client.setOperatingSystem(clientOS); client.setOperatingSystem(clientOS);
@@ -786,9 +760,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
// Process the security blob // Process the security blob
byte[] respBlob = null; byte[] respBlob = null;
boolean isNTLMSSP = false; final boolean isNTLMSSP;
UserTransaction tx = null;
try try
{ {
@@ -803,39 +775,36 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
while ( idx < NTLM.Signature.length && buf[secBlobPos + idx] == NTLM.Signature[ idx]) while ( idx < NTLM.Signature.length && buf[secBlobPos + idx] == NTLM.Signature[ idx])
idx++; idx++;
if ( idx == NTLM.Signature.length) isNTLMSSP = ( idx == NTLM.Signature.length);
isNTLMSSP = true; }
else {
isNTLMSSP = false;
} }
// Start a transaction // Start a transaction
tx = createTransaction(); respBlob = doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<byte[]>()
tx.begin();
// Process the security blob
if ( isNTLMSSP == true)
{ {
// Process an NTLMSSP security blob
respBlob = doNtlmsspSessionSetup( sess, client, buf, secBlobPos, secBlobLen, isUni); public byte[] execute() throws Throwable
} {
else // Process the security blob
{
// Process an SPNEGO security blob
respBlob = doSpnegoSessionSetup( sess, client, buf, secBlobPos, secBlobLen, isUni); if (isNTLMSSP)
} {
} // Process an NTLMSSP security blob
catch (SMBSrvException ex)
{
// Cleanup any stored context
sess.removeSetupObject( client.getProcessId()); return doNtlmsspSessionSetup(sess, client, buf, secBlobPos, secBlobLen, isUni);
}
else
{
// Process an SPNEGO security blob
// Rethrow the exception return doSpnegoSessionSetup(sess, client, buf, secBlobPos, secBlobLen, isUni);
}
}
});
throw ex;
} }
catch ( Exception ex) catch ( Exception ex)
{ {
@@ -847,34 +816,6 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
throw new SMBSrvException( SMBStatus.NTAccessDenied, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); throw new SMBSrvException( SMBStatus.NTAccessDenied, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
} }
finally
{
// Commit the transaction
if ( tx != null)
{
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
}
}
catch ( Exception ex)
{
}
}
}
// Debug // Debug
@@ -1046,11 +987,11 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
// Pack the security blob // Pack the security blob
int pos = respPkt.getByteOffset(); int pos = respPkt.getByteOffset();
buf = respPkt.getBuffer(); byte[] buf1 = respPkt.getBuffer();
if ( respBlob != null) if ( respBlob != null)
{ {
System.arraycopy( respBlob, 0, buf, pos, respBlob.length); System.arraycopy( respBlob, 0, buf1, pos, respBlob.length);
pos += respBlob.length; pos += respBlob.length;
} }
@@ -1059,9 +1000,9 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
if ( isUni) if ( isUni)
pos = DataPacker.wordAlign(pos); pos = DataPacker.wordAlign(pos);
pos = DataPacker.putString("Java", buf, pos, true, isUni); pos = DataPacker.putString("Java", buf1, pos, true, isUni);
pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni); pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf1, pos, true, isUni);
pos = DataPacker.putString(getCIFSConfig().getDomainName(), buf, pos, true, isUni); pos = DataPacker.putString(getCIFSConfig().getDomainName(), buf1, pos, true, isUni);
respPkt.setByteCount(pos - respPkt.getByteOffset()); respPkt.setByteCount(pos - respPkt.getByteOffset());
} }

View File

@@ -28,9 +28,6 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo; import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
@@ -68,6 +65,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.NTLMMode; import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator; import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -158,14 +156,14 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
* @param alg int * @param alg int
* @return int * @return int
*/ */
public int authenticateUser(ClientInfo client, SrvSession sess, int alg) public int authenticateUser(final ClientInfo client, final SrvSession sess, int alg)
{ {
// Check that the client is an Alfresco client // Check that the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false) if ( client instanceof AlfrescoClientInfo == false)
return ICifsAuthenticator.AUTH_DISALLOW; return ICifsAuthenticator.AUTH_DISALLOW;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client; final AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// The null session will only be allowed to connect to the IPC$ named pipe share. // The null session will only be allowed to connect to the IPC$ named pipe share.
@@ -181,224 +179,196 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
// Start a transaction // Start a transaction
UserTransaction tx = createTransaction(); return doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Integer>(){
int authSts = AUTH_DISALLOW;
try public Integer execute() throws Throwable
{
// Start the transaction
tx.begin();
// Check if the client is already authenticated, and it is not a null logon
if ( alfClient.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
{
// Use the existing authentication token
getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( client.getUserName()));
// Debug
if ( logger.isDebugEnabled())
logger.debug("Re-using existing authentication token");
// Return the authentication status
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
}
// Check if this is a guest logon
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Check if guest logons are allowed
if ( allowGuest() == false)
return AUTH_DISALLOW;
// Get a guest authentication token
doGuestLogon( client, sess);
// Indicate logged on as guest
authSts = AUTH_GUEST;
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + getStatusAsString(authSts));
// Return the guest status
return authSts;
}
// Find the active authentication session details for the server session
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
if (passDetails != null)
{ {
int authSts = AUTH_DISALLOW;
try try
{ {
// Check if the client is already authenticated, and it is not a null logon
// Authenticate the user by passing the hashed password to the authentication server if ( alfClient.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
// using the session that has already been setup. {
// Use the existing authentication token
AuthenticateSession authSess = passDetails.getAuthenticateSession(); getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( client.getUserName()));
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword(), 0);
// Check if the user has been logged on as a guest // Debug
if (authSess.isGuest()) if ( logger.isDebugEnabled())
logger.debug("Re-using existing authentication token");
// Return the authentication status
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
}
// Check if this is a guest logon
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Check if guest logons are allowed
if ( allowGuest() == false)
return AUTH_DISALLOW;
// Get a guest authentication token
doGuestLogon( client, sess);
// Indicate logged on as guest
authSts = AUTH_GUEST;
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + getStatusAsString(authSts));
// Return the guest status
return authSts;
}
// Find the active authentication session details for the server session
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
if (passDetails != null)
{ {
// Check if the local server allows guest access try
if (allowGuest() == true)
{ {
// Get a guest authentication token
doGuestLogon( client, sess); // Authenticate the user by passing the hashed password to the authentication server
// using the session that has already been setup.
// Allow the user access as a guest AuthenticateSession authSess = passDetails.getAuthenticateSession();
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword(), 0);
authSts = ICifsAuthenticator.AUTH_GUEST; // 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);
// Allow the user access as a guest
authSts = ICifsAuthenticator.AUTH_GUEST;
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + client.getUserName() + ", GUEST");
}
}
else
{
// Map the passthru username to an Alfresco person
String username = client.getUserName();
String personName = getPersonService().getUserIdentifier( username);
if ( personName != null)
{
// Use the person name as the current user
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser(personName));
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + username + ")");
// Allow the user full access to the server
authSts = ICifsAuthenticator.AUTH_ALLOW;
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
}
else if ( logger.isDebugEnabled())
logger.debug("Failed to find person matching user " + username);
}
}
catch (Exception ex)
{
// Debug // Debug
if (logger.isDebugEnabled()) logger.error(ex);
logger.debug("Passthru authenticate user=" + client.getUserName() + ", GUEST"); }
// Keep the authentication session if the user session is an SMB session, else close the
// session now
if ((sess instanceof SMBSrvSession) == false)
{
// 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 else
{ {
// Map the passthru username to an Alfresco person
String username = client.getUserName();
String personName = getPersonService().getUserIdentifier( username);
if ( personName != null)
{
// Use the person name as the current user
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser(personName));
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + username + ")");
// Allow the user full access to the server
authSts = ICifsAuthenticator.AUTH_ALLOW;
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
}
else if ( logger.isDebugEnabled())
logger.debug("Failed to find person matching user " + username);
}
}
catch (Exception ex)
{
// Debug
logger.error(ex);
}
// Keep the authentication session if the user session is an SMB session, else close the
// session now
if ((sess instanceof SMBSrvSession) == false)
{
// 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 // DEBUG
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Closed auth session, sessId=" + authSess.getSessionId()); logger.debug(" No PassthruDetails for " + sess.getUniqueId());
}
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());
}
}
catch ( Exception ex)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( ex);
// Return an access denied status
return AUTH_DISALLOW;
}
finally
{
// Commit the transaction
if ( tx != null)
{
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
} }
} }
catch ( Exception ex) catch ( Exception ex)
{ {
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( ex);
// Return an access denied status
return AUTH_DISALLOW;
} }
}
}
// Return the authentication status // Return the authentication status
return authSts; return authSts;
}});
} }
/** /**
@@ -954,7 +924,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
* @param type3Msg Type3NTLMMessage * @param type3Msg Type3NTLMMessage
* @exception SMBSrvException * @exception SMBSrvException
*/ */
private final void doNTLMv1Logon(SMBSrvSession sess, ClientInfo client, Type3NTLMMessage type3Msg) private final void doNTLMv1Logon(SMBSrvSession sess, final ClientInfo client, Type3NTLMMessage type3Msg)
throws SMBSrvException throws SMBSrvException
{ {
// Get the type 2 message that contains the challenge sent to the client // Get the type 2 message that contains the challenge sent to the client
@@ -963,7 +933,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
// Get the NTLM logon details // Get the NTLM logon details
String userName = type3Msg.getUserName(); final String userName = type3Msg.getUserName();
// Check for a null logon // Check for a null logon
@@ -1016,70 +986,59 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
{ {
// Wrap the service calls in a transaction // Wrap the service calls in a transaction
UserTransaction tx = createTransaction(); doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
try
{ {
// Start the transaction
tx.begin(); public Object execute() throws Throwable
// Map the passthru username to an Alfresco person
NodeRef userNode = getPersonService().getPerson(userName);
if ( userNode != null)
{ {
// Get the person name and use that as the current user to line up with permission checks // Map the passthru username to an Alfresco person
String personName = (String) getNodeService().getProperty(userNode, ContentModel.PROP_USERNAME); NodeRef userNode = getPersonService().getPerson(userName);
getAuthenticationComponent().setCurrentUser(personName); if (userNode != null)
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + userName + ")");
}
else
{
// Set using the user name
getAuthenticationComponent().setCurrentUser( userName);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using username " + userName);
}
// Get the authentication token and store
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().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 // Get the person name and use that as the current user to line up with permission
// checks
String personName = (String) getNodeService().getProperty(userNode,
ContentModel.PROP_USERNAME);
getAuthenticationComponent().setCurrentUser(personName);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username "
+ userName + ")");
} }
else
{
// Set using the user name
getAuthenticationComponent().setCurrentUser(userName);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Setting current user using username " + userName);
}
// Get the authentication token and store
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken(getAuthenticationComponent().getCurrentAuthentication());
// Indicate that the client is logged on
client.setLogonType(ClientInfo.LogonNormal);
// Debug
if (logger.isDebugEnabled())
logger.debug("Passthru authenticate user=" + userName + ", FULL");
return null;
} }
} });
} }
// Update the client details // Update the client details