mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Big honkin' merge from head. Sheesh!
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3617 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -91,7 +91,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
if ( client.isGuest())
|
||||
m_authComponent.setGuestUserAsCurrentUser();
|
||||
else
|
||||
m_authComponent.setCurrentUser(client.getUserName());
|
||||
m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName()));
|
||||
|
||||
// Debug
|
||||
|
||||
@@ -229,7 +229,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
|
||||
// Set the current user to be authenticated, save the authentication token
|
||||
|
||||
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName()));
|
||||
client.setAuthenticationToken( m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName())));
|
||||
|
||||
// Get the users home folder node, if available
|
||||
|
||||
|
@@ -890,4 +890,50 @@ public abstract class CifsAuthenticator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the case insensitive logon name to the internal person object user name
|
||||
*
|
||||
* @param userName String
|
||||
* @return String
|
||||
*/
|
||||
protected final String mapUserNameToPerson(String userName)
|
||||
{
|
||||
// Get the home folder for the user
|
||||
|
||||
UserTransaction tx = m_transactionService.getUserTransaction();
|
||||
String personName = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx.begin();
|
||||
personName = m_personService.getUserIdentifier( userName);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the person name
|
||||
|
||||
return personName;
|
||||
}
|
||||
}
|
@@ -1106,7 +1106,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( krbDetails.getUserName());
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson(krbDetails.getUserName()));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
@@ -1236,7 +1236,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( userName);
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson(userName));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
@@ -1368,7 +1368,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( client.getUserName());
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
@@ -1479,7 +1479,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( userName);
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson( userName));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
@@ -1602,7 +1602,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( client.getUserName());
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
@@ -1765,7 +1765,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
|
||||
|
||||
// Setup the Acegi authenticated user
|
||||
|
||||
m_authComponent.setCurrentUser( userName);
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson( userName));
|
||||
|
||||
// Store the full user name in the client information, indicate that this is not a guest logon
|
||||
|
||||
|
@@ -20,6 +20,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
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;
|
||||
@@ -182,26 +183,22 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a challenge key
|
||||
* Return an authentication context for the new session
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @return byte[]
|
||||
* @return AuthContext
|
||||
*/
|
||||
public byte[] getChallengeKey(SrvSession sess)
|
||||
public AuthContext getAuthContext( SMBSrvSession sess)
|
||||
{
|
||||
// In MD4 mode we generate the challenge locally
|
||||
|
||||
byte[] key = null;
|
||||
|
||||
// Check if the client is already authenticated, and it is not a null logon
|
||||
|
||||
|
||||
AuthContext authCtx = null;
|
||||
|
||||
if ( sess.hasAuthenticationContext() && sess.hasAuthenticationToken() &&
|
||||
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
|
||||
{
|
||||
// Return the previous challenge, user is already authenticated
|
||||
|
||||
NTLanManAuthContext authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
|
||||
key = authCtx.getChallenge();
|
||||
authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
|
||||
|
||||
// DEBUG
|
||||
|
||||
@@ -210,11 +207,10 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
}
|
||||
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
{
|
||||
// Generate a new challenge key, pack the key and return
|
||||
|
||||
key = new byte[8];
|
||||
|
||||
DataPacker.putIntelLong(m_random.nextLong(), key, 0);
|
||||
// Create a new authentication context for the session
|
||||
|
||||
authCtx = new NTLanManAuthContext();
|
||||
sess.setAuthenticationContext( authCtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -233,14 +229,17 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
|
||||
// Get the challenge from the token
|
||||
|
||||
if ( authToken.getChallenge() != null)
|
||||
key = authToken.getChallenge().getBytes();
|
||||
{
|
||||
authCtx = new NTLanManAuthContext( authToken.getChallenge().getBytes());
|
||||
sess.setAuthenticationContext( authCtx);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the challenge
|
||||
// Return the authentication context
|
||||
|
||||
return key;
|
||||
return authCtx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform MD4 user authentication
|
||||
*
|
||||
|
@@ -125,7 +125,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
{
|
||||
// Use the existing authentication token
|
||||
|
||||
m_authComponent.setCurrentUser(client.getUserName());
|
||||
m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName()));
|
||||
|
||||
// Debug
|
||||
|
||||
@@ -220,42 +220,28 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
|
||||
// Map the passthru username to an Alfresco person
|
||||
|
||||
String username = client.getUserName();
|
||||
NodeRef userNode = m_personService.getPerson( username);
|
||||
String personName = m_personService.getUserIdentifier( username);
|
||||
|
||||
if ( userNode != null)
|
||||
if ( personName != 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);
|
||||
// Use the person name as the current user
|
||||
|
||||
m_authComponent.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 = CifsAuthenticator.AUTH_ALLOW;
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set using the user name, lowercase the name if the person service is case insensitive
|
||||
|
||||
if ( m_personService.getUserNamesAreCaseSensitive() == false)
|
||||
username = username.toLowerCase();
|
||||
m_authComponent.setCurrentUser( username);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Setting current user using username " + username);
|
||||
}
|
||||
|
||||
// Allow the user full access to the server
|
||||
|
||||
authSts = CifsAuthenticator.AUTH_ALLOW;
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Passthru authenticate user=" + client.getUserName() + ", FULL");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -19,7 +19,9 @@ package org.alfresco.filesys.server.config;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
@@ -62,11 +64,15 @@ import org.alfresco.filesys.server.core.ShareType;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.server.core.SharedDeviceList;
|
||||
import org.alfresco.filesys.server.filesys.DefaultShareMapper;
|
||||
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
||||
import org.alfresco.filesys.server.filesys.DiskInterface;
|
||||
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
|
||||
import org.alfresco.filesys.server.filesys.HomeShareMapper;
|
||||
import org.alfresco.filesys.smb.ServerType;
|
||||
import org.alfresco.filesys.smb.TcpipSMB;
|
||||
import org.alfresco.filesys.smb.server.repo.ContentContext;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopActionException;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopActionTable;
|
||||
import org.alfresco.filesys.util.IPAddress;
|
||||
import org.alfresco.filesys.util.X64;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
@@ -182,6 +188,16 @@ public class ServerConfiguration implements ApplicationListener
|
||||
|
||||
private String m_broadcast;
|
||||
|
||||
// NetBIOS ports
|
||||
|
||||
private int m_nbNamePort = RFCNetBIOSProtocol.NAME_PORT;
|
||||
private int m_nbSessPort = RFCNetBIOSProtocol.PORT;
|
||||
private int m_nbDatagramPort = RFCNetBIOSProtocol.DATAGRAM;
|
||||
|
||||
// Native SMB port
|
||||
|
||||
private int m_tcpSMBPort = TcpipSMB.PORT;
|
||||
|
||||
// Announce the server to network neighborhood, announcement interval in
|
||||
// minutes
|
||||
|
||||
@@ -586,7 +602,7 @@ public class ServerConfiguration implements ApplicationListener
|
||||
m_platform = PlatformType.LINUX;
|
||||
else if (osName.startsWith("Mac OS X"))
|
||||
m_platform = PlatformType.MACOSX;
|
||||
else if (osName.startsWith("Solaris"))
|
||||
else if (osName.startsWith("Solaris") || osName.startsWith("SunOS"))
|
||||
m_platform = PlatformType.SOLARIS;
|
||||
}
|
||||
|
||||
@@ -800,103 +816,198 @@ public class ServerConfiguration implements ApplicationListener
|
||||
platformOK = true;
|
||||
}
|
||||
|
||||
// Check if the broadcast mask has been specified
|
||||
|
||||
if (getBroadcastMask() == null)
|
||||
throw new AlfrescoRuntimeException("Network broadcast mask not specified");
|
||||
|
||||
// Enable the NetBIOS SMB support, if enabled for this platform
|
||||
|
||||
setNetBIOSSMB(platformOK);
|
||||
|
||||
// Check for a bind address
|
||||
|
||||
String bindto = elem.getAttribute("bindto");
|
||||
if (bindto != null && bindto.length() > 0)
|
||||
// Parse/check NetBIOS settings, if enabled
|
||||
|
||||
if ( hasNetBIOSSMB())
|
||||
{
|
||||
|
||||
// Validate the bind address
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Check the bind address
|
||||
|
||||
InetAddress bindAddr = InetAddress.getByName(bindto);
|
||||
|
||||
// Set the bind address for the NetBIOS name server
|
||||
|
||||
setNetBIOSBindAddress(bindAddr);
|
||||
}
|
||||
catch (UnknownHostException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid NetBIOS bind address");
|
||||
}
|
||||
}
|
||||
else if (hasSMBBindAddress())
|
||||
{
|
||||
|
||||
// Use the SMB bind address for the NetBIOS name server
|
||||
|
||||
setNetBIOSBindAddress(getSMBBindAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get a list of all the local addresses
|
||||
|
||||
InetAddress[] addrs = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Get the local server IP address list
|
||||
|
||||
addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
|
||||
}
|
||||
catch (UnknownHostException ex)
|
||||
{
|
||||
logger.error("Failed to get local address list", ex);
|
||||
}
|
||||
|
||||
// Check the address list for one or more valid local addresses filtering out the loopback address
|
||||
|
||||
int addrCnt = 0;
|
||||
|
||||
if ( addrs != null)
|
||||
{
|
||||
for (int i = 0; i < addrs.length; i++)
|
||||
{
|
||||
|
||||
// Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses
|
||||
|
||||
if (addrs[i].getHostAddress().equals("127.0.0.1") == false
|
||||
&& addrs[i].getHostAddress().equals("0.0.0.0") == false)
|
||||
addrCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any addresses were found
|
||||
|
||||
if ( addrCnt == 0)
|
||||
{
|
||||
// Log the available IP addresses
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Local address list dump :-");
|
||||
if ( addrs != null)
|
||||
{
|
||||
for ( int i = 0; i < addrs.length; i++)
|
||||
logger.debug( " Address: " + addrs[i]);
|
||||
}
|
||||
else
|
||||
logger.debug(" No addresses");
|
||||
}
|
||||
|
||||
// Throw an exception to stop the CIFS/NetBIOS name server from starting
|
||||
|
||||
throw new AlfrescoRuntimeException( "Failed to get IP address(es) for the local server, check hosts file and/or DNS setup");
|
||||
}
|
||||
|
||||
// Check if the broadcast mask has been specified
|
||||
|
||||
if (getBroadcastMask() == null)
|
||||
throw new AlfrescoRuntimeException("Network broadcast mask not specified");
|
||||
|
||||
// Check for a bind address
|
||||
|
||||
String bindto = elem.getAttribute("bindto");
|
||||
if (bindto != null && bindto.length() > 0)
|
||||
{
|
||||
|
||||
// Validate the bind address
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Check the bind address
|
||||
|
||||
InetAddress bindAddr = InetAddress.getByName(bindto);
|
||||
|
||||
// Set the bind address for the NetBIOS name server
|
||||
|
||||
setNetBIOSBindAddress(bindAddr);
|
||||
}
|
||||
catch (UnknownHostException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Invalid NetBIOS bind address");
|
||||
}
|
||||
}
|
||||
else if (hasSMBBindAddress())
|
||||
{
|
||||
|
||||
// Use the SMB bind address for the NetBIOS name server
|
||||
|
||||
setNetBIOSBindAddress(getSMBBindAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get a list of all the local addresses
|
||||
|
||||
InetAddress[] addrs = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Get the local server IP address list
|
||||
|
||||
addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
|
||||
}
|
||||
catch (UnknownHostException ex)
|
||||
{
|
||||
logger.error("Failed to get local address list", ex);
|
||||
}
|
||||
|
||||
// Check the address list for one or more valid local addresses filtering out the loopback address
|
||||
|
||||
int addrCnt = 0;
|
||||
|
||||
if ( addrs != null)
|
||||
{
|
||||
for (int i = 0; i < addrs.length; i++)
|
||||
{
|
||||
|
||||
// Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses
|
||||
|
||||
if (addrs[i].getHostAddress().equals("127.0.0.1") == false
|
||||
&& addrs[i].getHostAddress().equals("0.0.0.0") == false)
|
||||
addrCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any addresses were found
|
||||
|
||||
if ( addrCnt == 0)
|
||||
{
|
||||
// Enumerate the network adapter list
|
||||
|
||||
Enumeration<NetworkInterface> niEnum = null;
|
||||
|
||||
try
|
||||
{
|
||||
niEnum = NetworkInterface.getNetworkInterfaces();
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
}
|
||||
|
||||
if ( niEnum != null)
|
||||
{
|
||||
while ( niEnum.hasMoreElements())
|
||||
{
|
||||
// Get the current network interface
|
||||
|
||||
NetworkInterface ni = niEnum.nextElement();
|
||||
|
||||
// Enumerate the addresses for the network adapter
|
||||
|
||||
Enumeration<InetAddress> niAddrs = ni.getInetAddresses();
|
||||
if ( niAddrs != null)
|
||||
{
|
||||
// Check for any valid addresses
|
||||
|
||||
while ( niAddrs.hasMoreElements())
|
||||
{
|
||||
InetAddress curAddr = niAddrs.nextElement();
|
||||
|
||||
if ( curAddr.getHostAddress().equals("127.0.0.1") == false &&
|
||||
curAddr.getHostAddress().equals("0.0.0.0") == false)
|
||||
addrCnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( addrCnt > 0 && logger.isDebugEnabled())
|
||||
logger.debug("Found valid IP address from interface list");
|
||||
}
|
||||
|
||||
// Check if we found any valid network addresses
|
||||
|
||||
if ( addrCnt == 0)
|
||||
{
|
||||
// Log the available IP addresses
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Local address list dump :-");
|
||||
if ( addrs != null)
|
||||
{
|
||||
for ( int i = 0; i < addrs.length; i++)
|
||||
logger.debug( " Address: " + addrs[i]);
|
||||
}
|
||||
else
|
||||
logger.debug(" No addresses");
|
||||
}
|
||||
|
||||
// Throw an exception to stop the CIFS/NetBIOS name server from starting
|
||||
|
||||
throw new AlfrescoRuntimeException( "Failed to get IP address(es) for the local server, check hosts file and/or DNS setup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the session port has been specified
|
||||
|
||||
String portNum = elem.getAttribute("sessionPort");
|
||||
if ( portNum != null && portNum.length() > 0) {
|
||||
try {
|
||||
setNetBIOSSessionPort(Integer.parseInt(portNum));
|
||||
if ( getNetBIOSSessionPort() <= 0 || getNetBIOSSessionPort() >= 65535)
|
||||
throw new AlfrescoRuntimeException("NetBIOS session port out of valid range");
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new AlfrescoRuntimeException("Invalid NetBIOS session port");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the name port has been specified
|
||||
|
||||
portNum = elem.getAttribute("namePort");
|
||||
if ( portNum != null && portNum.length() > 0) {
|
||||
try {
|
||||
setNetBIOSNamePort(Integer.parseInt(portNum));
|
||||
if ( getNetBIOSNamePort() <= 0 || getNetBIOSNamePort() >= 65535)
|
||||
throw new AlfrescoRuntimeException("NetBIOS name port out of valid range");
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new AlfrescoRuntimeException("Invalid NetBIOS name port");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the datagram port has been specified
|
||||
|
||||
portNum = elem.getAttribute("datagramPort");
|
||||
if ( portNum != null && portNum.length() > 0) {
|
||||
try {
|
||||
setNetBIOSDatagramPort(Integer.parseInt(portNum));
|
||||
if ( getNetBIOSDatagramPort() <= 0 || getNetBIOSDatagramPort() >= 65535)
|
||||
throw new AlfrescoRuntimeException("NetBIOS datagram port out of valid range");
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new AlfrescoRuntimeException("Invalid NetBIOS datagram port");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -937,6 +1048,20 @@ public class ServerConfiguration implements ApplicationListener
|
||||
// Enable the TCP/IP SMB support, if enabled for this platform
|
||||
|
||||
setTcpipSMB(platformOK);
|
||||
|
||||
// Check if the port has been specified
|
||||
|
||||
String portNum = elem.getAttribute("port");
|
||||
if ( portNum != null && portNum.length() > 0) {
|
||||
try {
|
||||
setTcpipSMBPort(Integer.parseInt(portNum));
|
||||
if ( getTcpipSMBPort() <= 0 || getTcpipSMBPort() >= 65535)
|
||||
throw new AlfrescoRuntimeException("TCP/IP SMB port out of valid range");
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new AlfrescoRuntimeException("Invalid TCP/IP SMB port");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1460,7 +1585,7 @@ public class ServerConfiguration implements ApplicationListener
|
||||
}
|
||||
}
|
||||
|
||||
// Get the top level filesystems confgiruation element
|
||||
// Get the top level filesystems configuration element
|
||||
|
||||
ConfigElement filesystems = config.getConfigElement("filesystems");
|
||||
|
||||
@@ -1511,8 +1636,9 @@ public class ServerConfiguration implements ApplicationListener
|
||||
{
|
||||
// Create a new filesystem driver instance and create a context for
|
||||
// the new filesystem
|
||||
|
||||
DiskInterface filesysDriver = this.diskInterface;
|
||||
DiskDeviceContext filesysContext = (DiskDeviceContext) filesysDriver.createContext(elem);
|
||||
ContentContext filesysContext = (ContentContext) filesysDriver.createContext(elem);
|
||||
|
||||
// Check if an access control list has been specified
|
||||
|
||||
@@ -1542,6 +1668,18 @@ public class ServerConfiguration implements ApplicationListener
|
||||
|
||||
DiskSharedDevice filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext);
|
||||
|
||||
// Attach desktop actions to the filesystem
|
||||
|
||||
ConfigElement deskActionsElem = elem.getChild("desktopActions");
|
||||
if ( deskActionsElem != null)
|
||||
{
|
||||
// Get the desktop actions list
|
||||
|
||||
DesktopActionTable desktopActions = processDesktopActions(deskActionsElem, filesys);
|
||||
if ( desktopActions != null)
|
||||
filesysContext.setDesktopActions( desktopActions, filesysDriver);
|
||||
}
|
||||
|
||||
// Add any access controls to the share
|
||||
|
||||
filesys.setAccessControlList(acls);
|
||||
@@ -1682,6 +1820,8 @@ public class ServerConfiguration implements ApplicationListener
|
||||
setAuthenticator(auth, authElem, allowGuest);
|
||||
auth.setMapToGuest( mapGuest);
|
||||
}
|
||||
else
|
||||
throw new AlfrescoRuntimeException("Authenticator not specified");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1775,6 +1915,99 @@ public class ServerConfiguration implements ApplicationListener
|
||||
return acls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a desktop actions sub-section and return the desktop action table
|
||||
*
|
||||
* @param deskActionElem ConfigElement
|
||||
* @param fileSys DiskSharedDevice
|
||||
*/
|
||||
private final DesktopActionTable processDesktopActions(ConfigElement deskActionElem, DiskSharedDevice fileSys)
|
||||
{
|
||||
// Get the desktop action configuration elements
|
||||
|
||||
DesktopActionTable desktopActions = null;
|
||||
List<ConfigElement> actionElems = deskActionElem.getChildren();
|
||||
|
||||
if ( actionElems != null)
|
||||
{
|
||||
// Check for the global configuration section
|
||||
|
||||
ConfigElement globalConfig = deskActionElem.getChild("global");
|
||||
|
||||
// Allocate the actions table
|
||||
|
||||
desktopActions = new DesktopActionTable();
|
||||
|
||||
// Process the desktop actions list
|
||||
|
||||
for ( ConfigElement actionElem : actionElems)
|
||||
{
|
||||
if ( actionElem.getName().equals("action"))
|
||||
{
|
||||
// Get the desktop action class name or bean id
|
||||
|
||||
ConfigElement className = actionElem.getChild("class");
|
||||
if ( className != null)
|
||||
{
|
||||
// Load the desktop action class, create a new instance
|
||||
|
||||
Object actionObj = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Create a new desktop action instance
|
||||
|
||||
actionObj = Class.forName(className.getValue()).newInstance();
|
||||
|
||||
// Make sure the object is a desktop action
|
||||
|
||||
if ( actionObj instanceof DesktopAction)
|
||||
{
|
||||
// Initialize the desktop action
|
||||
|
||||
DesktopAction deskAction = (DesktopAction) actionObj;
|
||||
deskAction.initializeAction(globalConfig, actionElem, fileSys);
|
||||
|
||||
// Add the action to the list of desktop actions
|
||||
|
||||
desktopActions.addAction(deskAction);
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Added desktop action " + deskAction.getName());
|
||||
}
|
||||
else
|
||||
throw new AlfrescoRuntimeException("Desktop action does not extend DesktopAction class, " + className.getValue());
|
||||
}
|
||||
catch ( ClassNotFoundException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Desktop action class not found, " + className.getValue());
|
||||
}
|
||||
catch (IllegalAccessException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex);
|
||||
}
|
||||
catch ( InstantiationException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex);
|
||||
}
|
||||
catch (DesktopActionException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to initialize desktop action", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( actionElem.getName().equals("global") == false)
|
||||
throw new AlfrescoRuntimeException("Invalid configuration element in desktopActions section, " + actionElem.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Return the desktop actions list
|
||||
|
||||
return desktopActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the platforms attribute returning the set of platform ids
|
||||
*
|
||||
@@ -2013,6 +2246,36 @@ public class ServerConfiguration implements ApplicationListener
|
||||
return m_nbBindAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the NetBIOS name server port
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getNetBIOSNamePort()
|
||||
{
|
||||
return m_nbNamePort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the NetBIOS session port
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getNetBIOSSessionPort()
|
||||
{
|
||||
return m_nbSessPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the NetBIOS datagram port
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getNetBIOSDatagramPort()
|
||||
{
|
||||
return m_nbDatagramPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the network broadcast mask to be used for broadcast datagrams.
|
||||
*
|
||||
@@ -2154,6 +2417,16 @@ public class ServerConfiguration implements ApplicationListener
|
||||
return m_win32NBUseWinsock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the native SMB port
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getTcpipSMBPort()
|
||||
{
|
||||
return m_tcpSMBPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the timezone name
|
||||
*
|
||||
@@ -2716,6 +2989,36 @@ public class ServerConfiguration implements ApplicationListener
|
||||
m_netBIOSEnable = ena;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NetBIOS name server port
|
||||
*
|
||||
* @param port int
|
||||
*/
|
||||
public final void setNetBIOSNamePort(int port)
|
||||
{
|
||||
m_nbNamePort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NetBIOS session port
|
||||
*
|
||||
* @param port int
|
||||
*/
|
||||
public final void setNetBIOSSessionPort(int port)
|
||||
{
|
||||
m_nbSessPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NetBIOS datagram port
|
||||
*
|
||||
* @param port int
|
||||
*/
|
||||
public final void setNetBIOSDatagramPort(int port)
|
||||
{
|
||||
m_nbDatagramPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable the TCP/IP SMB support
|
||||
*
|
||||
@@ -2726,6 +3029,16 @@ public class ServerConfiguration implements ApplicationListener
|
||||
m_tcpSMBEnable = ena;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the TCP/IP SMB port
|
||||
*
|
||||
* @param port int
|
||||
*/
|
||||
public final void setTcpipSMBPort( int port)
|
||||
{
|
||||
m_tcpSMBPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable the Win32 NetBIOS SMB support
|
||||
*
|
||||
|
@@ -1,589 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.smb.repo;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
|
||||
import org.alfresco.filesys.server.filesys.FileName;
|
||||
import org.alfresco.filesys.server.filesys.IOControlNotImplementedException;
|
||||
import org.alfresco.filesys.server.filesys.NetworkFile;
|
||||
import org.alfresco.filesys.server.filesys.NotifyChange;
|
||||
import org.alfresco.filesys.server.filesys.TreeConnection;
|
||||
import org.alfresco.filesys.smb.NTIOCtl;
|
||||
import org.alfresco.filesys.smb.SMBException;
|
||||
import org.alfresco.filesys.smb.SMBStatus;
|
||||
import org.alfresco.filesys.smb.server.repo.CifsHelper;
|
||||
import org.alfresco.filesys.smb.server.repo.ContentDiskDriver;
|
||||
import org.alfresco.filesys.smb.server.repo.IOControlHandler;
|
||||
import org.alfresco.filesys.util.DataBuffer;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.LockType;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Content Disk Driver I/O Control Handler Class
|
||||
*
|
||||
* <p>Provides the custom I/O control code handling used by the CIFS client interface application.
|
||||
*
|
||||
* @author gkspencer
|
||||
*/
|
||||
public class ContentIOControlHandler implements IOControlHandler
|
||||
{
|
||||
// Logging
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ContentIOControlHandler.class);
|
||||
|
||||
// Services and helpers
|
||||
|
||||
private CifsHelper cifsHelper;
|
||||
private TransactionService transactionService;
|
||||
private NodeService nodeService;
|
||||
private CheckOutCheckInService checkInOutService;
|
||||
|
||||
private ContentDiskDriver contentDriver;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public ContentIOControlHandler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initalize the I/O control handler
|
||||
*
|
||||
* @param contentDriver ContentDiskDriver
|
||||
* @param cifsHelper CifsHelper
|
||||
* @param transService TransactionService
|
||||
* @param nodeService NodeService
|
||||
* @param cociService CheckOutCheckInService
|
||||
*/
|
||||
public void initialize( ContentDiskDriver contentDriver, CifsHelper cifsHelper,
|
||||
TransactionService transService, NodeService nodeService, CheckOutCheckInService cociService)
|
||||
{
|
||||
this.contentDriver = contentDriver;
|
||||
this.cifsHelper = cifsHelper;
|
||||
this.transactionService = transService;
|
||||
this.nodeService = nodeService;
|
||||
this.checkInOutService = cociService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a filesystem I/O control request
|
||||
*
|
||||
* @param sess Server session
|
||||
* @param tree Tree connection.
|
||||
* @param ctrlCode I/O control code
|
||||
* @param fid File id
|
||||
* @param dataBuf I/O control specific input data
|
||||
* @param isFSCtrl true if this is a filesystem control, or false for a device control
|
||||
* @param filter if bit0 is set indicates that the control applies to the share root handle
|
||||
* @return DataBuffer
|
||||
* @exception IOControlNotImplementedException
|
||||
* @exception SMBException
|
||||
*/
|
||||
public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf,
|
||||
boolean isFSCtrl, int filter)
|
||||
throws IOControlNotImplementedException, SMBException
|
||||
{
|
||||
// Validate the file id
|
||||
|
||||
NetworkFile netFile = tree.findFile(fid);
|
||||
if ( netFile == null || netFile.isDirectory() == false)
|
||||
throw new SMBException(SMBStatus.NTErr, SMBStatus.NTInvalidParameter);
|
||||
|
||||
// Split the control code
|
||||
|
||||
int devType = NTIOCtl.getDeviceType(ctrlCode);
|
||||
int ioFunc = NTIOCtl.getFunctionCode(ctrlCode);
|
||||
|
||||
if ( devType != NTIOCtl.DeviceFileSystem || dataBuf == null)
|
||||
throw new IOControlNotImplementedException();
|
||||
|
||||
// Check if the request has a valid signature for an Alfresco CIFS server I/O control
|
||||
|
||||
if ( dataBuf.getLength() < IOControl.Signature.length())
|
||||
throw new IOControlNotImplementedException("Bad request length");
|
||||
|
||||
String sig = dataBuf.getString(IOControl.Signature.length(), false);
|
||||
|
||||
if ( sig == null || sig.compareTo(IOControl.Signature) != 0)
|
||||
throw new IOControlNotImplementedException("Bad request signature");
|
||||
|
||||
// Get the node for the parent folder, make sure it is a folder
|
||||
|
||||
NodeRef folderNode = null;
|
||||
|
||||
try
|
||||
{
|
||||
folderNode = contentDriver.getNodeForPath(tree, netFile.getFullName());
|
||||
|
||||
if ( cifsHelper.isDirectory( folderNode) == false)
|
||||
folderNode = null;
|
||||
}
|
||||
catch ( FileNotFoundException ex)
|
||||
{
|
||||
folderNode = null;
|
||||
}
|
||||
|
||||
// If the folder node is not valid return an error
|
||||
|
||||
if ( folderNode == null)
|
||||
throw new SMBException(SMBStatus.NTErr, SMBStatus.NTAccessDenied);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isInfoEnabled()) {
|
||||
logger.info("IO control func=0x" + Integer.toHexString(ioFunc) + ", fid=" + fid + ", buffer=" + dataBuf);
|
||||
logger.info(" Folder nodeRef=" + folderNode);
|
||||
}
|
||||
|
||||
// Check if the I/O control code is one of our custom codes
|
||||
|
||||
DataBuffer retBuffer = null;
|
||||
|
||||
switch ( ioFunc)
|
||||
{
|
||||
// Probe to check if this is an Alfresco CIFS server
|
||||
|
||||
case IOControl.CmdProbe:
|
||||
|
||||
// Return a buffer with the signature
|
||||
|
||||
retBuffer = new DataBuffer(IOControl.Signature.length());
|
||||
retBuffer.putFixedString(IOControl.Signature, IOControl.Signature.length());
|
||||
retBuffer.putInt(IOControl.StsSuccess);
|
||||
break;
|
||||
|
||||
// Get file information for a file within the current folder
|
||||
|
||||
case IOControl.CmdFileStatus:
|
||||
|
||||
// Process the file status request
|
||||
|
||||
retBuffer = procIOFileStatus( sess, tree, dataBuf, folderNode);
|
||||
break;
|
||||
|
||||
// Check-in file request
|
||||
|
||||
case IOControl.CmdCheckIn:
|
||||
|
||||
// Process the check-in request
|
||||
|
||||
retBuffer = procIOCheckIn( sess, tree, dataBuf, folderNode, netFile);
|
||||
break;
|
||||
|
||||
// Check-out file request
|
||||
|
||||
case IOControl.CmdCheckOut:
|
||||
|
||||
// Process the check-out request
|
||||
|
||||
retBuffer = procIOCheckOut( sess, tree, dataBuf, folderNode, netFile);
|
||||
break;
|
||||
|
||||
// Unknown I/O control code
|
||||
|
||||
default:
|
||||
throw new IOControlNotImplementedException();
|
||||
}
|
||||
|
||||
// Return the reply buffer, may be null
|
||||
|
||||
return retBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the file status I/O request
|
||||
*
|
||||
* @param sess Server session
|
||||
* @param tree Tree connection
|
||||
* @param reqBuf Request buffer
|
||||
* @param folderNode NodeRef of parent folder
|
||||
* @return DataBuffer
|
||||
*/
|
||||
private final DataBuffer procIOFileStatus( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode)
|
||||
{
|
||||
// Start a transaction
|
||||
|
||||
sess.beginTransaction( transactionService, true);
|
||||
|
||||
// Get the file name from the request
|
||||
|
||||
String fName = reqBuf.getString( true);
|
||||
logger.info(" File status, fname=" + fName);
|
||||
|
||||
// Create a response buffer
|
||||
|
||||
DataBuffer respBuf = new DataBuffer(256);
|
||||
respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length());
|
||||
|
||||
// Get the node for the file/folder
|
||||
|
||||
NodeRef childNode = null;
|
||||
|
||||
try
|
||||
{
|
||||
childNode = cifsHelper.getNodeRef( folderNode, fName);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Check if the file/folder was found
|
||||
|
||||
if ( childNode == null)
|
||||
{
|
||||
// Return an error response
|
||||
|
||||
respBuf.putInt(IOControl.StsFileNotFound);
|
||||
return respBuf;
|
||||
}
|
||||
|
||||
// Check if this is a file or folder node
|
||||
|
||||
if ( cifsHelper.isDirectory( childNode))
|
||||
{
|
||||
// Only return the status and node type for folders
|
||||
|
||||
respBuf.putInt(IOControl.StsSuccess);
|
||||
respBuf.putInt(IOControl.TypeFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Indicate that this is a file node
|
||||
|
||||
respBuf.putInt(IOControl.StsSuccess);
|
||||
respBuf.putInt(IOControl.TypeFile);
|
||||
|
||||
// Check if this file is a working copy
|
||||
|
||||
if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
// Indicate that this is a working copy
|
||||
|
||||
respBuf.putInt(IOControl.True);
|
||||
|
||||
// Get the owner username and file it was copied from
|
||||
|
||||
String owner = (String) nodeService.getProperty( childNode, ContentModel.PROP_WORKING_COPY_OWNER);
|
||||
String copiedFrom = null;
|
||||
|
||||
if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_COPIEDFROM))
|
||||
{
|
||||
// Get the path of the file the working copy was generated from
|
||||
|
||||
NodeRef fromNode = (NodeRef) nodeService.getProperty( childNode, ContentModel.PROP_COPY_REFERENCE);
|
||||
if ( fromNode != null)
|
||||
copiedFrom = (String) nodeService.getProperty( fromNode, ContentModel.PROP_NAME);
|
||||
}
|
||||
|
||||
// Pack the owner and copied from values
|
||||
|
||||
respBuf.putString(owner != null ? owner : "", true, true);
|
||||
respBuf.putString(copiedFrom != null ? copiedFrom : "", true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a working copy
|
||||
|
||||
respBuf.putInt(IOControl.False);
|
||||
}
|
||||
|
||||
// Check the lock status of the file
|
||||
|
||||
if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
// Get the lock type and owner
|
||||
|
||||
String lockTypeStr = (String) nodeService.getProperty( childNode, ContentModel.PROP_LOCK_TYPE);
|
||||
String lockOwner = null;
|
||||
|
||||
if ( lockTypeStr != null)
|
||||
lockOwner = (String) nodeService.getProperty( childNode, ContentModel.PROP_LOCK_OWNER);
|
||||
|
||||
// Pack the lock type, and owner if there is a lock on the file
|
||||
|
||||
if ( lockTypeStr == null)
|
||||
respBuf.putInt(IOControl.LockNone);
|
||||
else
|
||||
{
|
||||
LockType lockType = LockType.valueOf( lockTypeStr);
|
||||
|
||||
respBuf.putInt(lockType == LockType.READ_ONLY_LOCK ? IOControl.LockRead : IOControl.LockWrite);
|
||||
respBuf.putString(lockOwner != null ? lockOwner : "", true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// File is not lockable
|
||||
|
||||
respBuf.putInt(IOControl.LockNone);
|
||||
}
|
||||
|
||||
// Get the content data details for the file
|
||||
|
||||
ContentData contentData = (ContentData) nodeService.getProperty( childNode, ContentModel.PROP_CONTENT);
|
||||
|
||||
if ( contentData != null)
|
||||
{
|
||||
// Get the content mime-type
|
||||
|
||||
String mimeType = contentData.getMimetype();
|
||||
|
||||
// Pack the content length and mime-type
|
||||
|
||||
respBuf.putInt( IOControl.True);
|
||||
respBuf.putLong( contentData.getSize());
|
||||
respBuf.putString( mimeType != null ? mimeType : "", true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// File does not have any content
|
||||
|
||||
respBuf.putInt( IOControl.False);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the response
|
||||
|
||||
return respBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the check in I/O request
|
||||
*
|
||||
* @param sess Server session
|
||||
* @param tree Tree connection
|
||||
* @param reqBuf Request buffer
|
||||
* @param folderNode NodeRef of parent folder
|
||||
* @param netFile NetworkFile for the folder
|
||||
* @return DataBuffer
|
||||
*/
|
||||
private final DataBuffer procIOCheckIn( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode,
|
||||
NetworkFile netFile)
|
||||
{
|
||||
// Start a transaction
|
||||
|
||||
sess.beginTransaction( transactionService, false);
|
||||
|
||||
// Get the file name from the request
|
||||
|
||||
String fName = reqBuf.getString( true);
|
||||
boolean keepCheckedOut = reqBuf.getInt() == IOControl.True ? true : false;
|
||||
|
||||
logger.info(" CheckIn, fname=" + fName + ", keepCheckedOut=" + keepCheckedOut);
|
||||
|
||||
// Create a response buffer
|
||||
|
||||
DataBuffer respBuf = new DataBuffer(256);
|
||||
respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length());
|
||||
|
||||
// Get the node for the file/folder
|
||||
|
||||
NodeRef childNode = null;
|
||||
|
||||
try
|
||||
{
|
||||
childNode = cifsHelper.getNodeRef( folderNode, fName);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Check if the file/folder was found
|
||||
|
||||
if ( childNode == null)
|
||||
{
|
||||
// Return an error response
|
||||
|
||||
respBuf.putInt(IOControl.StsFileNotFound);
|
||||
return respBuf;
|
||||
}
|
||||
|
||||
// Check if this is a file or folder node
|
||||
|
||||
if ( cifsHelper.isDirectory( childNode))
|
||||
{
|
||||
// Return an error status, attempt to check in a folder
|
||||
|
||||
respBuf.putInt(IOControl.StsBadParameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if this file is a working copy
|
||||
|
||||
if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check in the file
|
||||
|
||||
checkInOutService.checkin( childNode, null, null, keepCheckedOut);
|
||||
|
||||
// Check in was successful
|
||||
|
||||
respBuf.putInt( IOControl.StsSuccess);
|
||||
|
||||
// Check if there are any file/directory change notify requests active
|
||||
|
||||
DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext();
|
||||
if (diskCtx.hasChangeHandler()) {
|
||||
|
||||
// Build the relative path to the checked in file
|
||||
|
||||
String fileName = FileName.buildPath( netFile.getFullName(), null, fName, FileName.DOS_SEPERATOR);
|
||||
|
||||
// Queue a file deleted change notification
|
||||
|
||||
diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, fileName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Return an error status and message
|
||||
|
||||
respBuf.setPosition( IOControl.Signature.length());
|
||||
respBuf.putInt(IOControl.StsError);
|
||||
respBuf.putString( ex.getMessage(), true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a working copy
|
||||
|
||||
respBuf.putInt(IOControl.StsNotWorkingCopy);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the response
|
||||
|
||||
return respBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the check out I/O request
|
||||
*
|
||||
* @param sess Server session
|
||||
* @param tree Tree connection
|
||||
* @param reqBuf Request buffer
|
||||
* @param folderNode NodeRef of parent folder
|
||||
* @param netFile NetworkFile for the folder
|
||||
* @return DataBuffer
|
||||
*/
|
||||
private final DataBuffer procIOCheckOut( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode,
|
||||
NetworkFile netFile)
|
||||
{
|
||||
// Start a transaction
|
||||
|
||||
sess.beginTransaction( transactionService, false);
|
||||
|
||||
// Get the file name from the request
|
||||
|
||||
String fName = reqBuf.getString( true);
|
||||
|
||||
logger.info(" CheckOut, fname=" + fName);
|
||||
|
||||
// Create a response buffer
|
||||
|
||||
DataBuffer respBuf = new DataBuffer(256);
|
||||
respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length());
|
||||
|
||||
// Get the node for the file/folder
|
||||
|
||||
NodeRef childNode = null;
|
||||
|
||||
try
|
||||
{
|
||||
childNode = cifsHelper.getNodeRef( folderNode, fName);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Check if the file/folder was found
|
||||
|
||||
if ( childNode == null)
|
||||
{
|
||||
// Return an error response
|
||||
|
||||
respBuf.putInt(IOControl.StsFileNotFound);
|
||||
return respBuf;
|
||||
}
|
||||
|
||||
// Check if this is a file or folder node
|
||||
|
||||
if ( cifsHelper.isDirectory( childNode))
|
||||
{
|
||||
// Return an error status, attempt to check in a folder
|
||||
|
||||
respBuf.putInt(IOControl.StsBadParameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check out the file
|
||||
|
||||
NodeRef workingCopyNode = checkInOutService.checkout( childNode);
|
||||
|
||||
// Get the working copy file name
|
||||
|
||||
String workingCopyName = (String) nodeService.getProperty( workingCopyNode, ContentModel.PROP_NAME);
|
||||
|
||||
// Check out was successful, pack the working copy name
|
||||
|
||||
respBuf.putInt( IOControl.StsSuccess);
|
||||
respBuf.putString( workingCopyName, true, true);
|
||||
|
||||
// Check if there are any file/directory change notify requests active
|
||||
|
||||
DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext();
|
||||
if (diskCtx.hasChangeHandler()) {
|
||||
|
||||
// Build the relative path to the checked in file
|
||||
|
||||
String fileName = FileName.buildPath( netFile.getFullName(), null, workingCopyName, FileName.DOS_SEPERATOR);
|
||||
|
||||
// Queue a file added change notification
|
||||
|
||||
diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Return an error status and message
|
||||
|
||||
respBuf.setPosition( IOControl.Signature.length());
|
||||
respBuf.putInt(IOControl.StsError);
|
||||
respBuf.putString( ex.getMessage(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the response
|
||||
|
||||
return respBuf;
|
||||
}
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2006 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.smb.repo;
|
||||
|
||||
import org.alfresco.filesys.smb.NTIOCtl;
|
||||
|
||||
/**
|
||||
* Content Disk Driver I/O Control Codes Class
|
||||
*
|
||||
* <p>contains I/O control codes and status codes used by the content disk driver I/O control
|
||||
* implementation.
|
||||
*
|
||||
* @author gkspencer
|
||||
*/
|
||||
public class IOControl
|
||||
{
|
||||
// Custom I/O control codes
|
||||
|
||||
public static final int CmdProbe = NTIOCtl.FsCtlCustom;
|
||||
public static final int CmdFileStatus = NTIOCtl.FsCtlCustom + 1;
|
||||
public static final int CmdCheckOut = NTIOCtl.FsCtlCustom + 2;
|
||||
public static final int CmdCheckIn = NTIOCtl.FsCtlCustom + 3;
|
||||
|
||||
// I/O control request/response signature
|
||||
|
||||
public static final String Signature = "ALFRESCO";
|
||||
|
||||
// I/O control status codes
|
||||
|
||||
public static final int StsSuccess = 0;
|
||||
|
||||
public static final int StsError = 1;
|
||||
public static final int StsFileNotFound = 2;
|
||||
public static final int StsAccessDenied = 3;
|
||||
public static final int StsBadParameter = 4;
|
||||
public static final int StsNotWorkingCopy = 5;
|
||||
|
||||
// Boolean field values
|
||||
|
||||
public static final int True = 1;
|
||||
public static final int False = 0;
|
||||
|
||||
// File status field values
|
||||
//
|
||||
// Node type
|
||||
|
||||
public static final int TypeFile = 0;
|
||||
public static final int TypeFolder = 1;
|
||||
|
||||
// Lock status
|
||||
|
||||
public static final int LockNone = 0;
|
||||
public static final int LockRead = 1;
|
||||
public static final int LockWrite = 2;
|
||||
}
|
Reference in New Issue
Block a user