mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Added guest user support to FTP server/filesystem authenticator. Changed authentication to use the standard authentication classes so FTP should work with LDAP and Kerberos setups.
Fixed server session transaction rollback problem. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2308 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -344,6 +344,18 @@ public class FTPPath
|
|||||||
return m_shareDev != null ? true : false;
|
return m_shareDev != null ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the shared device
|
||||||
|
*
|
||||||
|
* @param share DiskSharedDevice
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public final boolean setSharedDevice(DiskSharedDevice share)
|
||||||
|
{
|
||||||
|
m_shareDev = share;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an FTP path to the specified file
|
* Build an FTP path to the specified file
|
||||||
*
|
*
|
||||||
|
@@ -31,15 +31,16 @@ import java.util.Enumeration;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.transaction.Status;
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.alfresco.filesys.server.SrvSession;
|
import org.alfresco.filesys.server.SrvSession;
|
||||||
import org.alfresco.filesys.server.auth.ClientInfo;
|
import org.alfresco.filesys.server.auth.ClientInfo;
|
||||||
import org.alfresco.filesys.server.auth.SrvAuthenticator;
|
|
||||||
import org.alfresco.filesys.server.auth.acl.AccessControl;
|
import org.alfresco.filesys.server.auth.acl.AccessControl;
|
||||||
import org.alfresco.filesys.server.auth.acl.AccessControlManager;
|
import org.alfresco.filesys.server.auth.acl.AccessControlManager;
|
||||||
import org.alfresco.filesys.server.core.SharedDevice;
|
import org.alfresco.filesys.server.core.SharedDevice;
|
||||||
import org.alfresco.filesys.server.core.SharedDeviceList;
|
import org.alfresco.filesys.server.core.SharedDeviceList;
|
||||||
|
import org.alfresco.filesys.server.filesys.AccessDeniedException;
|
||||||
import org.alfresco.filesys.server.filesys.AccessMode;
|
import org.alfresco.filesys.server.filesys.AccessMode;
|
||||||
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
||||||
import org.alfresco.filesys.server.filesys.DiskFullException;
|
import org.alfresco.filesys.server.filesys.DiskFullException;
|
||||||
@@ -53,11 +54,22 @@ import org.alfresco.filesys.server.filesys.FileStatus;
|
|||||||
import org.alfresco.filesys.server.filesys.NetworkFile;
|
import org.alfresco.filesys.server.filesys.NetworkFile;
|
||||||
import org.alfresco.filesys.server.filesys.NotifyChange;
|
import org.alfresco.filesys.server.filesys.NotifyChange;
|
||||||
import org.alfresco.filesys.server.filesys.SearchContext;
|
import org.alfresco.filesys.server.filesys.SearchContext;
|
||||||
|
import org.alfresco.filesys.server.filesys.SrvDiskInfo;
|
||||||
import org.alfresco.filesys.server.filesys.TreeConnection;
|
import org.alfresco.filesys.server.filesys.TreeConnection;
|
||||||
import org.alfresco.filesys.server.filesys.TreeConnectionHash;
|
import org.alfresco.filesys.server.filesys.TreeConnectionHash;
|
||||||
|
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.sun.star.uno.RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FTP Server Session Class
|
* FTP Server Session Class
|
||||||
*
|
*
|
||||||
@@ -333,7 +345,10 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
// Initialize the current working directory using the root path
|
// Initialize the current working directory using the root path
|
||||||
|
|
||||||
m_cwd = new FTPPath(rootPath);
|
m_cwd = new FTPPath(rootPath);
|
||||||
m_cwd.setSharedDevice(getShareList(), this);
|
if ( rootPath.hasSharedDevice())
|
||||||
|
m_cwd.setSharedDevice( rootPath.getSharedDevice());
|
||||||
|
else
|
||||||
|
m_cwd.setSharedDevice(getShareList(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,7 +378,15 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
*/
|
*/
|
||||||
protected final FTPPath generatePathForRequest(FTPRequest req, boolean filePath, boolean checkExists)
|
protected final FTPPath generatePathForRequest(FTPRequest req, boolean filePath, boolean checkExists)
|
||||||
{
|
{
|
||||||
|
// Use the global share list for normal connections and the per session list for guest access
|
||||||
|
|
||||||
|
SharedDeviceList shareList = null;
|
||||||
|
|
||||||
|
if ( getClientInformation().isGuest())
|
||||||
|
shareList = getDynamicShareList();
|
||||||
|
else
|
||||||
|
shareList = getShareList();
|
||||||
|
|
||||||
// Convert the path to an FTP format path
|
// Convert the path to an FTP format path
|
||||||
|
|
||||||
String path = convertToFTPSeperators(req.getArgument());
|
String path = convertToFTPSeperators(req.getArgument());
|
||||||
@@ -412,7 +435,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
|
|
||||||
// Find the associated shared device
|
// Find the associated shared device
|
||||||
|
|
||||||
if (ftpPath.setSharedDevice(getShareList(), this) == false)
|
if (ftpPath.setSharedDevice( shareList, this) == false)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -439,7 +462,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
// Remove the last directory from the path
|
// Remove the last directory from the path
|
||||||
|
|
||||||
m_cwd.removeDirectory();
|
m_cwd.removeDirectory();
|
||||||
m_cwd.setSharedDevice(getShareList(), this);
|
m_cwd.setSharedDevice( shareList, this);
|
||||||
return m_cwd;
|
return m_cwd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -477,7 +500,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
|
|
||||||
// Find the associated shared device, if not already set
|
// Find the associated shared device, if not already set
|
||||||
|
|
||||||
if (ftpPath.hasSharedDevice() == false && ftpPath.setSharedDevice(getShareList(), this) == false)
|
if (ftpPath.hasSharedDevice() == false && ftpPath.setSharedDevice( shareList, this) == false)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,6 +567,11 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isErrorEnabled())
|
||||||
|
logger.error("Error generating FTP path", ex);
|
||||||
|
|
||||||
ftpPath = null;
|
ftpPath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -731,8 +759,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Check if the client information has been set, this indicates a user
|
// Check if the client information has been set, this indicates a user
|
||||||
// command has been
|
// command has been received
|
||||||
// received
|
|
||||||
|
|
||||||
if (hasClientInformation() == false)
|
if (hasClientInformation() == false)
|
||||||
{
|
{
|
||||||
@@ -743,76 +770,141 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
|
|
||||||
// Check for an anonymous login, accept any password string
|
// Check for an anonymous login, accept any password string
|
||||||
|
|
||||||
if (getClientInformation().isGuest())
|
ClientInfo cInfo = getClientInformation();
|
||||||
|
|
||||||
|
if (cInfo.isGuest())
|
||||||
{
|
{
|
||||||
|
if ( getFTPServer().allowAnonymous() == true)
|
||||||
// Save the anonymous login password string
|
|
||||||
|
|
||||||
getClientInformation().setPassword(req.getArgument());
|
|
||||||
|
|
||||||
// Accept the login
|
|
||||||
|
|
||||||
setLoggedOn(true);
|
|
||||||
sendFTPResponse(230, "User logged in, proceed");
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
|
||||||
logger.debug("Anonymous login, info=" + req.getArgument());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the user
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// Get the client information and store the received plain text
|
|
||||||
// password
|
|
||||||
|
|
||||||
getClientInformation().setPassword(req.getArgument());
|
|
||||||
|
|
||||||
// Authenticate the user
|
|
||||||
|
|
||||||
SrvAuthenticator auth = getServer().getConfiguration().getAuthenticator();
|
|
||||||
|
|
||||||
int access = auth.authenticateUserPlainText(getClientInformation(), this);
|
|
||||||
|
|
||||||
if (access == SrvAuthenticator.AUTH_ALLOW)
|
|
||||||
{
|
{
|
||||||
|
// Authenticate as the guest user
|
||||||
// User successfully logged on
|
|
||||||
|
AuthenticationComponent authComponent = getServer().getConfiguration().getAuthenticationComponent();
|
||||||
sendFTPResponse(230, "User logged in, proceed");
|
cInfo.setUserName( authComponent.getGuestUserName());
|
||||||
setLoggedOn(true);
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
|
||||||
logger.debug("User " + getClientInformation().getUserName() + ", logon successful");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Return an access denied error
|
// Return an access denied error
|
||||||
|
|
||||||
sendFTPResponse(530, "Access denied");
|
sendFTPResponse(530, "Access denied");
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
||||||
logger.debug("User " + getClientInformation().getUserName() + ", logon failed");
|
logger.debug("Anonymous logon not allowed");
|
||||||
|
|
||||||
// Close the connection
|
// Close the connection
|
||||||
|
|
||||||
closeSession();
|
closeSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the user has successfully logged on to the FTP server then inform
|
// Get the client information and store the received plain text password
|
||||||
// listeners
|
|
||||||
|
cInfo.setPassword(req.getArgument());
|
||||||
|
|
||||||
|
// Use the normal authentication service as we have the plaintext password
|
||||||
|
|
||||||
|
AuthenticationService authService = getServer().getConfiguration().getAuthenticationService();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Authenticate the user
|
||||||
|
|
||||||
|
if ( cInfo.isGuest())
|
||||||
|
{
|
||||||
|
// Authenticate as the guest user
|
||||||
|
|
||||||
|
authService.authenticateAsGuest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Authenticate as a normal user
|
||||||
|
|
||||||
|
authService.authenticate( cInfo.getUserName(), cInfo.getPasswordAsCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
// User successfully logged on
|
||||||
|
|
||||||
|
sendFTPResponse(230, "User logged in, proceed");
|
||||||
|
setLoggedOn(true);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
||||||
|
logger.debug("User " + getClientInformation().getUserName() + ", logon successful");
|
||||||
|
}
|
||||||
|
catch (org.alfresco.repo.security.authentication.AuthenticationException ex)
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Logon failed", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the logon was successful
|
||||||
|
|
||||||
|
if ( isLoggedOn() == true)
|
||||||
|
{
|
||||||
|
// If the user has successfully logged on to the FTP server then inform listeners
|
||||||
|
|
||||||
if (isLoggedOn())
|
|
||||||
getFTPServer().sessionLoggedOn(this);
|
getFTPServer().sessionLoggedOn(this);
|
||||||
|
|
||||||
|
// If this is a guest logon then we need to set the root folder to the guest user home folder
|
||||||
|
// as guest is not allowed access to other areas
|
||||||
|
|
||||||
|
if ( cInfo.isGuest())
|
||||||
|
{
|
||||||
|
// Generate a dynamic share with the guest users home folder as the root
|
||||||
|
|
||||||
|
DiskSharedDevice guestShare = createHomeDiskShare( cInfo);
|
||||||
|
addDynamicShare( guestShare);
|
||||||
|
|
||||||
|
// Set the root path for the guest logon to the guest share
|
||||||
|
|
||||||
|
StringBuilder rootPath = new StringBuilder();
|
||||||
|
|
||||||
|
rootPath.append(FTP_SEPERATOR);
|
||||||
|
rootPath.append( guestShare.getName());
|
||||||
|
rootPath.append(FTP_SEPERATOR);
|
||||||
|
|
||||||
|
FTPPath guestRoot = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Set the root path for this FTP session
|
||||||
|
|
||||||
|
guestRoot = new FTPPath( rootPath.toString());
|
||||||
|
guestRoot.setSharedDevice( guestShare);
|
||||||
|
setRootPath( guestRoot);
|
||||||
|
}
|
||||||
|
catch ( InvalidPathException ex)
|
||||||
|
{
|
||||||
|
if ( logger.isErrorEnabled())
|
||||||
|
logger.error("Error setting guest FTP root path", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
||||||
|
logger.debug(" Using root path " + guestRoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// Return an access denied error
|
||||||
|
|
||||||
|
sendFTPResponse(530, "Access denied");
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && hasDebug(DBG_STATE))
|
||||||
|
logger.debug("User " + getClientInformation().getUserName() + ", logon failed");
|
||||||
|
|
||||||
|
// Close the connection
|
||||||
|
|
||||||
|
closeSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2045,9 +2137,19 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
if (logger.isDebugEnabled() && hasDebug(DBG_FILEIO))
|
if (logger.isDebugEnabled() && hasDebug(DBG_FILEIO))
|
||||||
logger.debug(" Transfer complete, file closed");
|
logger.debug(" Transfer complete, file closed");
|
||||||
}
|
}
|
||||||
|
catch( AccessDeniedException ex)
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
||||||
|
logger.debug(" Access denied", ex);
|
||||||
|
|
||||||
|
// Session does not have write access to the filesystem
|
||||||
|
|
||||||
|
sendFTPResponse(550, "Access denied");
|
||||||
|
}
|
||||||
catch (SocketException ex)
|
catch (SocketException ex)
|
||||||
{
|
{
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
|
|
||||||
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
||||||
@@ -2093,13 +2195,13 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
|
|
||||||
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
||||||
logger.debug(" Error during transfer", ex);
|
logger.debug(" Error during transfer", ex);
|
||||||
ex.printStackTrace();
|
|
||||||
|
|
||||||
// Indicate that there was an error during transmission of the file
|
// Indicate that there was an error during transmission of the file
|
||||||
// data
|
// data
|
||||||
|
|
||||||
sendFTPResponse(426, "Error during transmission");
|
sendFTPResponse(426, "Error during transmission");
|
||||||
} finally
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
|
|
||||||
// Close the network file
|
// Close the network file
|
||||||
@@ -2216,6 +2318,17 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (AccessDeniedException ex)
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled() && hasDebug(DBG_ERROR))
|
||||||
|
logger.debug(" Access denied", ex);
|
||||||
|
|
||||||
|
// Session does not have write access to the filesystem
|
||||||
|
|
||||||
|
sendFTPResponse(550, "Access denied");
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
sendFTPResponse(450, "File action not taken");
|
sendFTPResponse(450, "File action not taken");
|
||||||
@@ -2444,7 +2557,8 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
{
|
{
|
||||||
sendFTPResponse(450, "File action not taken");
|
sendFTPResponse(450, "File action not taken");
|
||||||
return;
|
return;
|
||||||
} finally
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
|
|
||||||
// Clear the rename details
|
// Clear the rename details
|
||||||
@@ -2859,8 +2973,14 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
{
|
{
|
||||||
|
|
||||||
// The first level of directories are mapped to the available shares
|
// The first level of directories are mapped to the available shares
|
||||||
|
// Guest users only see their own list of shares
|
||||||
|
|
||||||
SharedDeviceList shares = getShareList();
|
SharedDeviceList shares = null;
|
||||||
|
if ( getClientInformation().isGuest())
|
||||||
|
shares = getDynamicShareList();
|
||||||
|
else
|
||||||
|
getShareList();
|
||||||
|
|
||||||
if (shares != null)
|
if (shares != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -3043,10 +3163,11 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
if (tree == null)
|
if (tree == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Create a new tree connection
|
// Create a new tree connection, do not add dynamic shares to the connection cache
|
||||||
|
|
||||||
tree = new TreeConnection(share);
|
tree = new TreeConnection(share);
|
||||||
m_connections.addConnection(tree);
|
if ( share.isTemporary() == false)
|
||||||
|
m_connections.addConnection(tree);
|
||||||
|
|
||||||
// Set the access permission for the shared filesystem
|
// Set the access permission for the shared filesystem
|
||||||
|
|
||||||
@@ -3068,6 +3189,73 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a disk share for the home folder
|
||||||
|
*
|
||||||
|
* @param client ClientInfo
|
||||||
|
* @return DiskSharedDevice
|
||||||
|
*/
|
||||||
|
private final DiskSharedDevice createHomeDiskShare(ClientInfo client)
|
||||||
|
{
|
||||||
|
// Check if the home folder has been set for the user
|
||||||
|
|
||||||
|
if ( client.hasHomeFolder() == false)
|
||||||
|
{
|
||||||
|
// Get the required services
|
||||||
|
|
||||||
|
NodeService nodeService = getServer().getConfiguration().getNodeService();
|
||||||
|
PersonService personService = getServer().getConfiguration().getPersonService();
|
||||||
|
TransactionService transService = getServer().getConfiguration().getTransactionService();
|
||||||
|
|
||||||
|
// Get the home folder for the user
|
||||||
|
|
||||||
|
UserTransaction tx = transService.getUserTransaction();
|
||||||
|
NodeRef homeSpaceRef = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tx.begin();
|
||||||
|
homeSpaceRef = (NodeRef) nodeService.getProperty( personService.getPerson(client.getUserName()),
|
||||||
|
ContentModel.PROP_HOMEFOLDER);
|
||||||
|
client.setHomeFolder( homeSpaceRef);
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
catch (Throwable ex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tx.rollback();
|
||||||
|
}
|
||||||
|
catch (Exception ex2)
|
||||||
|
{
|
||||||
|
logger.error("Failed to rollback transaction", ex2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ex instanceof RuntimeException)
|
||||||
|
{
|
||||||
|
throw (RuntimeException)ex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Failed to get home folder", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the disk driver and context
|
||||||
|
|
||||||
|
DiskInterface diskDrv = getServer().getConfiguration().getDiskInterface();
|
||||||
|
DiskDeviceContext diskCtx = new ContentContext("", "", client.getHomeFolder());
|
||||||
|
|
||||||
|
// Default the filesystem to look like an 80Gb sized disk with 90% free space
|
||||||
|
|
||||||
|
diskCtx.setDiskInformation(new SrvDiskInfo(2560, 64, 512, 2304));
|
||||||
|
|
||||||
|
// Create a temporary shared device for the users home directory
|
||||||
|
|
||||||
|
return new DiskSharedDevice( client.getUserName(), diskDrv, diskCtx, SharedDevice.Temporary);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the FTP session in a seperate thread
|
* Start the FTP session in a seperate thread
|
||||||
*/
|
*/
|
||||||
@@ -3351,24 +3539,20 @@ public class FTPSrvSession extends SrvSession implements Runnable
|
|||||||
+ FTPCommand.getCommandName(ftpReq.isCommand()) + " in " + duration + "ms");
|
+ FTPCommand.getCommandName(ftpReq.isCommand()) + " in " + duration + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for an active transaction, and commit it
|
// Commit, or rollback, any active user transaction
|
||||||
|
|
||||||
if ( hasUserTransaction())
|
try
|
||||||
{
|
{
|
||||||
try
|
// Commit or rollback the transaction
|
||||||
{
|
|
||||||
// Commit the transaction
|
|
||||||
|
|
||||||
UserTransaction trans = getUserTransaction();
|
endTransaction();
|
||||||
trans.commit();
|
}
|
||||||
}
|
catch ( Exception ex)
|
||||||
catch ( Exception ex)
|
{
|
||||||
{
|
// Debug
|
||||||
// Debug
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
if ( logger.isDebugEnabled())
|
logger.debug("Error committing transaction", ex);
|
||||||
logger.debug("Error committing transaction", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end while state
|
} // end while state
|
||||||
|
@@ -18,6 +18,8 @@ package org.alfresco.filesys.server;
|
|||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
import javax.transaction.Status;
|
||||||
|
import javax.transaction.SystemException;
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
@@ -479,9 +481,27 @@ public abstract class SrvSession
|
|||||||
boolean created = false;
|
boolean created = false;
|
||||||
|
|
||||||
// If there is an active transaction check that it is the required type
|
// If there is an active transaction check that it is the required type
|
||||||
|
|
||||||
if ( m_transaction != null)
|
if ( m_transaction != null)
|
||||||
{
|
{
|
||||||
|
// Check if the current transaction is marked for rollback
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( m_transaction.getStatus() == Status.STATUS_MARKED_ROLLBACK ||
|
||||||
|
m_transaction.getStatus() == Status.STATUS_ROLLEDBACK ||
|
||||||
|
m_transaction.getStatus() == Status.STATUS_ROLLING_BACK)
|
||||||
|
{
|
||||||
|
// Rollback the current transaction
|
||||||
|
|
||||||
|
m_transaction.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( SystemException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the transaction is a write transaction, if write has been requested
|
// Check if the transaction is a write transaction, if write has been requested
|
||||||
|
|
||||||
if ( readOnly == false && m_readOnlyTrans == true)
|
if ( readOnly == false && m_readOnlyTrans == true)
|
||||||
@@ -530,6 +550,48 @@ public abstract class SrvSession
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End a transaction by either committing or rolling back
|
||||||
|
*
|
||||||
|
* @exception AlfrescoRuntimeException
|
||||||
|
*/
|
||||||
|
public final void endTransaction()
|
||||||
|
throws AlfrescoRuntimeException
|
||||||
|
{
|
||||||
|
// Check if there is an active transaction
|
||||||
|
|
||||||
|
if ( m_transaction != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Commit or rollback the transaction
|
||||||
|
|
||||||
|
if ( m_transaction.getStatus() == Status.STATUS_MARKED_ROLLBACK)
|
||||||
|
{
|
||||||
|
// Transaction is marked for rollback
|
||||||
|
|
||||||
|
m_transaction.rollback();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Commit the transaction
|
||||||
|
|
||||||
|
m_transaction.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Exception ex)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to end transaction", ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Clear the current transaction
|
||||||
|
|
||||||
|
m_transaction = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Determine if the session has an active transaction
|
* Determine if the session has an active transaction
|
||||||
*
|
*
|
||||||
|
@@ -21,6 +21,8 @@ import java.util.Random;
|
|||||||
|
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.Authentication;
|
||||||
|
|
||||||
import org.alfresco.config.ConfigElement;
|
import org.alfresco.config.ConfigElement;
|
||||||
import org.alfresco.filesys.server.SrvSession;
|
import org.alfresco.filesys.server.SrvSession;
|
||||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||||
@@ -139,7 +141,10 @@ public class AlfrescoAuthenticator extends SrvAuthenticator
|
|||||||
{
|
{
|
||||||
// Use the existing authentication token
|
// Use the existing authentication token
|
||||||
|
|
||||||
m_authComponent.setCurrentUser(client.getUserName());
|
if ( client.isGuest())
|
||||||
|
m_authComponent.setGuestUserAsCurrentUser();
|
||||||
|
else
|
||||||
|
m_authComponent.setCurrentUser(client.getUserName());
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
|
||||||
@@ -151,11 +156,36 @@ public class AlfrescoAuthenticator extends SrvAuthenticator
|
|||||||
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
|
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if MD4 or passthru mode is configured
|
// Check if this is a guest logon
|
||||||
|
|
||||||
int authSts = AUTH_DISALLOW;
|
int authSts = AUTH_DISALLOW;
|
||||||
|
|
||||||
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
if ( client.isGuest())
|
||||||
|
{
|
||||||
|
// Check if guest logons are allowed
|
||||||
|
|
||||||
|
if ( allowGuest() == false)
|
||||||
|
return AUTH_DISALLOW;
|
||||||
|
|
||||||
|
// Get a guest authentication token
|
||||||
|
|
||||||
|
m_authComponent.setGuestUserAsCurrentUser();
|
||||||
|
Authentication authToken = m_authComponent.getCurrentAuthentication();
|
||||||
|
|
||||||
|
client.setAuthenticationToken( authToken);
|
||||||
|
|
||||||
|
// Set the home folder for the guest user
|
||||||
|
|
||||||
|
getHomeFolderForUser( client);
|
||||||
|
|
||||||
|
// Indicate logged on as guest
|
||||||
|
|
||||||
|
authSts = AUTH_GUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if MD4 or passthru mode is configured
|
||||||
|
|
||||||
|
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||||
{
|
{
|
||||||
// Perform local MD4 password check
|
// Perform local MD4 password check
|
||||||
|
|
||||||
|
@@ -129,6 +129,24 @@ public class ClientInfo
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the password as a character array
|
||||||
|
*
|
||||||
|
* @return char[]
|
||||||
|
*/
|
||||||
|
public final char[] getPasswordAsCharArray()
|
||||||
|
{
|
||||||
|
char[] cpwd = null;
|
||||||
|
|
||||||
|
if (m_password != null)
|
||||||
|
{
|
||||||
|
String pwd = new String(m_password);
|
||||||
|
cpwd = new char[pwd.length()];
|
||||||
|
pwd.getChars(0, pwd.length(), cpwd, 0);
|
||||||
|
}
|
||||||
|
return cpwd;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the client has specified an ANSI password
|
* Determine if the client has specified an ANSI password
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user