Replaced the file server code with the Alfresco JLAN project.

Restructured the file server code packages.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@7757 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gary Spencer
2008-01-06 16:44:00 +00:00
parent 0a7fef92aa
commit 6478d72321
396 changed files with 6336 additions and 118542 deletions

View File

@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="source/java"/>
<classpathentry kind="src" path="config"/>
<classpathentry kind="src" path="source/test-resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="/Core"/>
<classpathentry kind="src" path="/3rd Party"/>
<classpathentry combineaccessrules="false" kind="src" path="/MBean"/>
<classpathentry combineaccessrules="false" kind="src" path="/Deployment"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="source/java"/>
<classpathentry kind="src" path="config"/>
<classpathentry kind="src" path="source/test-resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="/Core"/>
<classpathentry kind="src" path="/3rd Party"/>
<classpathentry combineaccessrules="false" kind="src" path="/MBean"/>
<classpathentry combineaccessrules="false" kind="src" path="/Deployment"/>
<classpathentry combineaccessrules="false" kind="src" path="/Alfresco JLAN"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>

View File

@@ -1,28 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Repository</name>
<comment>JavaCC Nature</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/JibX.launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>rk.eclipse.javacc.javaccnature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Repository</name>
<comment>JavaCC Nature</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>rk.eclipse.javacc.javaccnature</nature>
</natures>
</projectDescription>

View File

@@ -399,13 +399,13 @@
<!-- CIFS Server -->
<bean id="fileServerConfiguration" class="org.alfresco.filesys.server.config.ServerConfiguration" parent="fileServerConfigurationBase">
<bean id="fileServerConfiguration" class="org.alfresco.filesys.ServerConfigurationBean" parent="fileServerConfigurationBase">
<property name="configService">
<ref bean="fileServersConfigService"/>
</property>
</bean>
<bean id="cifsServer" class="org.alfresco.filesys.CIFSServer" destroy-method="stopServer">
<bean id="cifsServer" class="org.alfresco.filesys.CIFSServerBean" destroy-method="stopServer">
<constructor-arg>
<ref local="fileServerConfiguration"/>
</constructor-arg>
@@ -413,7 +413,7 @@
<!-- FTP Server -->
<bean id="ftpServer" class="org.alfresco.filesys.FTPServer" destroy-method="stopServer">
<bean id="ftpServer" class="org.alfresco.filesys.FTPServerBean" destroy-method="stopServer">
<constructor-arg>
<ref local="fileServerConfiguration"/>
</constructor-arg>
@@ -421,7 +421,7 @@
<!-- NFS Server -->
<bean id="nfsServer" class="org.alfresco.filesys.NFSServer" destroy-method="stopServer">
<bean id="nfsServer" class="org.alfresco.filesys.NFSServerBean" destroy-method="stopServer">
<constructor-arg>
<ref local="fileServerConfiguration"/>
</constructor-arg>

View File

@@ -115,7 +115,7 @@
</bean>
<bean id="FileServerConfig"
class="org.alfresco.filesys.server.config.FileServerConfig">
class="org.alfresco.filesys.FileServerConfig">
<property name="fileServerConfiguration"><ref bean="fileServerConfiguration"/></property>
</bean>

View File

@@ -25,6 +25,10 @@
<Win32NetBIOS/>
<Win32Announce interval="5"/>
<!-- CIFS authentication -->
<authenticator type="enterprise">
</authenticator>
<!--
<WINS>
<primary>1.2.3.4</primary>
@@ -36,6 +40,15 @@
<config evaluator="string-compare" condition="FTP Server">
<serverEnable enabled="true"/>
<!-- Run on a non-privileged port -->
<!--
<port>1121</port>
-->
<!-- FTP authentication -->
<authenticator type="alfresco"/>
<!-- <debug flags="File,Search,Error,Directory,Info,DataPort"/> -->
</config>
@@ -133,27 +146,25 @@
</config>
<config evaluator="string-compare" condition="Filesystem Security">
<authenticator type="enterprise">
</authenticator>
<!-- Domain mappings used for passthri authentication routing -->
<!--
<DomainMappings>
<Domain name="ALFRESCO" subnet="192.168.1.0" mask="192.168.1.255"/>
</DomainMappings>
-->
<!-- Custom share mapper when multi-tenancy is enabled -->
<!--
<shareMapper type="multi-tenant">
<debug/>
</shareMapper>
-->
<!--
<globalAccessControl default="None">
<user name="admin" access="Write"/>
<address ip="90.1.0.90" access="Write"/>
</globalAccessControl>
<users>
<localuser name="user">
<password>user</password>
<comment>Normal user account</comment>
</localuser>
<localuser name="administrator">
<password>admin</password>
<administrator/>
<comment>Administrator account</comment>
</localuser>
</users>
-->
</config>

View File

@@ -58,7 +58,7 @@
</bean>
<!-- Filesystem Interface -->
<bean id="contentDiskDriver" class="org.alfresco.filesys.smb.server.repo.ContentDiskDriver" >
<bean id="contentDiskDriver" class="org.alfresco.filesys.repo.ContentDiskDriver" >
<constructor-arg>
<ref bean="cifsHelper" />
</constructor-arg>
@@ -76,7 +76,7 @@
<property name="stateReaper"><ref bean="fileStateReaper"/></property>
</bean>
<bean id="cifsHelper" class="org.alfresco.filesys.smb.server.repo.CifsHelper">
<bean id="cifsHelper" class="org.alfresco.filesys.repo.CifsHelper">
<property name="dictionaryService"><ref bean="dictionaryService" /></property>
<property name="nodeService"><ref bean="NodeService" /></property>
<property name="fileFolderService"><ref bean="FileFolderService" /></property>
@@ -103,7 +103,7 @@
</bean>
<!-- File State Reaper -->
<bean id="fileStateReaper" class="org.alfresco.filesys.server.state.FileStateReaper"
<bean id="fileStateReaper" class="org.alfresco.filesys.state.FileStateReaper"
destroy-method="shutdownRequest"/>
</beans>

View File

@@ -0,0 +1,197 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys;
import org.alfresco.jlan.server.config.ConfigSection;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService;
/**
* Alfresco Configuration Section Class
*
* @author gkspencer
*/
public class AlfrescoConfigSection extends ConfigSection {
// Alfresco configuration section name
public static final String SectionName = "Alfresco";
// Disk interface to use for shared filesystems
private DiskInterface m_repoDiskInterface;
// AVM filesystem interface
private DiskInterface m_avmDiskInterface;
// Main authentication service, public API
private AuthenticationService m_authenticationService;
// Authentication component, for internal functions
private AuthenticationComponent m_authenticationComponent;
// Various services
private NodeService m_nodeService;
private PersonService m_personService;
private TransactionService m_transactionService;
private TenantService m_tenantService;
private SearchService m_searchService;
private NamespaceService m_namespaceService;
/**
* Class constructor
*
* @param config ServerConfigurationBean
*/
public AlfrescoConfigSection(ServerConfigurationBean config) {
super( SectionName, config);
// Copy values from the server configuration bean
m_repoDiskInterface = config.getRepoDiskInterface();
m_avmDiskInterface = config.getAvmDiskInterface();
m_authenticationService = config.getAuthenticationService();
m_authenticationComponent = config.getAuthenticationComponent();
m_nodeService = config.getNodeService();
m_personService = config.getPersonService();
m_transactionService = config.getTransactionService();
m_tenantService = config.getTenantService();
m_searchService = config.getSearchService();
m_namespaceService = config.getNamespaceService();
}
/**
* Return the repository disk interface to be used to create shares
*
* @return DiskInterface
*/
public final DiskInterface getRepoDiskInterface()
{
return m_repoDiskInterface;
}
/**
* Return the disk interface to be used to create AVM filesystem shares
*
* @return DiskInterface
*/
public final DiskInterface getAvmDiskInterface()
{
return m_avmDiskInterface;
}
/**
* Return the authentication service
*
* @return AuthenticationService
*/
public final AuthenticationService getAuthenticationService()
{
return m_authenticationService;
}
/**
* Return the authentication component
*
* @return AuthenticationComponent
*/
public final AuthenticationComponent getAuthenticationComponent()
{
return m_authenticationComponent;
}
/**
* Return the node service
*
* @return NodeService
*/
public final NodeService getNodeService()
{
return m_nodeService;
}
/**
* Return the person service
*
* @return PersonService
*/
public final PersonService getPersonService()
{
return m_personService;
}
/**
* Return the transaction service
*
* @return TransactionService
*/
public final TransactionService getTransactionService()
{
return m_transactionService;
}
/**
* Return the tenant service
*
* @return TenantService
*/
public final TenantService getTenantService()
{
return m_tenantService;
}
/**
* Return the search service
*
* @return SearchService
*/
public final SearchService getSearchService()
{
return m_searchService;
}
/**
* Return the namespace service
*
* @return NamespaceService
*/
public final NamespaceService getNamespaceService()
{
return m_namespaceService;
}
}

View File

@@ -29,11 +29,12 @@ import java.io.PrintStream;
import java.net.SocketException;
import java.util.Vector;
import org.alfresco.jlan.netbios.server.NetBIOSNameServer;
import org.alfresco.jlan.server.NetworkServer;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.smb.server.CIFSConfigSection;
import org.alfresco.jlan.smb.server.SMBServer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.netbios.server.NetBIOSNameServer;
import org.alfresco.filesys.server.NetworkServer;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.smb.server.SMBServer;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -48,14 +49,15 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author GKSpencer
*/
public class CIFSServer extends AbstractLifecycleBean
public class CIFSServerBean extends AbstractLifecycleBean
{
private static final Log logger = LogFactory.getLog("org.alfresco.smb.server");
// Server configuration
// Server configuration and sections
private ServerConfiguration m_filesysConfig;
private CIFSConfigSection m_cifsConfig;
private ServerConfiguration filesysConfig;
// List of CIFS server components
private Vector<NetworkServer> serverList = new Vector<NetworkServer>();
@@ -65,9 +67,9 @@ public class CIFSServer extends AbstractLifecycleBean
*
* @param serverConfig ServerConfiguration
*/
public CIFSServer(ServerConfiguration serverConfig)
public CIFSServerBean(ServerConfiguration serverConfig)
{
this.filesysConfig = serverConfig;
m_filesysConfig = serverConfig;
}
/**
@@ -77,7 +79,7 @@ public class CIFSServer extends AbstractLifecycleBean
*/
public final ServerConfiguration getConfiguration()
{
return filesysConfig;
return m_filesysConfig;
}
/**
@@ -85,7 +87,7 @@ public class CIFSServer extends AbstractLifecycleBean
*/
public boolean isStarted()
{
return (filesysConfig != null && filesysConfig.isSMBServerEnabled());
return (m_filesysConfig != null && m_filesysConfig.isServerRunning( "CIFS"));
}
/**
@@ -100,22 +102,24 @@ public class CIFSServer extends AbstractLifecycleBean
{
// Create the SMB server and NetBIOS name server, if enabled
if (filesysConfig.isSMBServerEnabled())
m_cifsConfig = (CIFSConfigSection) m_filesysConfig.getConfigSection(CIFSConfigSection.SectionName);
if (m_cifsConfig != null)
{
// Create the NetBIOS name server if NetBIOS SMB is enabled
if (filesysConfig.hasNetBIOSSMB())
serverList.add(new NetBIOSNameServer(filesysConfig));
if (m_cifsConfig.hasNetBIOSSMB())
serverList.add(new NetBIOSNameServer(m_filesysConfig));
// Create the SMB server
serverList.add(new SMBServer(filesysConfig));
serverList.add(new SMBServer(m_filesysConfig));
// Add the servers to the configuration
for (NetworkServer server : serverList)
{
filesysConfig.addServer(server);
m_filesysConfig.addServer(server);
}
}
@@ -134,7 +138,7 @@ public class CIFSServer extends AbstractLifecycleBean
}
catch (Throwable e)
{
filesysConfig = null;
m_filesysConfig = null;
throw new AlfrescoRuntimeException("Failed to start CIFS Server", e);
}
// success
@@ -145,7 +149,7 @@ public class CIFSServer extends AbstractLifecycleBean
*/
public final void stopServer()
{
if (filesysConfig == null)
if (m_filesysConfig == null)
{
// initialisation failed
return;
@@ -170,7 +174,7 @@ public class CIFSServer extends AbstractLifecycleBean
// Clear the server list and configuration
serverList.clear();
filesysConfig = null;
m_filesysConfig = null;
}
/**
@@ -193,7 +197,7 @@ public class CIFSServer extends AbstractLifecycleBean
// Get the CIFS server bean
CIFSServer server = (CIFSServer) ctx.getBean("cifsServer");
CIFSServerBean server = (CIFSServerBean) ctx.getBean("cifsServer");
if (server == null)
{
throw new AlfrescoRuntimeException("Server bean 'cifsServer' not defined");
@@ -201,23 +205,19 @@ public class CIFSServer extends AbstractLifecycleBean
// Stop the FTP server, if running
server.getConfiguration().setFTPServerEnabled(false);
NetworkServer srv = server.getConfiguration().findServer("FTP");
if ( srv != null)
srv.shutdownServer(true);
// Stop the NFS server, if running
server.getConfiguration().setNFSServerEnabled(false);
srv = server.getConfiguration().findServer("NFS");
if ( srv != null)
srv.shutdownServer(true);
// Only wait for shutdown if the SMB/CIFS server is enabled
if ( server.getConfiguration().isSMBServerEnabled())
if ( server.getConfiguration().hasConfigSection(CIFSConfigSection.SectionName))
{
// SMB/CIFS server should have automatically started

View File

@@ -28,16 +28,16 @@ import java.io.IOException;
import java.io.PrintStream;
import java.net.SocketException;
import org.alfresco.jlan.ftp.FTPConfigSection;
import org.alfresco.jlan.ftp.FTPServer;
import org.alfresco.jlan.server.NetworkServer;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.ftp.FTPNetworkServer;
import org.alfresco.filesys.server.NetworkServer;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
@@ -47,26 +47,27 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author GKSpencer
*/
public class FTPServer extends AbstractLifecycleBean
public class FTPServerBean extends AbstractLifecycleBean
{
private static final Log logger = LogFactory.getLog("org.alfresco.ftp.server");
// Server configuration
// Server configuration and sections
private ServerConfiguration filesysConfig;
private FTPConfigSection m_ftpConfig;
// The actual FTP server
private FTPNetworkServer ftpServer;
private FTPServer ftpServer;
/**
* Class constructor
*
* @param serverConfig ServerConfiguration
*/
public FTPServer(ServerConfiguration serverConfig)
public FTPServerBean(ServerConfiguration serverConfig)
{
this.filesysConfig = serverConfig;
filesysConfig = serverConfig;
}
/**
@@ -84,7 +85,7 @@ public class FTPServer extends AbstractLifecycleBean
*/
public boolean isStarted()
{
return (filesysConfig != null && filesysConfig.isFTPServerEnabled());
return (filesysConfig != null && filesysConfig.isServerRunning("FTP"));
}
/**
@@ -99,11 +100,13 @@ public class FTPServer extends AbstractLifecycleBean
{
// Create the FTP server, if enabled
if (filesysConfig.isFTPServerEnabled())
m_ftpConfig = (FTPConfigSection) filesysConfig.getConfigSection( FTPConfigSection.SectionName);
if (m_ftpConfig != null)
{
// Create the FTP server
ftpServer = new FTPNetworkServer(filesysConfig);
ftpServer = new FTPServer(filesysConfig);
filesysConfig.addServer(ftpServer);
}
@@ -179,7 +182,7 @@ public class FTPServer extends AbstractLifecycleBean
// Get the FTP server bean
FTPServer server = (FTPServer) ctx.getBean("ftpServer");
FTPServerBean server = (FTPServerBean) ctx.getBean("ftpServer");
if (server == null)
{
throw new AlfrescoRuntimeException("Server bean 'ftpServer' not defined");
@@ -197,7 +200,7 @@ public class FTPServer extends AbstractLifecycleBean
// Only wait for shutdown if the FTP server is enabled
if ( server.getConfiguration().isFTPServerEnabled())
if ( server.getConfiguration().hasConfigSection(FTPConfigSection.SectionName))
{
// FTP server should have automatically started

View File

@@ -20,18 +20,20 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.server.config;
package org.alfresco.filesys;
import java.net.InetAddress;
import org.alfresco.filesys.smb.TcpipSMB;
import org.alfresco.filesys.util.CifsMounter;
import org.alfresco.filesys.util.Platform;
import org.alfresco.jlan.ftp.FTPConfigSection;
import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.smb.TcpipSMB;
import org.alfresco.jlan.smb.server.CIFSConfigSection;
import org.alfresco.jlan.util.Platform;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sun.star.io.UnknownHostException;
/**
* File Server Configuration MBean Class
*
@@ -84,7 +86,7 @@ public class FileServerConfig implements FileServerConfigMBean {
*/
public boolean isCIFSServerEnabled()
{
return m_serverConfig.isSMBServerEnabled();
return m_serverConfig.hasConfigSection(CIFSConfigSection.SectionName);
}
/**
@@ -94,7 +96,7 @@ public class FileServerConfig implements FileServerConfigMBean {
*/
public boolean isFTPServerEnabled()
{
return m_serverConfig.isFTPServerEnabled();
return m_serverConfig.hasConfigSection(FTPConfigSection.SectionName);
}
/**
@@ -104,7 +106,7 @@ public class FileServerConfig implements FileServerConfigMBean {
*/
public boolean isNFSServerEnabled()
{
return m_serverConfig.isNFSServerEnabled();
return m_serverConfig.hasConfigSection(NFSConfigSection.SectionName);
}
/**
@@ -139,6 +141,10 @@ public class FileServerConfig implements FileServerConfigMBean {
if ( isCIFSServerEnabled() == false)
return null;
// Access the CIFS configuration
CIFSConfigSection cifsConfig = (CIFSConfigSection) m_serverConfig.getConfigSection(CIFSConfigSection.SectionName);
// Create the CIFS mounter
CifsMounter cifsMounter = new CifsMounter();
@@ -146,11 +152,11 @@ public class FileServerConfig implements FileServerConfigMBean {
// Set the server address if the global bind address has been set
if ( m_serverConfig.hasSMBBindAddress())
if ( cifsConfig.hasSMBBindAddress())
{
// Use the global CIFS server bind address
cifsMounter.setServerAddress( m_serverConfig.getSMBBindAddress().getHostAddress());
cifsMounter.setServerAddress( cifsConfig.getSMBBindAddress().getHostAddress());
}
// Get the local platform type
@@ -159,7 +165,7 @@ public class FileServerConfig implements FileServerConfigMBean {
// Figure out which CIFS sub-protocol to use to connect to the server
if ( platform == Platform.Type.LINUX && m_serverConfig.hasTcpipSMB())
if ( platform == Platform.Type.LINUX && cifsConfig.hasTcpipSMB())
{
// Connect using native SMB, this defaults to port 445 but may be running on a different port
@@ -167,16 +173,16 @@ public class FileServerConfig implements FileServerConfigMBean {
// Check if the native SMB server is listening on a non-standard port
if ( m_serverConfig.getTcpipSMBPort() != TcpipSMB.PORT)
cifsMounter.setProtocolPort( m_serverConfig.getTcpipSMBPort());
if ( cifsConfig.getTcpipSMBPort() != TcpipSMB.PORT)
cifsMounter.setProtocolPort( cifsConfig.getTcpipSMBPort());
}
else
{
// Check if the server is using Win32 NetBIOS
if ( m_serverConfig.hasWin32NetBIOS())
if ( cifsConfig.hasWin32NetBIOS())
cifsMounter.setProtocolType( CifsMounter.Win32NetBIOS);
else if ( m_serverConfig.hasNetBIOSSMB())
else if ( cifsConfig.hasNetBIOSSMB())
{
// Set the protocol type for Java socket based NetBIOS
@@ -184,8 +190,8 @@ public class FileServerConfig implements FileServerConfigMBean {
// Check if the socket NetBIOS is bound to a particular address
if ( m_serverConfig.hasNetBIOSBindAddress())
cifsMounter.setServerAddress( m_serverConfig.getNetBIOSBindAddress().getHostAddress());
if ( cifsConfig.hasNetBIOSBindAddress())
cifsMounter.setServerAddress( cifsConfig.getNetBIOSBindAddress().getHostAddress());
}
}

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.server.config;
package org.alfresco.filesys;
/**
* File Server Configuration MBean Interface

View File

@@ -28,11 +28,13 @@ import java.io.PrintStream;
import java.net.SocketException;
import java.util.Vector;
import org.alfresco.jlan.oncrpc.mount.MountServer;
import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection;
import org.alfresco.jlan.oncrpc.nfs.NFSServer;
import org.alfresco.jlan.oncrpc.portmap.PortMapperServer;
import org.alfresco.jlan.server.NetworkServer;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.NetworkServer;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.oncrpc.mount.MountServer;
import org.alfresco.filesys.server.oncrpc.portmap.PortMapperServer;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -47,15 +49,16 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author GKSpencer
*/
public class NFSServer extends AbstractLifecycleBean
public class NFSServerBean extends AbstractLifecycleBean
{
// Debug logging
private static final Log logger = LogFactory.getLog("org.alfresco.nfs.server");
// Server configuration
// Server configuration and sections
private ServerConfiguration m_filesysConfig;
private NFSConfigSection m_nfsConfig;
// List of NFS server components
@@ -66,7 +69,7 @@ public class NFSServer extends AbstractLifecycleBean
*
* @param serverConfig ServerConfiguration
*/
public NFSServer(ServerConfiguration serverConfig)
public NFSServerBean(ServerConfiguration serverConfig)
{
m_filesysConfig = serverConfig;
}
@@ -88,7 +91,7 @@ public class NFSServer extends AbstractLifecycleBean
*/
public boolean isStarted()
{
return (m_filesysConfig != null && m_filesysConfig.isNFSServerEnabled());
return (m_filesysConfig != null && m_filesysConfig.isServerRunning( "NFS"));
}
/**
@@ -103,17 +106,19 @@ public class NFSServer extends AbstractLifecycleBean
{
// Create the NFS, mount and portmapper servers, if enabled
if (m_filesysConfig.isNFSServerEnabled())
m_nfsConfig = (NFSConfigSection) m_filesysConfig.getConfigSection( NFSConfigSection.SectionName);
if (m_nfsConfig != null)
{
// Create the portmapper server, if enabled
if (m_filesysConfig.hasNFSPortMapper())
if (m_nfsConfig.hasNFSPortMapper())
m_serverList.add(new PortMapperServer(m_filesysConfig));
// Create the mount and main NFS servers
m_serverList.add(new MountServer(m_filesysConfig));
m_serverList.add(new org.alfresco.filesys.server.oncrpc.nfs.NFSServer(m_filesysConfig));
m_serverList.add(new NFSServer(m_filesysConfig));
// Add the servers to the configuration
@@ -198,7 +203,7 @@ public class NFSServer extends AbstractLifecycleBean
// Get the NFS server bean
NFSServer server = (NFSServer) ctx.getBean("nfsServer");
NFSServerBean server = (NFSServerBean) ctx.getBean("nfsServer");
if (server == null)
{
throw new AlfrescoRuntimeException("Server bean 'nfsServer' not defined");
@@ -206,23 +211,19 @@ public class NFSServer extends AbstractLifecycleBean
// Stop the FTP server, if running
server.getConfiguration().setFTPServerEnabled(false);
NetworkServer srv = server.getConfiguration().findServer("FTP");
if ( srv != null)
srv.shutdownServer(true);
// Stop the CIFS server, if running
server.getConfiguration().setSMBServerEnabled(false);
srv = server.getConfiguration().findServer("SMB");
if ( srv != null)
srv.shutdownServer(true);
// Only wait for shutdown if the NFS server is enabled
if ( server.getConfiguration().isNFSServerEnabled())
if ( server.getConfiguration().hasConfigSection( NFSConfigSection.SectionName))
{
// NFS server should have automatically started

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,142 @@
package org.alfresco.filesys.alfresco;
import net.sf.acegisecurity.Authentication;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.service.cmr.repository.NodeRef;
/*
* AlfrescoClientInfo.java
*
* Copyright (c) 2007 Starlasoft. All rights reserved.
*/
/**
* Alfresco Client Information Class
*
* <p>Contains additional fields used by the Alfresco filesystem drivers.
*/
public class AlfrescoClientInfo extends ClientInfo {
// Authentication token
private Authentication m_authToken;
// Authentication ticket, used for web access without having to re-authenticate
private String m_authTicket;
// Home folder node
private NodeRef m_homeNode;
/**
* Default constructor
*/
public AlfrescoClientInfo()
{
super("", null);
}
/**
* Class constructor
*
* @param user User name
* @param pwd Password
*/
public AlfrescoClientInfo(String user, byte[] pwd)
{
super(user, pwd);
}
/**
* Check if the client has an authentication token
*
* @return boolean
*/
public final boolean hasAuthenticationToken()
{
return m_authToken != null ? true : false;
}
/**
* Return the authentication token
*
* @return Authentication
*/
public final Authentication getAuthenticationToken()
{
return m_authToken;
}
/**
* Check if the client has an authentication ticket
*
* @return boolean
*/
public final boolean hasAuthenticationTicket()
{
return m_authTicket != null ? true : false;
}
/**
* Return the authentication ticket
*
* @return String
*/
public final String getAuthenticationTicket()
{
return m_authTicket;
}
/**
* Check if the client has a home folder node
*
* @return boolean
*/
public final boolean hasHomeFolder()
{
return m_homeNode != null ? true : false;
}
/**
* Return the home folder node
*
* @return NodeRef
*/
public final NodeRef getHomeFolder()
{
return m_homeNode;
}
/**
* Set the authentication toekn
*
* @param token Authentication
*/
public final void setAuthenticationToken(Authentication token)
{
m_authToken = token;
}
/**
* Set the authentication ticket
*
* @param ticket String
*/
public final void setAuthenticationTicket(String ticket)
{
m_authTicket = ticket;
}
/**
* Set the home folder node
*
* @param homeNode NodeRef
*/
public final void setHomeFolder(NodeRef homeNode)
{
m_homeNode = homeNode;
}
}

View File

@@ -0,0 +1,40 @@
package org.alfresco.filesys.alfresco;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.ClientInfoFactory;
/*
* AlfrescoClientInfoFactory.java
*
* Copyright (c) 2007 Starlasoft. All rights reserved.
*/
/**
* Alfresco Client Info Factory Class
*/
public class AlfrescoClientInfoFactory implements ClientInfoFactory {
/**
* Class constructor
*/
public AlfrescoClientInfoFactory() {
// Plug the client info factory in
ClientInfo.setFactory( this);
}
/**
* Create the extended client information object
*
* @param user String
* @param password byte[]
* @return ClientInfo
*/
public ClientInfo createInfo(String user, byte[] password) {
// Return an Alfresco extended client information object
return new AlfrescoClientInfo( user, password);
}
}

View File

@@ -26,11 +26,14 @@ package org.alfresco.filesys.alfresco;
import java.util.Enumeration;
import org.alfresco.filesys.server.filesys.*;
import org.alfresco.filesys.server.pseudo.PseudoFileImpl;
import org.alfresco.filesys.server.pseudo.PseudoFileInterface;
import org.alfresco.filesys.server.state.FileStateReaper;
import org.alfresco.filesys.server.state.FileStateTable;
import org.alfresco.jlan.server.filesys.DiskDeviceContext;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileSystem;
import org.alfresco.jlan.server.filesys.SrvDiskInfo;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileInterface;
import org.alfresco.filesys.state.FileStateReaper;
import org.alfresco.filesys.state.FileStateTable;
/**
* Alfresco Filesystem Context Class
@@ -125,7 +128,7 @@ public abstract class AlfrescoContext extends DiskDeviceContext
{
// Remove the state table from the reaper
stateReaper.removeStateTable( getFilesystemName());
stateReaper.removeStateTable( getShareName());
m_stateTable = null;
}
else if ( m_stateTable == null)
@@ -136,7 +139,7 @@ public abstract class AlfrescoContext extends DiskDeviceContext
// Register with the file state reaper
stateReaper.addStateTable( getFilesystemName(), m_stateTable);
stateReaper.addStateTable( getShareName(), m_stateTable);
}
// Save the reaper, for deregistering when the filesystem is closed

View File

@@ -23,16 +23,24 @@
package org.alfresco.filesys.alfresco;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.filesys.IOControlNotImplementedException;
import org.alfresco.filesys.server.filesys.IOCtlInterface;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.alfresco.filesys.server.state.FileStateReaper;
import org.alfresco.filesys.smb.SMBException;
import org.alfresco.filesys.smb.SMBStatus;
import org.alfresco.filesys.util.DataBuffer;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.filesys.IOControlNotImplementedException;
import org.alfresco.jlan.server.filesys.IOCtlInterface;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.TransactionalFilesystemInterface;
import org.alfresco.jlan.server.filesys.TreeConnection;
import org.alfresco.jlan.smb.SMBException;
import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.jlan.util.DataBuffer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.state.FileStateReaper;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Alfresco Disk Driver Base Class
@@ -41,16 +49,24 @@ import org.alfresco.service.ServiceRegistry;
*
* @author gkspencer
*/
public class AlfrescoDiskDriver implements IOCtlInterface {
public class AlfrescoDiskDriver implements IOCtlInterface, TransactionalFilesystemInterface {
// Logging
private static final Log logger = LogFactory.getLog(AlfrescoDiskDriver.class);
// Service registry for desktop actions
private ServiceRegistry serviceRegistry;
private ServiceRegistry m_serviceRegistry;
// File state reaper
private FileStateReaper m_stateReaper;
// Transaction service
private TransactionService m_transactionService;
/**
* Return the service registry
*
@@ -58,7 +74,7 @@ public class AlfrescoDiskDriver implements IOCtlInterface {
*/
public final ServiceRegistry getServiceRegistry()
{
return this.serviceRegistry;
return m_serviceRegistry;
}
/**
@@ -71,6 +87,16 @@ public class AlfrescoDiskDriver implements IOCtlInterface {
return m_stateReaper;
}
/**
* Return the transaction service
*
* @return TransactionService
*/
public final TransactionService getTransactionService()
{
return m_transactionService;
}
/**
* Set the service registry
*
@@ -78,7 +104,7 @@ public class AlfrescoDiskDriver implements IOCtlInterface {
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
m_serviceRegistry = serviceRegistry;
}
/**
@@ -91,6 +117,14 @@ public class AlfrescoDiskDriver implements IOCtlInterface {
m_stateReaper = stateReaper;
}
/**
* @param transactionService the transaction service
*/
public void setTransactionService(TransactionService transactionService)
{
m_transactionService = transactionService;
}
/**
* Process a filesystem I/O control request
*
@@ -123,4 +157,191 @@ public class AlfrescoDiskDriver implements IOCtlInterface {
else
throw new IOControlNotImplementedException();
}
/**
* Begin a read-only transaction
*
* @param sess SrvSession
*/
public void beginReadTransaction(SrvSession sess) {
beginTransaction( sess, true);
}
/**
* Begin a writeable transaction
*
* @param sess SrvSession
*/
public void beginWriteTransaction(SrvSession sess) {
beginTransaction( sess, false);
}
/**
* End an active transaction
*
* @param sess SrvSession
* @param tx ThreadLocal<Object>
*/
public void endTransaction(SrvSession sess, ThreadLocal<Object> tx) {
// Check that the transaction object is valid
if ( tx == null)
return;
// Get the filesystem transaction
FilesysTransaction filesysTx = (FilesysTransaction) tx.get();
// Check if there is an active transaction
if ( filesysTx != null && filesysTx.hasTransaction())
{
// Get the active transaction
UserTransaction ftx = filesysTx.getTransaction();
try
{
// Commit or rollback the transaction
if ( ftx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
ftx.rollback();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("End transaction (rollback)");
}
else
{
// Commit the transaction
ftx.commit();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("End transaction (commit)");
}
}
catch ( Exception ex)
{
throw new AlfrescoRuntimeException("Failed to end transaction", ex);
}
finally
{
// Clear the current transaction
filesysTx.clearTransaction();
}
}
// Clear the active transaction interface, leave the transaction object as we will reuse it
sess.setTransaction( null);
}
/**
* Create and start a transaction, if not already active
*
* @param sess SrvSession
* @param readOnly boolean
* @exception AlfrescoRuntimeException
*/
private final void beginTransaction( SrvSession sess, boolean readOnly)
throws AlfrescoRuntimeException
{
// Initialize the per session thread local that holds the transaction
sess.initializeTransactionObject();
// Get the filesystem transaction
FilesysTransaction filesysTx = (FilesysTransaction) sess.getTransactionObject().get();
if ( filesysTx == null)
{
filesysTx = new FilesysTransaction();
sess.getTransactionObject().set( filesysTx);
}
// If there is an active transaction check that it is the required type
if ( filesysTx.hasTransaction())
{
// Get the active transaction
UserTransaction tx = filesysTx.getTransaction();
// Check if the current transaction is marked for rollback
try
{
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK ||
tx.getStatus() == Status.STATUS_ROLLEDBACK ||
tx.getStatus() == Status.STATUS_ROLLING_BACK)
{
// Rollback the current transaction
tx.rollback();
}
}
catch ( Exception ex)
{
}
// Check if the transaction is a write transaction, if write has been requested
if ( readOnly == false && filesysTx.isReadOnly() == true)
{
// Commit the read-only transaction
try
{
tx.commit();
}
catch ( Exception ex)
{
throw new AlfrescoRuntimeException("Failed to commit read-only transaction, " + ex.getMessage());
}
finally
{
// Clear the active transaction
filesysTx.clearTransaction();
}
}
}
// Create the transaction
if ( filesysTx.hasTransaction() == false)
{
try
{
UserTransaction userTrans = m_transactionService.getUserTransaction(readOnly);
userTrans.begin();
// Store the transaction
filesysTx.setTransaction( userTrans, readOnly);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Created transaction readOnly=" + readOnly);
}
catch (Exception ex)
{
throw new AlfrescoRuntimeException("Failed to create transaction, " + ex.getMessage());
}
}
// Store the transaction callback
sess.setTransaction( this);
}
}

View File

@@ -0,0 +1,52 @@
package org.alfresco.filesys.alfresco;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.filesys.state.FileState;
/*
* AlfrescoNetworkFile.java
*
* Copyright (c) 2007 Starlasoft. All rights reserved.
*/
/**
* Alfresco Network File Class
*
* <p>Adds Alfresco extensions to the network file.
*/
public abstract class AlfrescoNetworkFile extends NetworkFile {
// Associated file state
private FileState m_state;
/**
* Create a network file object with the specified file/directory name.
*
* @param name File name string.
*/
public AlfrescoNetworkFile(String name)
{
super( name);
}
/**
* Return the associated file state
*
* @return FileState
*/
public final FileState getFileState()
{
return m_state;
}
/**
* Set the associated file state
*
* @param state FileState
*/
public final void setFileState( FileState state)
{
m_state = state;
}
}

View File

@@ -19,7 +19,8 @@
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.alfresco;
@@ -29,10 +30,10 @@ import java.net.InetAddress;
import java.net.URL;
import java.net.URLDecoder;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.pseudo.LocalPseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.server.pseudo.LocalPseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.service.ServiceRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -41,7 +42,6 @@ import org.apache.commons.logging.LogFactory;
* Desktop Action Class
*
* @author gkspencer
*
*/
public abstract class DesktopAction {

View File

@@ -25,9 +25,9 @@ package org.alfresco.filesys.alfresco;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.service.cmr.repository.NodeRef;
/**
@@ -43,6 +43,10 @@ public class DesktopParams {
private SrvSession m_session;
// Filesystem driver
private AlfrescoDiskDriver m_driver;
// Folder node that the actions are working in
private NodeRef m_folderNode;
@@ -66,12 +70,14 @@ public class DesktopParams {
* Class constructor
*
* @param sess SrvSession
* @param driver AlfrescoDiskDriver
* @param folderNode NodeRef
* @param folderFile NetworkFile
*/
public DesktopParams(SrvSession sess, NodeRef folderNode, NetworkFile folderFile)
public DesktopParams(SrvSession sess, AlfrescoDiskDriver driver, NodeRef folderNode, NetworkFile folderFile)
{
m_session = sess;
m_driver = driver;
m_folderNode = folderNode;
m_folderFile = folderFile;
}
@@ -104,8 +110,10 @@ public class DesktopParams {
public final String getTicket()
{
ClientInfo cInfo = m_session.getClientInformation();
if ( cInfo != null)
return cInfo.getAuthenticationTicket();
if ( cInfo != null && cInfo instanceof AlfrescoClientInfo) {
AlfrescoClientInfo alfInfo = (AlfrescoClientInfo) cInfo;
return alfInfo.getAuthenticationTicket();
}
return null;
}
@@ -128,6 +136,16 @@ public class DesktopParams {
{
return m_folderFile;
}
/**
* Return the filesystem driver
*
* @return AlfrescoDiskDriver
*/
public final AlfrescoDiskDriver getDriver()
{
return m_driver;
}
/**
* Set the folder network file

View File

@@ -0,0 +1,102 @@
package org.alfresco.filesys.alfresco;
import javax.transaction.UserTransaction;
/*
* FilesysTransaction.java
*
* Copyright (c) 2007 Starlasoft. All rights reserved.
*/
/**
* Filesystem Transaction Class
*
* <p>Holds the details of a transaction used during a batch of filesystem driver requests.
*
* @author gkspencer
*/
public class FilesysTransaction {
// Transaction
private UserTransaction m_transaction;
// Flag to indicate read-only or writeable transaction
private boolean m_readOnly;
/**
* Default constructor
*/
public FilesysTransaction()
{
}
/**
* Check if the transaction is valid
*
* @return boolean
*/
public final boolean hasTransaction()
{
return m_transaction != null ? true : false;
}
/**
* Check if the transaction is read-only
*
* @return boolean
*/
public final boolean isReadOnly()
{
return m_readOnly;
}
/**
* Return the active transaction
*
* @return UserTransaction
*/
public final UserTransaction getTransaction()
{
return m_transaction;
}
/**
* Set the transaction
*
* @param trans UserTransaction
* @param readOnly boolean
*/
public final void setTransaction( UserTransaction trans, boolean readOnly)
{
m_transaction = trans;
m_readOnly = readOnly;
}
/**
* Clear the transaction
*/
public final void clearTransaction()
{
m_transaction = null;
m_readOnly = true;
}
/**
* Return the transaction details as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
str.append( "[");
str.append( m_transaction);
str.append( isReadOnly() ? ",Read" : ",Write");
str.append( "]");
return str.toString();
}
}

View File

@@ -24,7 +24,7 @@
*/
package org.alfresco.filesys.alfresco;
import org.alfresco.filesys.smb.NTIOCtl;
import org.alfresco.jlan.smb.nt.NTIOCtl;
/**
* Content Disk Driver I/O Control Codes Class

View File

@@ -25,7 +25,7 @@
package org.alfresco.filesys.alfresco;
import org.alfresco.filesys.server.filesys.IOCtlInterface;
import org.alfresco.jlan.server.filesys.IOCtlInterface;
/**
* I/O Control Handler Interface

View File

@@ -0,0 +1,450 @@
/*
* 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.alfresco;
import java.util.Enumeration;
import java.util.Hashtable;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.AlfrescoConfigSection;
import org.alfresco.filesys.repo.ContentContext;
import org.alfresco.filesys.repo.ContentDiskDriver;
import org.alfresco.jlan.debug.Debug;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.InvalidUserException;
import org.alfresco.jlan.server.config.ConfigId;
import org.alfresco.jlan.server.config.ConfigurationListener;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.ShareMapper;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.core.SharedDeviceList;
import org.alfresco.jlan.server.filesys.DiskDeviceContext;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection;
import org.alfresco.jlan.server.filesys.SrvDiskInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* Multi Tenant Share Mapper Class
*
* @author gkspencer
*/
public class MultiTenantShareMapper implements ShareMapper, ConfigurationListener {
// Server configuration and configuration sections
private ServerConfiguration m_config;
private FilesystemsConfigSection m_filesysConfig;
private AlfrescoConfigSection m_alfrescoConfig;
// Share name for multi-tenant connections
private String m_tenantShareName;
// Store name and root path from standard content filesystem share
private String m_rootPath;
private String m_storeName;
// Table of tenant share lists indexed by tenant domain
private Hashtable<String, SharedDeviceList> m_tenantShareLists;
// Debug enable flag
private boolean m_debug;
/**
* Default constructor
*/
public MultiTenantShareMapper() {
}
/**
* Initialize the share mapper
*
* @param config ServerConfiguration
* @param params ConfigElement
* @exception InvalidConfigurationException
*/
public void initializeMapper(ServerConfiguration config, ConfigElement params)
throws InvalidConfigurationException {
// Save the server configuration
m_config = config;
// Filesystem configuration will usually be initialized after the security configuration so we need to plug in
// a listener to initialize it later
m_filesysConfig = (FilesystemsConfigSection) m_config.getConfigSection( FilesystemsConfigSection.SectionName);
// Get the Alfresco configuration section
m_alfrescoConfig = (AlfrescoConfigSection) m_config.getConfigSection( AlfrescoConfigSection.SectionName);
if ( m_filesysConfig == null || m_alfrescoConfig == null)
m_config.addListener( this);
// Find the content filesystem details to be used for hte tenant shares
if ( m_filesysConfig != null)
findContentShareDetails();
// Check if a tenant share name has been specified
ConfigElement tenantShareName = params.getChild( "TenantShareName");
if ( tenantShareName != null)
{
// Validate the share name
if ( tenantShareName.getValue() != null && tenantShareName.getValue().length() > 0)
m_tenantShareName = tenantShareName.getValue();
else
throw new InvalidConfigurationException("Invalid tenant share name");
}
// Check if debug is enabled
if ( params.getChild("debug") != null)
m_debug = true;
// Create the tenant share lists table
m_tenantShareLists = new Hashtable<String, SharedDeviceList>();
}
/**
* Check if debug output is enabled
*
* @return boolean
*/
public final boolean hasDebug() {
return m_debug;
}
/**
* Find a share using the name and type for the specified client.
*
* @param host String
* @param name String
* @param typ int
* @param sess SrvSession
* @param create boolean
* @return SharedDevice
* @exception InvalidUserException
*/
public SharedDevice findShare(String host, String name, int typ, SrvSession sess, boolean create)
throws InvalidUserException {
// Check if this is a tenant user
if ( m_alfrescoConfig.getTenantService().isEnabled() && m_alfrescoConfig.getTenantService().isTenantUser())
return findTenantShare(host, name, typ, sess, create);
// Find the required share by name/type. Use a case sensitive search first, if that fails use a case
// insensitive search.
SharedDevice share = m_filesysConfig.getShares().findShare(name, typ, false);
if ( share == null) {
// Try a case insensitive search for the required share
share = m_filesysConfig.getShares().findShare(name, typ, true);
}
// Check if the share is available
if ( share != null && share.getContext() != null && share.getContext().isAvailable() == false)
share = null;
// Return the shared device, or null if no matching device was found
return share;
}
/**
* Delete temporary shares for the specified session
*
* @param sess SrvSession
*/
public void deleteShares(SrvSession sess) {
// Check if the session has any dynamic shares
if ( sess.hasDynamicShares() == false)
return;
// Delete the dynamic shares
SharedDeviceList shares = sess.getDynamicShareList();
Enumeration<SharedDevice> enm = shares.enumerateShares();
while ( enm.hasMoreElements()) {
// Get the current share from the list
SharedDevice shr = enm.nextElement();
// Close the shared device
shr.getContext().CloseContext();
// DEBUG
if ( Debug.EnableInfo && hasDebug())
Debug.println("Deleted dynamic share " + shr);
}
}
/**
* Return the list of available shares.
*
* @param host String
* @param sess SrvSession
* @param allShares boolean
* @return SharedDeviceList
*/
public SharedDeviceList getShareList(String host, SrvSession sess, boolean allShares) {
// Check that the filesystems configuration is valid
if ( m_filesysConfig == null)
return null;
// Check if this is a tenant user
if ( m_alfrescoConfig.getTenantService().isEnabled() && m_alfrescoConfig.getTenantService().isTenantUser())
return getTenantShareList(host, sess, allShares);
// Make a copy of the global share list and add the per session dynamic shares
SharedDeviceList shrList = new SharedDeviceList( m_filesysConfig.getShares());
if ( sess != null && sess.hasDynamicShares()) {
// Add the per session dynamic shares
shrList.addShares(sess.getDynamicShareList());
}
// Remove unavailable shares from the list and return the list
if ( allShares == false)
shrList.removeUnavailableShares();
return shrList;
}
/**
* Close the share mapper, release any resources.
*/
public void closeMapper() {
// Close all the tenant shares
// TODO:
}
/**
* Configuration changed
*
* @param id int
* @param config Serverconfiguration
* @param newVal Object
* @return int
* @throws InvalidConfigurationException
*/
public int configurationChanged(int id, ServerConfiguration config, Object newVal)
throws InvalidConfigurationException {
// Check if the filesystems configuration section has been added
if ( id == ConfigId.ConfigSection) {
// Check if the section added is the filesystems config
if (newVal instanceof FilesystemsConfigSection)
m_filesysConfig = (FilesystemsConfigSection) newVal;
// Or the Alfresco config
else if (newVal instanceof AlfrescoConfigSection)
m_alfrescoConfig = (AlfrescoConfigSection) newVal;
// Return a dummy status
return ConfigurationListener.StsAccepted;
}
// Check if the tenant share template details have been set
if ( m_rootPath == null)
findContentShareDetails();
// Return a dummy status
return ConfigurationListener.StsIgnored;
}
/**
* Find a share for a tenant
*
* @param host String
* @param name String
* @param typ int
* @param sess SrvSession
* @param create boolean
* @return SharedDevice
* @exception InvalidUserException
*/
private final SharedDevice findTenantShare(String host, String name, int typ, SrvSession sess, boolean create)
throws InvalidUserException {
// Get the share list for the tenant
SharedDeviceList shareList = getTenantShareList(host, sess, true);
if ( shareList == null)
return null;
// Search for the required share
return shareList.findShare( name, typ, true);
}
/**
* Return the list of available shares for a particular tenant
*
* @param host String
* @param sess SrvSession
* @param allShares boolean
* @return SharedDeviceList
*/
private final SharedDeviceList getTenantShareList(String host, SrvSession sess, boolean allShares) {
// Get the tenant user domain
String tenantDomain = m_alfrescoConfig.getTenantService().getCurrentUserDomain();
// Get the share list for the current domain
SharedDeviceList shareList = null;
synchronized ( m_tenantShareLists)
{
// Get the tenant specific share list
shareList = m_tenantShareLists.get( tenantDomain);
if ( shareList == null)
{
// Create the tenant specific share list
shareList = new SharedDeviceList();
// Create a tenant specific share for this domain
shareList.addShare( createTenantShare());
// Store the list for use by other members of this domain
m_tenantShareLists.put( tenantDomain, shareList);
}
}
// Return the tenant specific share list
return shareList;
}
/**
* Create a tenant domain specific share
*/
private final DiskSharedDevice createTenantShare()
{
StoreRef storeRef = new StoreRef(m_storeName);
NodeRef rootNodeRef = new NodeRef(storeRef.getProtocol(), storeRef.getIdentifier(), "dummy");
// Root nodeRef is required for storeRef part
rootNodeRef = m_alfrescoConfig.getTenantService().getRootNode(m_alfrescoConfig.getNodeService(), m_alfrescoConfig.getSearchService(),
m_alfrescoConfig.getNamespaceService(), m_rootPath, rootNodeRef);
// Create the disk driver and context
ContentDiskDriver diskDrv = (ContentDiskDriver) m_alfrescoConfig.getRepoDiskInterface();
ContentContext diskCtx = new ContentContext(m_tenantShareName, "", m_rootPath, rootNodeRef);
// Enable file state caching
diskCtx.enableStateTable( true, diskDrv.getStateReaper());
// Initialize the I/O control handler
if ( diskCtx.hasIOHandler())
diskCtx.getIOHandler().initialize( diskDrv, diskCtx);
// 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 user to access the tenant company home directory
return new DiskSharedDevice(m_tenantShareName, diskDrv, diskCtx);
}
/**
* Find the content filesystem driver details used for the tenant shares
*/
private final void findContentShareDetails()
{
// Need the file system configuration to do the lookup
if ( m_filesysConfig == null)
return;
// Get the fixed share list
SharedDeviceList shareList = m_filesysConfig.getShares();
Enumeration<SharedDevice> shareEnum = shareList.enumerateShares();
while ( shareEnum.hasMoreElements())
{
// Get the current shared device
SharedDevice share = shareEnum.nextElement();
if ( share.getContext() instanceof ContentContext)
{
// Found a content filesystem share
ContentContext ctx = (ContentContext) share.getContext();
// Store the share details that are used for the tenant shares
m_rootPath = ctx.getRootPath();
m_storeName = ctx.getStoreName();
if ( m_tenantShareName == null)
m_tenantShareName = ctx.getDeviceName();
}
}
}
}

View File

@@ -22,21 +22,21 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.server.pseudo;
package org.alfresco.filesys.alfresco;
import java.util.Enumeration;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.TreeConnection;
import org.alfresco.jlan.server.filesys.pseudo.MemoryPseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileInterface;
import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.filesys.alfresco.DesktopAction;
import org.alfresco.filesys.alfresco.DesktopActionTable;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.alfresco.filesys.server.pseudo.MemoryPseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFileInterface;
import org.alfresco.filesys.server.state.FileState;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.smb.server.repo.ContentContext;
import org.alfresco.filesys.repo.ContentContext;
import org.alfresco.filesys.state.FileState;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -22,20 +22,24 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.server.auth;
package org.alfresco.filesys.auth.cifs;
import java.security.NoSuchAlgorithmException;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
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;
import org.alfresco.filesys.server.core.SharedDevice;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.util.HexDump;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.AuthContext;
import org.alfresco.jlan.server.auth.CifsAuthenticator;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.NTLanManAuthContext;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.util.HexDump;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
@@ -47,17 +51,17 @@ import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
*
* <p>Note: Switching off encrypted password support will cause later NT4 service pack releases and
* Win2000 to refuse to connect to the server without a registry update on the client.
*
* @author GKSpencer
*
* @author gkspencer
*/
public class AlfrescoAuthenticator extends CifsAuthenticator
public class AlfrescoCifsAuthenticator extends CifsAuthenticatorBase
{
/**
* Default Constructor
*
* <p>Default to user mode security with encrypted password support.
*/
public AlfrescoAuthenticator()
public AlfrescoCifsAuthenticator()
{
}
@@ -70,8 +74,8 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
{
// Make sure the authentication component supports MD4 hashed passwords or passthru mode
if ( m_authComponent.getNTLMMode() != NTLMMode.MD4_PROVIDER &&
m_authComponent.getNTLMMode() != NTLMMode.PASS_THROUGH)
if ( getAuthenticationComponent().getNTLMMode() != NTLMMode.MD4_PROVIDER &&
getAuthenticationComponent().getNTLMMode() != NTLMMode.PASS_THROUGH)
return false;
return true;
}
@@ -85,6 +89,13 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
*/
public int authenticateUser(ClientInfo client, SrvSession sess, int alg)
{
// Check that the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false)
return CifsAuthenticator.AUTH_DISALLOW;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Check if this is an SMB/CIFS null session logon.
//
// The null session will only be allowed to connect to the IPC$ named pipe share.
@@ -101,11 +112,11 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Check if the client is already authenticated, and it is not a null logon
if ( client.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
if ( alfClient.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
{
// Use the existing authentication token
m_authComponent.setCurrentUser(client.getUserName());
getAuthenticationComponent().setCurrentUser(client.getUserName());
// Debug
@@ -120,64 +131,111 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Check if this is a guest logon
int authSts = AUTH_DISALLOW;
UserTransaction tx = null;
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
try
{
// 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;
}
// Check if MD4 or passthru mode is configured
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Perform local MD4 password check
authSts = doMD4UserAuthentication(client, sess, alg);
}
else
{
// Perform passthru authentication password check
authSts = doPassthruUserAuthentication(client, sess, alg);
}
// Check if the logon status indicates a guest logon
if ( authSts == AUTH_GUEST)
{
// Only allow the guest logon if user mapping is enabled
if ( mapUnknownUserToGuest())
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Logon as guest, setup the security context
// 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;
}
// Check if MD4 or passthru mode is configured
else if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Start a transaction
tx = getTransactionService().getUserTransaction( true);
tx.begin();
// Perform local MD4 password check
authSts = doMD4UserAuthentication(client, sess, alg);
}
else
{
// Do not allow the guest logon
// Start a transaction
authSts = AUTH_DISALLOW;
tx = getTransactionService().getUserTransaction( true);
tx.begin();
// Perform passthru authentication password check
authSts = doPassthruUserAuthentication(client, sess, alg);
}
// Check if the logon status indicates a guest logon
if ( authSts == AUTH_GUEST)
{
// Only allow the guest logon if user mapping is enabled
if ( mapUnknownUserToGuest())
{
// Logon as guest, setup the security context
doGuestLogon( client, sess);
}
else
{
// Do not allow the guest logon
authSts = AUTH_DISALLOW;
}
}
}
catch ( Exception ex)
{
if ( logger.isDebugEnabled())
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)
{
}
}
}
@@ -185,7 +243,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + getStatusAsString(authSts) +
" via " + (m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER ? "MD4" : "Passthru"));
" via " + (getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER ? "MD4" : "Passthru"));
// Return the authentication status
@@ -222,19 +280,18 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
AuthContext authCtx = null;
if ( sess.hasAuthenticationContext() && sess.hasAuthenticationToken() &&
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
if ( sess.hasAuthenticationContext() && sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
{
// Return the previous challenge, user is already authenticated
authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
authCtx = sess.getAuthenticationContext();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Re-using existing challenge, already authenticated");
}
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
else if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Create a new authentication context for the session
@@ -249,11 +306,11 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Run the first stage of the passthru authentication to get the challenge
m_authComponent.authenticate( authToken);
getAuthenticationComponent().authenticate( authToken);
// Save the authentication token for the second stage of the authentication
sess.setAuthenticationToken(authToken);
sess.setAuthenticationContext( new AuthTokenAuthContext( authToken));
// Get the challenge from the token
@@ -279,13 +336,9 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
*/
private final int doMD4UserAuthentication(ClientInfo client, SrvSession sess, int alg)
{
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(client.getUserName());
String md4hash = getAuthenticationComponent().getMD4HashedPassword(client.getUserName());
if ( md4hash != null)
{
@@ -350,8 +403,9 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
logger.info( "Logged on user " + client.getUserName() + " (" + sess.getRemoteAddress() + ") using auto-logon shared password");
// Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName()));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser(client.getUserName()));
// Get the users home folder node, if available
@@ -392,17 +446,18 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
*/
private final int doPassthruUserAuthentication(ClientInfo client, SrvSession sess, int alg)
{
// Start a transaction
sess.beginWriteTransaction( m_transactionService);
// Default logon status to disallow
// Default logon status to disallow
int authSts = CifsAuthenticator.AUTH_DISALLOW;
// Get the authentication token for the session
NTLMPassthruToken authToken = (NTLMPassthruToken) sess.getAuthenticationToken();
AuthContext authCtx = sess.getAuthenticationContext();
if ( authCtx == null || authCtx instanceof AuthTokenAuthContext == false)
return CifsAuthenticator.AUTH_DISALLOW;
AuthTokenAuthContext tokenCtx = (AuthTokenAuthContext) authCtx;
NTLMPassthruToken authToken = tokenCtx.getToken();
if ( authToken == null)
return CifsAuthenticator.AUTH_DISALLOW;
@@ -434,7 +489,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
{
// Run the second stage of the passthru authentication
genAuthToken = m_authComponent.authenticate( authToken);
genAuthToken = getAuthenticationComponent().authenticate( authToken);
// Check if the user has been logged on as a guest
@@ -460,8 +515,9 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
}
// Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( genAuthToken);
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( genAuthToken);
// Get the users home folder node, if available
@@ -477,9 +533,9 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
logger.error("Error during passthru authentication", ex);
}
// Clear the authentication token
// Clear the authentication context
sess.setAuthenticationToken(null);
sess.setAuthenticationContext(null);
// Return the authentication status

View File

@@ -1,53 +1,60 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
/**
* Name Template Exception Class
* <p>
* Thrown when a NetBIOS name template contains invalid characters or is too long.
*/
public class NameTemplateException extends Exception
{
private static final long serialVersionUID = 3256439188231762230L;
/**
* Default constructor.
*/
public NameTemplateException()
{
super();
}
/**
* Class constructor
*
* @param s java.lang.String
*/
public NameTemplateException(String s)
{
super(s);
}
}
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.auth.cifs;
import org.alfresco.jlan.server.auth.AuthContext;
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
/**
* Authenitcation Token Authentication Context Class
*
* @author gkspencer
*/
public class AuthTokenAuthContext extends AuthContext {
// Passthru authentication token
private NTLMPassthruToken m_token;
/**
* Class constructor
*
* @param token NTLMPassthruToken
*/
public AuthTokenAuthContext( NTLMPassthruToken token)
{
m_token = token;
}
/**
* Return the passthru authentication token
*
* @return NTLMPassthruToken
*/
public final NTLMPassthruToken getToken()
{
return m_token;
}
}

View File

@@ -0,0 +1,339 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.auth.cifs;
import javax.transaction.UserTransaction;
import net.sf.acegisecurity.Authentication;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.AlfrescoConfigSection;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.filesys.repo.ContentContext;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.CifsAuthenticator;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.filesys.DiskDeviceContext;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.SrvDiskInfo;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
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.LogFactory;
/**
* CIFS Authenticator Base Class
*
* <p>
* Base class for Alfresco CIFS authenticator implementations.
*
* @author gkspencer
*/
public abstract class CifsAuthenticatorBase extends CifsAuthenticator
{
// Logging
protected static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth");
// MD4 hash decoder
protected MD4PasswordEncoder m_md4Encoder = new MD4PasswordEncoderImpl();
// Alfresco configuration
protected AlfrescoConfigSection m_alfrescoConfig;
/**
* Initialize the authenticator
*
* @param config ServerConfiguration
* @param params ConfigElement
* @exception InvalidConfigurationException
*/
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
{
super.initialize(config, params);
// Get the alfresco configuration section, required to get hold of various services/components
m_alfrescoConfig = (AlfrescoConfigSection) config.getConfigSection( AlfrescoConfigSection.SectionName);
// Check that the required authentication classes are available
if ( m_alfrescoConfig == null || getAuthenticationComponent() == null)
throw new InvalidConfigurationException("Authentication component not available");
// Set the guest user name
setGuestUserName( getAuthenticationComponent().getGuestUserName());
// Check that the authentication component is the required type for this authenticator
if ( validateAuthenticationMode() == false)
throw new InvalidConfigurationException("Required authentication mode not available");
}
/**
* Validate that the authentication component supports the required mode
*
* @return boolean
*/
protected boolean validateAuthenticationMode()
{
return true;
}
/**
* Logon using the guest user account
*
* @param client ClientInfo
* @param sess SrvSession
*/
protected void doGuestLogon( ClientInfo client, SrvSession sess)
{
// Check that the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false)
return;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Get a guest authentication token
getAuthenticationService().authenticateAsGuest();
Authentication authToken = getAuthenticationComponent().getCurrentAuthentication();
alfClient.setAuthenticationToken( authToken);
// Set the home folder for the guest user
client.setUserName( getGuestUserName());
getHomeFolderForUser( client);
// Mark the client as being a guest logon
client.setGuest( true);
// Create a dynamic share for the guest user, create the disk driver and context
DiskInterface diskDrv = m_alfrescoConfig.getRepoDiskInterface();
DiskDeviceContext diskCtx = new ContentContext(client.getUserName(), "", "", alfClient.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
sess.addDynamicShare( new DiskSharedDevice( client.getUserName(), diskDrv, diskCtx, SharedDevice.Temporary));
}
/**
* Get the home folder for the user
*
* @param client ClientInfo
*/
protected final void getHomeFolderForUser(ClientInfo client)
{
// Check if the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false)
return;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Get the home folder for the user
UserTransaction tx = getTransactionService().getUserTransaction();
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
if (ex instanceof RuntimeException)
{
throw (RuntimeException) ex;
}
else
{
throw new RuntimeException("Error during execution of transaction.", ex);
}
}
}
/**
* 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_alfrescoConfig.getTransactionService().getUserTransaction();
String personName = null;
try
{
tx.begin();
personName = m_alfrescoConfig.getPersonService().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;
}
/**
* Set the current authenticated user context for this thread
*
* @param client ClientInfo
*/
public void setCurrentUser(ClientInfo client) {
// Check the account type and setup the authentication context
if (client.isNullSession())
{
// Clear the authentication, null user should not be allowed to do any service calls
getAuthenticationComponent().clearCurrentSecurityContext();
}
else if (client.isGuest() == false && client instanceof AlfrescoClientInfo)
{
// Set the authentication context for the request
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
getAuthenticationComponent().setCurrentAuthentication(alfClient.getAuthenticationToken());
}
else
{
// Enable guest access for the request
getAuthenticationComponent().setGuestUserAsCurrentUser();
}
}
/**
* Return the authentication component
*
* @return AuthenticationComponent
*/
protected final AuthenticationComponent getAuthenticationComponent()
{
return m_alfrescoConfig.getAuthenticationComponent();
}
/**
* Return the authentication service
*
* @return AuthenticationService
*/
protected final AuthenticationService getAuthenticationService()
{
return m_alfrescoConfig.getAuthenticationService();
}
/**
* Return the node service
*
* @return NodeService
*/
protected final NodeService getNodeService()
{
return m_alfrescoConfig.getNodeService();
}
/**
* Return the person service
*
* @return PersonService
*/
protected final PersonService getPersonService()
{
return m_alfrescoConfig.getPersonService();
}
/**
* Return the transaction service
*
* @return TransactionService
*/
protected final TransactionService getTransactionService()
{
return m_alfrescoConfig.getTransactionService();
}
}

View File

@@ -22,14 +22,13 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.server.auth;
package org.alfresco.filesys.auth.cifs;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import javax.security.auth.Subject;
@@ -41,37 +40,39 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.sasl.RealmCallback;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.auth.AuthenticatorException;
import org.alfresco.filesys.server.auth.CifsAuthenticator;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
import org.alfresco.filesys.server.auth.kerberos.KerberosDetails;
import org.alfresco.filesys.server.auth.kerberos.SessionSetupPrivilegedAction;
import org.alfresco.filesys.server.auth.ntlm.NTLM;
import org.alfresco.filesys.server.auth.ntlm.NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.NTLMv2Blob;
import org.alfresco.filesys.server.auth.ntlm.TargetInfo;
import org.alfresco.filesys.server.auth.ntlm.Type1NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.Type2NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.Type3NTLMMessage;
import org.alfresco.filesys.server.auth.spnego.NegTokenInit;
import org.alfresco.filesys.server.auth.spnego.NegTokenTarg;
import org.alfresco.filesys.server.auth.spnego.OID;
import org.alfresco.filesys.server.auth.spnego.SPNEGO;
import org.alfresco.filesys.server.config.InvalidConfigurationException;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.smb.Capability;
import org.alfresco.filesys.smb.SMBStatus;
import org.alfresco.filesys.smb.server.SMBSrvException;
import org.alfresco.filesys.smb.server.SMBSrvPacket;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.smb.server.VirtualCircuit;
import org.alfresco.filesys.util.DataPacker;
import org.alfresco.filesys.util.HexDump;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.jlan.server.auth.AuthenticatorException;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.NTLanManAuthContext;
import org.alfresco.jlan.server.auth.kerberos.KerberosDetails;
import org.alfresco.jlan.server.auth.kerberos.SessionSetupPrivilegedAction;
import org.alfresco.jlan.server.auth.ntlm.NTLM;
import org.alfresco.jlan.server.auth.ntlm.NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.NTLMv2Blob;
import org.alfresco.jlan.server.auth.ntlm.TargetInfo;
import org.alfresco.jlan.server.auth.ntlm.Type1NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.Type2NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.Type3NTLMMessage;
import org.alfresco.jlan.server.auth.spnego.NegTokenInit;
import org.alfresco.jlan.server.auth.spnego.NegTokenTarg;
import org.alfresco.jlan.server.auth.spnego.OID;
import org.alfresco.jlan.server.auth.spnego.SPNEGO;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.smb.Capability;
import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.jlan.smb.dcerpc.UUID;
import org.alfresco.jlan.smb.server.SMBSrvException;
import org.alfresco.jlan.smb.server.SMBSrvPacket;
import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.smb.server.VirtualCircuit;
import org.alfresco.jlan.util.DataPacker;
import org.alfresco.jlan.util.HexDump;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.ietf.jgss.Oid;
@@ -82,7 +83,7 @@ import org.ietf.jgss.Oid;
*
* @author gkspencer
*/
public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements CallbackHandler
public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implements CallbackHandler
{
// Constants
//
@@ -140,6 +141,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
*/
public EnterpriseCifsAuthenticator()
{
setExtendedSecurity( true);
}
/**
@@ -203,54 +205,25 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
throw new InvalidConfigurationException("Invalid login entry specified");
}
// Get the server principal name
// Build the CIFS service account name
ConfigElement principal = params.getChild("Principal");
StringBuilder cifsAccount = new StringBuilder();
if ( principal != null) {
// Use the supplied principal name to build the account name
StringBuffer cifsAccount = new StringBuffer();
cifsAccount.append( principal.getValue());
cifsAccount.append("@");
cifsAccount.append(m_krbRealm);
m_accountName = cifsAccount.toString();
}
else {
// Build the CIFS service account name
StringBuffer cifsAccount = new StringBuffer();
cifsAccount.append("cifs/");
cifsAccount.append( config.getServerName().toLowerCase());
cifsAccount.append("@");
cifsAccount.append(m_krbRealm);
m_accountName = cifsAccount.toString();
}
cifsAccount.append("cifs/");
cifsAccount.append( config.getServerName().toLowerCase());
cifsAccount.append("@");
cifsAccount.append(m_krbRealm);
m_accountName = cifsAccount.toString();
// Create a login context for the CIFS server service
try
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "CIFS Kerberos login using account " + m_accountName);
// Login the CIFS server service
m_loginContext = new LoginContext( m_loginEntryName, this);
m_loginContext.login();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "CIFS Kerberos login successful");
}
catch ( LoginException ex)
{
@@ -266,9 +239,9 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
Vector<Oid> mechTypes = new Vector<Oid>();
mechTypes.add(OID.NTLMSSP);
mechTypes.add(OID.KERBEROS5);
mechTypes.add(OID.MSKERBEROS5);
mechTypes.add(OID.NTLMSSP);
// Build the SPNEGO NegTokenInit blob
@@ -366,7 +339,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Make sure that either Kerberos support is enabled and/or the authentication component
// supports MD4 hashed passwords
if ( isKerberosEnabled() == false && m_authComponent.getNTLMMode() != NTLMMode.MD4_PROVIDER)
if ( isKerberosEnabled() == false && getAuthenticationComponent().getNTLMMode() != NTLMMode.MD4_PROVIDER)
{
// Log an error
@@ -508,9 +481,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
UUID serverGUID = sess.getSMBServer().getServerGUID();
DataPacker.putIntelLong( serverGUID.getLeastSignificantBits(), buf, pos);
DataPacker.putIntelLong( serverGUID.getMostSignificantBits(), buf, pos + 8);
System.arraycopy( serverGUID.getBytes(), 0, buf, pos, 16);
pos += 16;
// If SPNEGO is enabled then pack the NegTokenInit blob
@@ -540,15 +511,62 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Check that the received packet looks like a valid NT session setup andX request
if (reqPkt.checkPacketIsValid(12, 0) == false)
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
// Check if the request is using security blobs or the older hashed password format
if ( reqPkt.getParameterCount() == 13)
{
// Process the hashed password session setup
UserTransaction tx = null;
try
{
// Start a transaction
doHashedPasswordLogon( sess, reqPkt, respPkt);
tx = getTransactionService().getUserTransaction( true);
tx.begin();
// Process the hashed password session setup
doHashedPasswordLogon( sess, reqPkt, respPkt);
}
catch ( Exception ex)
{
// Convert to an access denied exception
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
return;
}
@@ -587,7 +605,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
domain = reqPkt.unpackString(isUni);
if (domain == null)
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// Extract the clients native operating system
@@ -601,7 +619,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
clientOS = reqPkt.unpackString(isUni);
if (clientOS == null)
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// DEBUG
@@ -617,7 +635,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Create the client information and store in the session
ClientInfo client = new ClientInfo();
ClientInfo client = new AlfrescoClientInfo();
client.setDomain(domain);
client.setOperatingSystem(clientOS);
@@ -641,6 +659,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
byte[] respBlob = null;
boolean isNTLMSSP = false;
UserTransaction tx = null;
try
{
@@ -658,7 +678,12 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
isNTLMSSP = true;
}
// Process the security blob
// Start a transaction
tx = getTransactionService().getUserTransaction( true);
tx.begin();
// Process the security blob
if ( isNTLMSSP == true)
{
@@ -683,6 +708,44 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
throw ex;
}
catch ( Exception ex)
{
// Cleanup any stored context
sess.removeSetupObject( client.getProcessId());
// Convert to an access denied exception
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
@@ -781,7 +844,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Failed to allocate a UID
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) {
@@ -828,7 +891,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
pos = DataPacker.putString("Java", buf, pos, true, isUni);
pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni);
pos = DataPacker.putString(sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni);
pos = DataPacker.putString(getCIFSConfig().getDomainName(), buf, pos, true, isUni);
respPkt.setByteCount(pos - respPkt.getByteOffset());
}
@@ -864,7 +927,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Check for a type 1 NTLMSSP message
@@ -933,7 +996,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Determine if the client sent us NTLMv1 or NTLMv2
@@ -1034,7 +1097,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Get the second stage NTLMSSP blob
@@ -1076,7 +1139,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Determine the authentication mechanism the client is using and logon
@@ -1124,7 +1187,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// No valid authentication mechanism
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1135,7 +1198,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Generate the NegTokenTarg blob
@@ -1157,7 +1220,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Failed to build response blob
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Return the SPNEGO response blob
@@ -1199,99 +1262,37 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
negTokenTarg = new NegTokenTarg( SPNEGO.AcceptCompleted, OID.KERBEROS5, krbDetails.getResponseToken());
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if this is a null logon
String userName = krbDetails.getUserName();
if ( userName != null)
{
// Check for the machine account name
if ( userName.endsWith( "$") && userName.equals( userName.toUpperCase()))
{
// Null logon
client.setLogonType( ClientInfo.LogonNull);
// Debug
if ( logger.isDebugEnabled())
logger.debug("Machine account logon, " + userName + ", as null logon");
}
else
{
// Map the user name to an Alfresco person name
String alfPersonName = mapUserNameToPerson( userName);
// Check if the user name was mapped, if not then check if this is a domain client system name, ie. ends with '$'
if ( alfPersonName != null)
{
// Setup the Acegi authenticated user
AuthenticationUtil.setCurrentUser( alfPersonName);
// Store the full user name in the client information, indicate that this is not a guest logon
client.setUserName( krbDetails.getSourceName());
client.setGuest( false);
client.setAuthenticationToken( m_authComponent.getCurrentAuthentication());
// Indicate that the session is logged on
sess.setLoggedOn(true);
}
else
{
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
}
}
}
else
{
// Null logon
client.setLogonType( ClientInfo.LogonNull);
}
// Setup the Acegi authenticated user
// Set the current user to be authenticated, save the authentication token
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson(krbDetails.getUserName())));
// Store the full user name in the client information, indicate that this is not a guest logon
client.setUserName( krbDetails.getSourceName());
client.setGuest( false);
// Indicate that the session is logged on
sess.setLoggedOn(true);
// Debug
if ( logger.isDebugEnabled())
logger.debug("Logged on using Kerberos, user " + userName);
}
else
{
// Debug
if ( logger.isDebugEnabled())
logger.debug( "No SPNEGO response, Kerberos logon failed");
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
logger.debug("Logged on using Kerberos");
}
}
catch (Exception ex)
{
// Log the error
logger.error("Kerberos logon error", ex);
logger.error(ex);
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Return the response SPNEGO blob
@@ -1320,7 +1321,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Get the type 2 message that contains the challenge sent to the client
@@ -1330,7 +1331,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Get the NTLM logon details
@@ -1353,7 +1354,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(userName);
String md4hash = getAuthenticationComponent().getMD4HashedPassword(userName);
if ( md4hash != null)
{
@@ -1390,13 +1391,14 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
{
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
// Setup the Acegi authenticated user
client.setAuthenticationToken( m_authComponent.setCurrentUser( mapUserNameToPerson(userName)));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson(userName)));
// Store the full user name in the client information, indicate that this is not a guest logon
@@ -1415,7 +1417,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1426,7 +1428,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
@@ -1450,16 +1452,12 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Check for a null logon
@@ -1478,7 +1476,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(client.getUserName());
String md4hash = getAuthenticationComponent().getMD4HashedPassword(client.getUserName());
if ( md4hash != null)
{
@@ -1526,13 +1524,14 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
{
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
// Setup the Acegi authenticated user
client.setAuthenticationToken( m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName())));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( client.getUserName())));
// Store the full user name in the client information, indicate that this is not a guest logon
@@ -1550,7 +1549,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1561,7 +1560,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
@@ -1581,13 +1580,9 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId());
sess.removeSetupObject( client.getProcessId());
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if we are using local MD4 password hashes or passthru authentication
// Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Get the NTLM logon details
@@ -1610,7 +1605,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(userName);
String md4hash = getAuthenticationComponent().getMD4HashedPassword(userName);
if ( md4hash != null)
{
@@ -1641,13 +1636,14 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
{
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
// Setup the Acegi authenticated user
client.setAuthenticationToken( m_authComponent.setCurrentUser( mapUserNameToPerson( userName)));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( userName)));
// Store the full user name in the client information, indicate that this is not a guest logon
@@ -1666,7 +1662,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1677,7 +1673,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1688,7 +1684,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
@@ -1702,13 +1698,9 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
private final void doNTLMv2Logon(SMBSrvSession sess, ClientInfo client)
throws SMBSrvException
{
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Check for a null logon
@@ -1727,7 +1719,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(client.getUserName());
String md4hash = getAuthenticationComponent().getMD4HashedPassword(client.getUserName());
if ( md4hash != null)
{
@@ -1768,13 +1760,14 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
{
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
// Setup the Acegi authenticated user
client.setAuthenticationToken( m_authComponent.setCurrentUser( mapUserNameToPerson( client.getUserName())));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( client.getUserName())));
// Store the full user name in the client information, indicate that this is not a guest logon
@@ -1792,7 +1785,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1803,7 +1796,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1814,7 +1807,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
@@ -1834,13 +1827,9 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId());
sess.removeSetupObject( client.getProcessId());
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
if ( getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Get the NTLM logon details
@@ -1863,7 +1852,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = m_authComponent.getMD4HashedPassword(userName);
String md4hash = getAuthenticationComponent().getMD4HashedPassword(userName);
if ( md4hash != null)
{
@@ -1935,13 +1924,14 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
{
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
// Setup the Acegi authenticated user
client.setAuthenticationToken( m_authComponent.setCurrentUser( mapUserNameToPerson( userName)));
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( userName)));
// Store the full user name in the client information, indicate that this is not a guest logon
@@ -1960,7 +1950,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
else
@@ -1971,7 +1961,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
}
@@ -1990,7 +1980,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
if (reqPkt.checkPacketIsValid(13, 0) == false)
{
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// Extract the session details
@@ -2021,7 +2011,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
if (user == null)
{
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// Extract the clients primary domain name string
@@ -2037,7 +2027,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
if (domain == null)
{
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
}
@@ -2054,7 +2044,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
if (clientOS == null)
{
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
}
@@ -2080,7 +2070,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Create the client information and store in the session
ClientInfo client = new ClientInfo(user, uniPwd);
ClientInfo client = new AlfrescoClientInfo(user, uniPwd);
client.setANSIPassword(ascPwd);
client.setDomain(domain);
client.setOperatingSystem(clientOS);
@@ -2153,7 +2143,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Failed to allocate a UID
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE))
{
@@ -2199,7 +2189,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
pos = DataPacker.putString("Java", buf, pos, true, isUni);
pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni);
pos = DataPacker.putString(sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni);
pos = DataPacker.putString(getCIFSConfig().getDomainName(), buf, pos, true, isUni);
respPkt.setByteCount(pos - respPkt.getByteOffset());
}

View File

@@ -22,42 +22,48 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.server.auth.passthru;
package org.alfresco.filesys.auth.cifs;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.UUID;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.SessionListener;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.AuthContext;
import org.alfresco.filesys.server.auth.AuthenticatorException;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.auth.CifsAuthenticator;
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
import org.alfresco.filesys.server.auth.ntlm.NTLM;
import org.alfresco.filesys.server.auth.ntlm.NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.TargetInfo;
import org.alfresco.filesys.server.auth.ntlm.Type1NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.Type2NTLMMessage;
import org.alfresco.filesys.server.auth.ntlm.Type3NTLMMessage;
import org.alfresco.filesys.server.config.InvalidConfigurationException;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.core.SharedDevice;
import org.alfresco.filesys.smb.Capability;
import org.alfresco.filesys.smb.SMBStatus;
import org.alfresco.filesys.smb.server.SMBServer;
import org.alfresco.filesys.smb.server.SMBSrvException;
import org.alfresco.filesys.smb.server.SMBSrvPacket;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.smb.server.VirtualCircuit;
import org.alfresco.filesys.util.DataPacker;
import org.alfresco.filesys.util.HexDump;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.jlan.server.SessionListener;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.AuthContext;
import org.alfresco.jlan.server.auth.AuthenticatorException;
import org.alfresco.jlan.server.auth.CifsAuthenticator;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.NTLanManAuthContext;
import org.alfresco.jlan.server.auth.ntlm.NTLM;
import org.alfresco.jlan.server.auth.ntlm.NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.TargetInfo;
import org.alfresco.jlan.server.auth.ntlm.Type1NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.Type2NTLMMessage;
import org.alfresco.jlan.server.auth.ntlm.Type3NTLMMessage;
import org.alfresco.jlan.server.auth.passthru.AuthenticateSession;
import org.alfresco.jlan.server.auth.passthru.PassthruDetails;
import org.alfresco.jlan.server.auth.passthru.PassthruServers;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.smb.Capability;
import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.jlan.smb.dcerpc.UUID;
import org.alfresco.jlan.smb.server.SMBServer;
import org.alfresco.jlan.smb.server.SMBSrvException;
import org.alfresco.jlan.smb.server.SMBSrvPacket;
import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.smb.server.VirtualCircuit;
import org.alfresco.jlan.util.DataPacker;
import org.alfresco.jlan.util.HexDump;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
@@ -71,7 +77,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author GKSpencer
*/
public class PassthruAuthenticator extends CifsAuthenticator implements SessionListener
public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements SessionListener
{
// Debug logging
@@ -112,7 +118,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
* <p>
* Default to user mode security with encrypted password support.
*/
public PassthruAuthenticator()
public PassthruCifsAuthenticator()
{
// Allocate the session table
@@ -144,6 +150,13 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
*/
public int authenticateUser(ClientInfo client, SrvSession sess, int alg)
{
// Check that the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false)
return CifsAuthenticator.AUTH_DISALLOW;
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// The null session will only be allowed to connect to the IPC$ named pipe share.
if (client.isNullSession())
@@ -156,178 +169,223 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
return CifsAuthenticator.AUTH_ALLOW;
}
// Start a transaction
// Start a transaction
sess.beginReadTransaction( m_transactionService);
// Check if the client is already authenticated, and it is not a null logon
if ( client.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
{
// Use the existing authentication token
m_authComponent.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
UserTransaction tx = getTransactionService().getUserTransaction( true);
int authSts = AUTH_DISALLOW;
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
try
{
// Check if guest logons are allowed
// Start the transaction
tx.begin();
// Check if the client is already authenticated, and it is not a null logon
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)
{
try
if ( alfClient.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
{
// Authenticate the user by passing the hashed password to the authentication server
// using the session that has already been setup.
AuthenticateSession authSess = passDetails.getAuthenticateSession();
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword(), 0);
// Check if the user has been logged on as a guest
if (authSess.isGuest())
{
// Check if the local server allows guest access
if (allowGuest() == true)
{
// Get a guest authentication token
doGuestLogon( client, sess);
// Allow the user access as a guest
authSts = CifsAuthenticator.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 = m_personService.getUserIdentifier( username);
if ( personName != null)
{
// Use the person name as the current user
client.setAuthenticationToken( 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 if ( logger.isDebugEnabled())
logger.debug("Failed to find person matching user " + username);
}
}
catch (Exception ex)
{
// Use the existing authentication token
getAuthenticationComponent().setCurrentUser( mapUserNameToPerson( client.getUserName()));
// Debug
logger.error(ex.getMessage());
if ( logger.isDebugEnabled())
logger.debug("Re-using existing authentication token");
// Return the authentication status
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
}
// Keep the authentication session if the user session is an SMB session, else close the
// session now
if ((sess instanceof SMBSrvSession) == false)
// Check if this is a guest logon
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Remove the passthru session from the active list
m_sessions.remove(sess.getUniqueId());
// Close the passthru authentication session
// 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)
{
try
{
// Close the authentication session
// Authenticate the user by passing the hashed password to the authentication server
// using the session that has already been setup.
AuthenticateSession authSess = passDetails.getAuthenticateSession();
authSess.CloseSession();
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Closed auth session, sessId=" + authSess.getSessionId());
authSess.doSessionSetup(client.getDomain(), client.getUserName(), null, client.getANSIPassword(), client.getPassword(), 0);
// Check if the user has been logged on as a guest
if (authSess.isGuest())
{
// Check if the local server allows guest access
if (allowGuest() == true)
{
// Get a guest authentication token
doGuestLogon( client, sess);
// Allow the user access as a guest
authSts = CifsAuthenticator.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 = CifsAuthenticator.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("Passthru error closing session (auth user)", ex);
logger.error(ex.getMessage());
}
// 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
{
// 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)
{
}
}
}
else
{
// DEBUG
if (logger.isDebugEnabled())
logger.debug(" No PassthruDetails for " + sess.getUniqueId());
}
// Return the authentication status
return authSts;
@@ -338,7 +396,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
*
* @return AuthContext
*/
public AuthContext getAuthContext( SMBSrvSession sess)
public AuthContext getAuthContext( SrvSession sess)
{
// Make sure the SMB server listener is installed
@@ -368,7 +426,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Create an entry in the active sessions table for the new session
PassthruDetails passDetails = new PassthruDetails(sess, authSess, false);
PassthruDetails passDetails = new PassthruDetails(sess, authSess);
m_sessions.put(sess.getUniqueId(), passDetails);
// Use the challenge key returned from the authentication server
@@ -381,9 +439,6 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
if (logger.isDebugEnabled())
logger.debug("Passthru sessId=" + authSess.getSessionId() + ", auth ctx=" + authCtx);
}
else if ( logger.isDebugEnabled())
logger.debug("No passthru server available for domain, " + domain);
}
catch (Exception ex)
{
@@ -433,9 +488,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
UUID serverGUID = sess.getSMBServer().getServerGUID();
DataPacker.putIntelLong( serverGUID.getLeastSignificantBits(), buf, pos);
DataPacker.putIntelLong( serverGUID.getMostSignificantBits(), buf, pos + 8);
System.arraycopy( serverGUID.getBytes(), 0, buf, pos, 16);
pos += 16;
// Set the negotiate response length
@@ -457,7 +510,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Check that the received packet looks like a valid NT session setup andX request
if (reqPkt.checkPacketIsValid(12, 0) == false)
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
// Check if the request is using security blobs or the older hashed password format
@@ -504,7 +557,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
domain = reqPkt.unpackString(isUni);
if (domain == null)
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// Extract the clients native operating system
@@ -518,7 +571,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
clientOS = reqPkt.unpackString(isUni);
if (clientOS == null)
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
// Store the client maximum buffer size, maximum multiplexed requests count and client capability flags
@@ -529,7 +582,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Create the client information and store in the session
ClientInfo client = new ClientInfo();
ClientInfo client = new AlfrescoClientInfo();
client.setDomain(domain);
client.setOperatingSystem(clientOS);
@@ -587,7 +640,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{
// Invalid blob type
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError);
throw new SMBSrvException( SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
}
}
catch (SMBSrvException ex)
@@ -698,7 +751,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Failed to allocate a UID
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) {
@@ -745,7 +798,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
pos = DataPacker.putString("Java", buf, pos, true, isUni);
pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni);
pos = DataPacker.putString(sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni);
pos = DataPacker.putString(getCIFSConfig().getDomainName(), buf, pos, true, isUni);
respPkt.setByteCount(pos - respPkt.getByteOffset());
}
@@ -781,7 +834,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Return a logon failure status
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Check for a type 1 NTLMSSP message
@@ -802,9 +855,6 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
NTLanManAuthContext ntlmCtx = (NTLanManAuthContext) getAuthContext( sess);
if ( ntlmCtx == null)
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
// Build a type2 message to send back to the client, containing the challenge
String domain = sess.getSMBServer().getServerName();
@@ -850,7 +900,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
// Determine if the client sent us NTLMv1 or NTLMv2
@@ -864,7 +914,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Return a logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
}
else
{
@@ -897,7 +947,6 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{
// Get the type 2 message that contains the challenge sent to the client
Type2NTLMMessage type2Msg = (Type2NTLMMessage) sess.getSetupObject( client.getProcessId());
sess.removeSetupObject( client.getProcessId());
// Get the NTLM logon details
@@ -955,7 +1004,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{
// Wrap the service calls in a transaction
UserTransaction tx = m_transactionService.getUserTransaction( false);
UserTransaction tx = getTransactionService().getUserTransaction( false);
try
{
@@ -965,13 +1014,13 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Map the passthru username to an Alfresco person
NodeRef userNode = m_personService.getPerson(userName);
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
String personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
m_authComponent.setCurrentUser(personName);
String personName = (String) getNodeService().getProperty(userNode, ContentModel.PROP_USERNAME);
getAuthenticationComponent().setCurrentUser(personName);
// DEBUG
@@ -982,7 +1031,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{
// Set using the user name
m_authComponent.setCurrentUser( userName);
getAuthenticationComponent().setCurrentUser( userName);
// DEBUG
@@ -991,8 +1040,9 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
}
// Get the authentication token and store
client.setAuthenticationToken( m_authComponent.getCurrentAuthentication());
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().getCurrentAuthentication());
// Indicate that the client is logged on
@@ -1027,9 +1077,14 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
}
catch (Exception ex)
{
// Debug
logger.error(ex.getMessage());
// Indicate logon failure
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
throw new SMBSrvException( SMBStatus.NTErr, SMBStatus.NTLogonFailure);
}
finally
{
@@ -1131,7 +1186,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
// Get the local server name, trim the domain name
srvList = config.getLocalServerName(true);
srvList = getCIFSConfig().getServerName();
if(srvList == null)
throw new AlfrescoRuntimeException("Passthru authenticator failed to get local server name");
}
@@ -1174,7 +1229,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
{
// Get the local domain/workgroup name
domainName = config.getLocalDomainName();
domainName = getCIFSConfig().getDomainName();
}
// Check if a domain name has been specified
@@ -1196,9 +1251,16 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
if (domainName != null)
{
// Initialize using the domain
m_passthruServers.setDomain(domainName);
try
{
// Initialize using the domain
m_passthruServers.setDomain(domainName);
}
catch ( IOException ex)
{
throw new AlfrescoRuntimeException("Error setting passthru domain, " + ex.getMessage());
}
}
}
@@ -1304,7 +1366,7 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
PassthruDetails passDetails = m_sessions.get(sess.getUniqueId());
if (passDetails != null && passDetails.hasKeepAlive() == false)
if (passDetails != null)
{
// Remove the passthru session from the active list

View File

@@ -0,0 +1,296 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.auth.ftp;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import net.sf.acegisecurity.Authentication;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.AlfrescoConfigSection;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.jlan.ftp.FTPAuthenticator;
import org.alfresco.jlan.ftp.FTPSrvSession;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.PasswordEncryptor;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Alfresco FTP Authenticator Class
*
* @author gkspencer
*/
public class AlfrescoFtpAuthenticator implements FTPAuthenticator {
// Logging
protected static final Log logger = LogFactory.getLog("org.alfresco.ftp.protocol.auth");
// MD4 hash decoder
protected MD4PasswordEncoder m_md4Encoder = new MD4PasswordEncoderImpl();
// Password encryptor, for MD4 hashing
protected PasswordEncryptor m_encryptor = new PasswordEncryptor();
// Alfresco configuration section
private AlfrescoConfigSection m_alfrescoConfig;
/**
* Initialize the authenticator
*
* @param config ServerConfiguration
* @param params ConfigElement
* @exception InvalidConfigurationException
*/
public void initialize(ServerConfiguration config, ConfigElement params)
throws InvalidConfigurationException
{
// Get the alfresco configuration section, required to get hold of various services/components
m_alfrescoConfig = (AlfrescoConfigSection) config.getConfigSection( AlfrescoConfigSection.SectionName);
// Check that the required authentication classes are available
if ( m_alfrescoConfig == null || getAuthenticationComponent() == null)
throw new InvalidConfigurationException("Authentication component not available");
}
/**
* Authenticate the user
*
* @param client ClientInfo
* @param sess FTPSrvSession
* @return boolean
*/
public boolean authenticateUser( ClientInfo client, FTPSrvSession sess)
{
// Check that the client is an Alfresco client
if ( client instanceof AlfrescoClientInfo == false)
return false;
// Check if this is a guest logon
boolean authSts = false;
UserTransaction tx = null;
try
{
if ( client.isGuest())
{
// Get a guest authentication token
doGuestLogon((AlfrescoClientInfo) client, sess);
// Indicate logged on as guest
authSts = true;
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + authSts);
// Return the guest status
return authSts;
}
// Start a transaction
tx = getTransactionService().getUserTransaction( true);
tx.begin();
// Perform local MD4 password check
authSts = doMD4UserAuthentication(client, sess);
}
catch ( Exception ex)
{
if ( logger.isDebugEnabled())
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)
{
}
}
}
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + authSts +
" via " + (getAuthenticationComponent().getNTLMMode() == NTLMMode.MD4_PROVIDER ? "MD4" : "Passthru"));
// Return the authentication status
return authSts;
}
/**
* Logon using the guest user account
*
* @param client AlfrescoClientInfo
* @param sess SrvSession
*/
protected void doGuestLogon( AlfrescoClientInfo client, SrvSession sess)
{
// Get a guest authentication token
getAuthenticationService().authenticateAsGuest();
Authentication authToken = getAuthenticationComponent().getCurrentAuthentication();
client.setAuthenticationToken( authToken);
// Mark the client as being a guest logon
client.setGuest( true);
}
/**
* Perform MD4 user authentication
*
* @param client Client information
* @param sess Server session
* @return boolean
*/
private final boolean doMD4UserAuthentication(ClientInfo client, SrvSession sess)
{
// Get the stored MD4 hashed password for the user, or null if the user does not exist
String md4hash = getAuthenticationComponent().getMD4HashedPassword(client.getUserName());
if ( md4hash != null)
{
// Check if the client has supplied an NTLM hashed password, if not then do not allow access
if ( client.getPassword() == null)
return false;
// Encode the user supplied password
String userMd4 = m_md4Encoder.encodePassword( client.getPasswordAsString(), null);
// Compare the hashed passwords
if ( md4hash.equals( userMd4) == false)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Password mismatch for user " + client.getUserName());
// Access not allowed
return false;
}
// Logging
if ( logger.isInfoEnabled())
logger.info( "Logged on user " + client.getUserName() + " ( address " + sess.getRemoteAddress() + ")");
// Set the current user to be authenticated, save the authentication token
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
alfClient.setAuthenticationToken( getAuthenticationComponent().setCurrentUser(client.getUserName()));
// Passwords match, grant access
return true;
}
// User does not exist
return false;
}
/**
* Return the authentication componenet
*
* @return AuthenticationComponent
*/
protected final AuthenticationComponent getAuthenticationComponent()
{
return m_alfrescoConfig.getAuthenticationComponent();
}
/**
* Return the authentication service
*
* @return AuthenticationService
*/
protected final AuthenticationService getAuthenticationService()
{
return m_alfrescoConfig.getAuthenticationService();
}
/**
* Return the transaction service
*
* @return TransactionService
*/
protected final TransactionService getTransactionService()
{
return m_alfrescoConfig.getTransactionService();
}
}

View File

@@ -19,24 +19,29 @@
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.server.auth;
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.auth.nfs;
import java.util.HashMap;
import java.util.List;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.config.InvalidConfigurationException;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.oncrpc.AuthType;
import org.alfresco.filesys.server.oncrpc.Rpc;
import org.alfresco.filesys.server.oncrpc.RpcAuthenticationException;
import org.alfresco.filesys.server.oncrpc.RpcAuthenticator;
import org.alfresco.filesys.server.oncrpc.RpcPacket;
import org.alfresco.filesys.server.oncrpc.nfs.NFS;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.filesys.AlfrescoConfigSection;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.jlan.oncrpc.AuthType;
import org.alfresco.jlan.oncrpc.Rpc;
import org.alfresco.jlan.oncrpc.RpcAuthenticationException;
import org.alfresco.jlan.oncrpc.RpcAuthenticator;
import org.alfresco.jlan.oncrpc.RpcPacket;
import org.alfresco.jlan.oncrpc.nfs.NFS;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -61,10 +66,9 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
private HashMap<Integer, String> m_idMap;
// Authentication component and services
private AuthenticationComponent m_authComponent;
private TransactionService m_transService;
// Alfresco configuration
protected AlfrescoConfigSection m_alfrescoConfig;
/**
* Authenticate an RPC client and create a unique session id key.
@@ -159,7 +163,6 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
*/
public ClientInfo getRpcClientInformation(Object sessKey, RpcPacket rpc)
{
// Create a client information object to hold the client details
ClientInfo cInfo = null;
@@ -207,7 +210,7 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
{
// Create the client information and fill in relevant fields
cInfo = new ClientInfo( userName, null);
cInfo = ClientInfo.getFactory().createInfo( userName, null);
cInfo.setNFSAuthenticationType( authType);
cInfo.setClientAddress( clientAddr);
@@ -227,7 +230,7 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
{
// Create the client information
cInfo = new ClientInfo( "", null);
cInfo = ClientInfo.getFactory().createInfo( "", null);
cInfo.setClientAddress(rpc.getClientAddress().getHostAddress());
// DEBUG
@@ -252,64 +255,104 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
{
// Start a transaction
sess.beginReadTransaction( m_transService);
UserTransaction tx = m_alfrescoConfig.getTransactionService().getUserTransaction( true);
// Check the account type and setup the authentication context
if ( client == null || client.isNullSession())
{
// Clear the authentication, null user should not be allowed to do any service calls
m_authComponent.clearCurrentSecurityContext();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Clear security context, client=" + client);
}
else if ( client.isGuest() == false)
{
// Check if the authentication token has been set for the client
if ( client.hasAuthenticationToken() == false)
{
// Set the current user and retrieve the authentication token
m_authComponent.setCurrentUser( client.getUserName());
client.setAuthenticationToken( m_authComponent.getCurrentAuthentication());
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set user name=" + client.getUserName() + ", token=" + client.getAuthenticationToken());
}
else
{
// Set the authentication context for the request
m_authComponent.setCurrentAuthentication( client.getAuthenticationToken());
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set user using auth token, token=" + client.getAuthenticationToken());
}
}
else
{
// Enable guest access for the request
m_authComponent.setGuestUserAsCurrentUser();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set guest user");
}
// Commit the authentication transaction
sess.endTransaction();
try
{
// start the transaction
tx.begin();
// Check the account type and setup the authentication context
if ( client == null || client.isNullSession() || client instanceof AlfrescoClientInfo == false)
{
// Clear the authentication, null user should not be allowed to do any service calls
m_alfrescoConfig.getAuthenticationComponent().clearCurrentSecurityContext();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Clear security context, client=" + client);
}
else if ( client.isGuest() == false)
{
// Access the Alfresco client
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Check if the authentication token has been set for the client
if ( alfClient.hasAuthenticationToken() == false)
{
// Set the current user and retrieve the authentication token
m_alfrescoConfig.getAuthenticationComponent().setCurrentUser( client.getUserName());
alfClient.setAuthenticationToken( m_alfrescoConfig.getAuthenticationComponent().getCurrentAuthentication());
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set user name=" + client.getUserName() + ", token=" + alfClient.getAuthenticationToken());
}
else
{
// Set the authentication context for the request
m_alfrescoConfig.getAuthenticationComponent().setCurrentAuthentication( alfClient.getAuthenticationToken());
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set user using auth token, token=" + alfClient.getAuthenticationToken());
}
}
else
{
// Enable guest access for the request
m_alfrescoConfig.getAuthenticationComponent().setGuestUserAsCurrentUser();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Set guest user");
}
}
catch ( Exception ex)
{
if ( logger.isDebugEnabled())
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)
{
}
}
}
}
/**
@@ -322,10 +365,9 @@ public class AlfrescoRpcAuthenticator implements RpcAuthenticator {
public void initialize(ServerConfiguration config, ConfigElement params)
throws InvalidConfigurationException {
// Get the configured authentication component and transaction service
m_authComponent = config.getAuthenticationComponent();
m_transService = config.getTransactionService();
// Get the Alfresco configuration section, for access to services
m_alfrescoConfig = (AlfrescoConfigSection) config.getConfigSection( AlfrescoConfigSection.SectionName);
// Check for the user mappings

View File

@@ -27,12 +27,12 @@ import java.util.Map;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.IOControlHandler;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.FileSystem;
import org.alfresco.filesys.server.filesys.NotifyChange;
import org.alfresco.filesys.server.state.FileState;
import org.alfresco.filesys.server.state.FileStateTable;
import org.alfresco.filesys.state.FileState;
import org.alfresco.filesys.state.FileStateTable;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileSystem;
import org.alfresco.jlan.server.filesys.NotifyChange;
import org.alfresco.repo.avm.CreateStoreCallback;
import org.alfresco.repo.avm.CreateVersionCallback;
import org.alfresco.repo.avm.PurgeStoreCallback;

View File

@@ -36,30 +36,30 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.core.DeviceContext;
import org.alfresco.filesys.server.core.DeviceContextException;
import org.alfresco.filesys.server.core.DeviceInterface;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileExistsException;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.FileOpenParams;
import org.alfresco.filesys.server.filesys.FileStatus;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.PathNotFoundException;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFileList;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.filesys.server.state.FileState;
import org.alfresco.filesys.util.StringList;
import org.alfresco.filesys.util.WildCard;
import org.alfresco.filesys.state.FileState;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.core.DeviceContext;
import org.alfresco.jlan.server.core.DeviceContextException;
import org.alfresco.jlan.server.core.DeviceInterface;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.DirectoryNotEmptyException;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileExistsException;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileOpenParams;
import org.alfresco.jlan.server.filesys.FileStatus;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.PathNotFoundException;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.TreeConnection;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
import org.alfresco.jlan.util.StringList;
import org.alfresco.jlan.util.WildCard;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.avm.CreateStoreTxnListener;
import org.alfresco.repo.avm.CreateVersionTxnListener;
@@ -130,7 +130,6 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Services and helpers
private AVMService m_avmService;
private TransactionService m_transactionService;
private MimetypeService m_mimetypeService;
private AuthenticationComponent m_authComponent;
private AuthenticationService m_authService;
@@ -174,16 +173,6 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
return m_authService;
}
/**
* Return the transaction service
*
* @return TransactionService
*/
public final TransactionService getTransactionService()
{
return m_transactionService;
}
/**
* Set the AVM service
*
@@ -195,17 +184,6 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
m_avmService = avmService;
}
/**
* Set the transaction service
*
* @param transactionService
* the transaction service
*/
public void setTransactionService(TransactionService transactionService)
{
m_transactionService = transactionService;
}
/**
* Set the authentication component
*
@@ -307,16 +285,12 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
* Parse and validate the parameter string and create a device context object for this instance of the shared
* device.
*
* @param devIface
* DeviceInterface
* @param name
* String
* @param cfg
* ConfigElement
* @param shareName String
* @param cfg ConfigElement
* @return DeviceContext
* @exception DeviceContextException
*/
public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement cfg)
public DeviceContext createContext(String shareName, ConfigElement cfg)
throws DeviceContextException
{
// Use the system user as the authenticated context for the filesystem initialization
@@ -328,7 +302,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Wrap the initialization in a transaction
UserTransaction tx = m_transactionService.getUserTransaction(false);
UserTransaction tx = getTransactionService().getUserTransaction(false);
AVMContext context = null;
@@ -385,7 +359,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Create the context
context = new AVMContext(name, showOptions, this);
context = new AVMContext(shareName, showOptions, this);
// Enable file state caching
@@ -558,7 +532,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Create the context
context = new AVMContext(name, storePath, version);
context = new AVMContext(shareName, storePath, version);
// Enable file state caching
@@ -622,7 +596,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Wrap the service request in a transaction
UserTransaction tx = m_transactionService.getUserTransaction(false);
UserTransaction tx = getTransactionService().getUserTransaction(false);
StringList storeNames = new StringList();
@@ -697,7 +671,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Wrap the service request in a transaction
UserTransaction tx = m_transactionService.getUserTransaction(false);
UserTransaction tx = getTransactionService().getUserTransaction(false);
Map<QName, PropertyValue> properties = null;
@@ -808,7 +782,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Start a transaction if the file has been updated
if ( file.getWriteCount() > 0)
sess.beginWriteTransaction( m_transactionService);
beginWriteTransaction( sess);
// Close the file
@@ -870,7 +844,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Create a new file
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
try
{
@@ -942,7 +916,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Create a new file
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
AVMNetworkFile netFile = null;
@@ -1032,7 +1006,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Make sure the path is to a folder before deleting it
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
try
{
@@ -1100,7 +1074,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Make sure the path is to a file before deleting it
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
try
{
@@ -1214,7 +1188,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Search for the file/folder
sess.beginReadTransaction(m_transactionService);
beginReadTransaction( sess);
AVMNodeDescriptor nodeDesc = m_avmService.lookup(storePath.getVersion(), storePath.getAVMPath());
@@ -1270,7 +1244,16 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Convert the relative path to a store path
AVMContext ctx = (AVMContext) tree.getContext();
AVMPath storePath = buildStorePath( ctx, name, sess);
AVMPath storePath = null;
try
{
storePath = buildStorePath( ctx, name, sess);
}
catch ( Exception ex)
{
throw new FileNotFoundException( name);
}
// DEBUG
@@ -1314,7 +1297,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Search for the file/folder
sess.beginReadTransaction( m_transactionService);
beginReadTransaction( sess);
FileInfo info = null;
@@ -1465,7 +1448,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Search for the file/folder
sess.beginReadTransaction(m_transactionService);
beginReadTransaction( sess);
AVMNetworkFile netFile = null;
@@ -1550,7 +1533,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
AVMNetworkFile avmFile = (AVMNetworkFile) file;
if (avmFile.hasContentChannel() == false)
sess.beginReadTransaction(m_transactionService);
beginReadTransaction( sess);
// Read the file
@@ -1612,7 +1595,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Start a transaction for the rename
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
try
{
@@ -1662,7 +1645,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
AVMNetworkFile avmFile = (AVMNetworkFile) file;
if (avmFile.hasContentChannel() == false)
sess.beginReadTransaction(m_transactionService);
beginReadTransaction( sess);
// Set the file position
@@ -1819,7 +1802,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
// Check if the path is a wildcard search
sess.beginReadTransaction(m_transactionService);
beginReadTransaction( sess);
SearchContext context = null;
if (WildCard.containsWildcards(searchPath))
@@ -1908,7 +1891,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
AVMNetworkFile avmFile = (AVMNetworkFile) file;
if (avmFile.hasContentChannel() == false || avmFile.isWritable() == false)
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
// Truncate or extend the file
@@ -1950,7 +1933,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface
AVMNetworkFile avmFile = (AVMNetworkFile) file;
if (avmFile.hasContentChannel() == false || avmFile.isWritable() == false)
sess.beginWriteTransaction(m_transactionService);
beginWriteTransaction( sess);
// Write the data to the file

View File

@@ -28,10 +28,11 @@ import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.smb.SeekType;
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.smb.SeekType;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -46,7 +47,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author GKSpencer
*/
public class AVMNetworkFile extends NetworkFile {
public class AVMNetworkFile extends AlfrescoNetworkFile {
// Logging
@@ -218,7 +219,7 @@ public class AVMNetworkFile extends NetworkFile {
// Write to the channel
ByteBuffer byteBuffer = ByteBuffer.wrap(buf, pos, len);
int count = m_channel.write(byteBuffer, fileOff);
m_channel.write(byteBuffer, fileOff);
// Set modification flag

View File

@@ -23,7 +23,7 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileName;
/**
* AVM Path Class

View File

@@ -23,11 +23,11 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.filesys.util.WildCard;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.util.WildCard;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
/**

View File

@@ -26,17 +26,17 @@ package org.alfresco.filesys.avm;
import java.util.Enumeration;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.InvalidUserException;
import org.alfresco.filesys.server.config.InvalidConfigurationException;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException;
import org.alfresco.filesys.server.core.ShareMapper;
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.DiskSharedDevice;
import org.alfresco.filesys.util.StringList;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.InvalidDeviceInterfaceException;
import org.alfresco.jlan.server.core.ShareMapper;
import org.alfresco.jlan.server.core.ShareType;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.core.SharedDeviceList;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection;
import org.alfresco.jlan.util.StringList;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.AVMWrongTypeException;
@@ -63,11 +63,16 @@ public class AVMShareMapper implements ShareMapper {
// Server configuration
private ServerConfiguration m_config;
private FilesystemsConfigSection m_filesysConfig;
// List of available AVM shares
private StringList m_avmShareNames;
// Filesystem driver to be used to create home shares
private AVMDiskDriver m_driver;
// Debug enable flag
private boolean m_debug;
@@ -91,6 +96,7 @@ public class AVMShareMapper implements ShareMapper {
// Save the server configuration
m_config = config;
m_filesysConfig = (FilesystemsConfigSection) m_config.getConfigSection(FilesystemsConfigSection.SectionName);
// Check if debug is enabled
@@ -101,7 +107,7 @@ public class AVMShareMapper implements ShareMapper {
m_avmShareNames = new StringList();
SharedDeviceList shrList = m_config.getShares();
SharedDeviceList shrList = m_filesysConfig.getShares();
Enumeration<SharedDevice> shrEnum = shrList.enumerateShares();
while ( shrEnum.hasMoreElements())
@@ -112,8 +118,17 @@ public class AVMShareMapper implements ShareMapper {
try
{
if ( curShare.getInterface() instanceof AVMDiskDriver)
m_avmShareNames.addString( curShare.getName());
if ( curShare.getInterface() instanceof AVMDiskDriver)
{
// Add the shared filesystem name to the list of AVM shares
m_avmShareNames.addString( curShare.getName());
// Set the AVM filesystem driver to be used when creating dynamic shares
if ( m_driver == null)
m_driver = (AVMDiskDriver) curShare.getInterface();
}
}
catch ( InvalidDeviceInterfaceException ex)
{
@@ -143,7 +158,7 @@ public class AVMShareMapper implements ShareMapper {
{
// Make a copy of the global share list and add the per session dynamic shares
SharedDeviceList shrList = new SharedDeviceList(m_config.getShares());
SharedDeviceList shrList = new SharedDeviceList(m_filesysConfig.getShares());
if ( sess != null && sess.hasDynamicShares()) {
@@ -176,14 +191,14 @@ public class AVMShareMapper implements ShareMapper {
// Find the required share by name/type. Use a case sensitive search first, if that fails use a case
// insensitive search.
SharedDevice share = m_config.getShares().findShare(name, typ, false);
SharedDevice share = m_filesysConfig.getShares().findShare(name, typ, false);
if ( share == null)
{
// Try a case insensitive search for the required share
share = m_config.getShares().findShare(name, typ, true);
share = m_filesysConfig.getShares().findShare(name, typ, true);
}
// If the share was not found then check if the share is in the AVM versioned share format - '<storename>_<version>'
@@ -238,12 +253,11 @@ public class AVMShareMapper implements ShareMapper {
if ( storePath.length() > 0 && storeVersion != -1)
{
// Validate the store name and version
// Validate the store name and version
AVMDiskDriver avmDrv = (AVMDiskDriver) m_config.getAvmDiskInterface();
AVMService avmService = avmDrv.getAvmService();
AVMService avmService = m_driver.getAvmService();
sess.beginReadTransaction( avmDrv.getTransactionService());
m_driver.beginReadTransaction( sess);
try
{
@@ -254,11 +268,11 @@ public class AVMShareMapper implements ShareMapper {
// Create a dynamic share mapped to the AVM store/version
AVMContext avmCtx = new AVMContext( name, storePath, storeVersion);
avmCtx.enableStateTable( true, avmDrv.getStateReaper());
avmCtx.enableStateTable( true, m_driver.getStateReaper());
// Create a dynamic shared device for the store version
DiskSharedDevice diskShare = new DiskSharedDevice( name, avmDrv, avmCtx, SharedDevice.Temporary);
DiskSharedDevice diskShare = new DiskSharedDevice( name, m_driver, avmCtx, SharedDevice.Temporary);
// Add the new share to the sessions dynamic share list

View File

@@ -23,9 +23,9 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
/**

View File

@@ -22,12 +22,13 @@
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
/**
* Dummy Folder Pseudo File Class

View File

@@ -23,12 +23,13 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFileList;
import org.alfresco.filesys.util.WildCard;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.jlan.util.WildCard;
/**
* Pseudo File List Search Context Class

View File

@@ -23,12 +23,12 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
/**

View File

@@ -23,12 +23,12 @@
package org.alfresco.filesys.avm;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFolderNetworkFile;
import org.alfresco.service.cmr.avm.VersionDescriptor;
/**

View File

@@ -25,12 +25,8 @@ package org.alfresco.filesys.avm;
import java.util.Hashtable;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFolderNetworkFile;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
import org.alfresco.service.cmr.repository.NodeRef;

View File

@@ -0,0 +1,83 @@
package org.alfresco.filesys.debug;
/*
* FileServerDebugInterface.java
*
* Copyright (c) 2007 Starlasoft. All rights reserved.
*/
import org.alfresco.config.ConfigElement;
import org.alfresco.jlan.debug.DebugInterface;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Alfresco File Server Debug Interface Class
*
* @author gkspencer
*/
public class FileServerDebugInterface implements DebugInterface {
// Logger to use for all file server debug output
private static final Log logger = LogFactory.getLog("org.alfresco.fileserver");
// temporary buffer for debugPrint
private StringBuilder m_printBuf;
/**
* Class constructor
*/
public FileServerDebugInterface() {
m_printBuf = new StringBuilder(120);
}
/**
* Close the debug output.
*/
public void close() {
}
/**
* Output a debug string.
*
* @param str java.lang.String
*/
public void debugPrint(String str) {
if ( logger.isDebugEnabled())
m_printBuf.append( str);
}
/**
* Output a debug string, and a newline.
*
* @param str java.lang.String
*/
public void debugPrintln(String str) {
if ( logger.isDebugEnabled()) {
// Check if there is any buffered output
if ( m_printBuf.length() > 0) {
m_printBuf.append( str);
logger.debug( m_printBuf.toString());
m_printBuf.setLength( 0);
}
else
logger.debug( str);
}
}
/**
* Initialize the debug interface using the specified named parameters.
*
* @param params ConfigElement
* @exception Exception
*/
public void initialize(ConfigElement params)
throws Exception {
// Nothing to do
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
/**
* FTP Command Types Class
*
* @author GKSpencer
*/
public class FTPCommand
{
// Command ids
public final static int User = 0;
public final static int Pass = 1;
public final static int Acct = 2;
public final static int Cwd = 3;
public final static int Cdup = 4;
public final static int Smnt = 5;
public final static int Rein = 6;
public final static int Quit = 7;
public final static int Port = 8;
public final static int Pasv = 9;
public final static int Type = 10;
public final static int Stru = 11;
public final static int Mode = 12;
public final static int Retr = 13;
public final static int Stor = 14;
public final static int Stou = 15;
public final static int Appe = 16;
public final static int Allo = 17;
public final static int Rest = 18;
public final static int Rnfr = 19;
public final static int Rnto = 20;
public final static int Abor = 21;
public final static int Dele = 22;
public final static int Rmd = 23;
public final static int Mkd = 24;
public final static int Pwd = 25;
public final static int List = 26;
public final static int Nlst = 27;
public final static int Site = 28;
public final static int Syst = 29;
public final static int Stat = 30;
public final static int Help = 31;
public final static int Noop = 32;
public final static int Mdtm = 33;
public final static int Size = 34;
public final static int Opts = 35;
public final static int Feat = 36;
public final static int XPwd = 37;
public final static int XMkd = 38;
public final static int XRmd = 39;
public final static int XCup = 40;
public final static int XCwd = 41;
public final static int MLst = 42;
public final static int MLsd = 43;
public final static int MaxId = 43;
public final static int InvalidCmd = -1;
// Command name strings
private static final String[] _cmds = { "USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT",
"PASV", "TYPE", "STRU", "MODE", "RETR", "STOR", "STOU", "APPE", "ALLO", "REST", "RNFR", "RNTO", "ABOR",
"DELE", "RMD", "MKD", "PWD", "LIST", "NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "SIZE",
"OPTS", "FEAT", "XPWD", "XMKD", "XRMD", "XCUP", "XCWD", "MLST", "MLSD" };
/**
* Convert an FTP command to an id
*
* @param cmd String
* @return int
*/
public final static int getCommandId(String cmd)
{
// Check if the command is valid
if (cmd == null)
return InvalidCmd;
// Convert to a command id
for (int i = 0; i <= MaxId; i++)
if (_cmds[i].equalsIgnoreCase(cmd))
return i;
// Command not found
return InvalidCmd;
}
/**
* Return the FTP command name for the specified id
*
* @param id int
* @return String
*/
public final static String getCommandName(int id)
{
if (id < 0 || id > MaxId)
return null;
return _cmds[id];
}
}

View File

@@ -1,982 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
import java.net.*;
import java.io.*;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.filesys.AccessMode;
import org.alfresco.filesys.server.filesys.DiskDeviceContext;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.FileAction;
import org.alfresco.filesys.server.filesys.FileOpenParams;
import org.alfresco.filesys.server.filesys.FileStatus;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.NotifyChange;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* FTP Data Session Class
* <p>
* A data connection is made when a PORT or PASV FTP command is received on the main control
* session.
* <p>
* The PORT command will actively connect to the specified address/port on the client. The PASV
* command will create a listening socket and wait for the client to connect.
*
* @author GKSpencer
*/
public class FTPDataSession extends SrvSession implements Runnable
{
// Debug logging
private static final Log logger = LogFactory.getLog("org.alfresco.ftp.protocol");
// Data session command types
public enum DataCommand { StoreFile, ReturnFile };
// FTP session that this data connection is associated with
private FTPSrvSession m_cmdSess;
// Connection details for active connection
private InetAddress m_clientAddr;
private int m_clientPort;
// Local port to use
private int m_localPort;
// Active data session socket
private Socket m_activeSock;
// Passive data session socket
private ServerSocket m_passiveSock;
// Transfer in progress and abort file transfer flags
private boolean m_transfer;
private boolean m_abort;
// Send/receive data byte count
private long m_bytCount;
// Data command type
private DataCommand m_dataCmd;
// Requested file name
private String m_reqFileName;
// Path to the local file
private FTPPath m_ftpPath;
// Restart position
private long m_restartPos;
// Thread that runs the data command
private Thread m_dataThread;
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection.
*
* @param sess FTPSrvSession
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection
m_passiveSock = new ServerSocket(0, 1, null);
}
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection on the specified network
* adapter and local port.
*
* @param sess FTPSrvSession
* @param localPort int
* @param addr InetAddress
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress bindAddr) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection on the specified network
// adapter
m_localPort = localPort;
m_passiveSock = new ServerSocket(localPort, 1, bindAddr);
}
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection on the specified network
* adapter.
*
* @param sess FTPSrvSession
* @param addr InetAddress
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress bindAddr) throws IOException
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection on the specified network
// adapter
m_passiveSock = new ServerSocket(0, 1, bindAddr);
}
/**
* Class constructor
* <p>
* Create a data connection to the specified client address and port.
*
* @param sess FTPSrvSession
* @param addr InetAddress
* @param port int
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress addr, int port)
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
// Save the client address/port details, the actual connection will be made later when
// the client requests/sends a file
m_clientAddr = addr;
m_clientPort = port;
}
/**
* Class constructor
* <p>
* Create a data connection to the specified client address and port, using the specified local
* port.
*
* @param sess FTPSrvSession
* @param localPort int
* @param addr InetAddress
* @param port int
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress addr, int port)
{
// Setup the base class
super( -1, sess.getServer(), "FTPDATA", null);
// Set the associated command session
m_cmdSess = sess;
// Save the local port
m_localPort = localPort;
// Save the client address/port details, the actual connection will be made later when
// the client requests/sends a file
m_clientAddr = addr;
m_clientPort = port;
}
/**
* Return the associated command session
*
* @return FTPSrvSession
*/
public final FTPSrvSession getCommandSession()
{
return m_cmdSess;
}
/**
* Return the local port
*
* @return int
*/
public final int getLocalPort()
{
if (m_passiveSock != null)
return m_passiveSock.getLocalPort();
else if (m_activeSock != null)
return m_activeSock.getLocalPort();
return -1;
}
/**
* Return the port that was allocated to the data session
*
* @return int
*/
protected final int getAllocatedPort()
{
return m_localPort;
}
/**
* Return the passive server socket address
*
* @return InetAddress
*/
public final InetAddress getPassiveAddress()
{
if (m_passiveSock != null)
{
// Get the server socket local address
InetAddress addr = m_passiveSock.getInetAddress();
if (addr.getHostAddress().compareTo("0.0.0.0") == 0)
{
try
{
addr = InetAddress.getLocalHost();
}
catch (UnknownHostException ex)
{
}
}
return addr;
}
return null;
}
/**
* Return the passive server socket port
*
* @return int
*/
public final int getPassivePort()
{
if (m_passiveSock != null)
return m_passiveSock.getLocalPort();
return -1;
}
/**
* Determine if a file transfer is active
*
* @return boolean
*/
public final boolean isTransferActive()
{
return m_transfer;
}
/**
* Determine if the transfer has been aborted
*
* @return boolean
*/
public final boolean isTransferAborted()
{
return m_abort;
}
/**
* Abort an in progress file transfer
*/
public final void abortTransfer()
{
m_abort = true;
}
/**
* Return the transfer byte count
*
* @return long
*/
public final synchronized long getTransferByteCount()
{
return m_bytCount;
}
/**
* Return the data socket connected to the client
*
* @return Socket
* @exception IOException
*/
public final Socket getSocket() throws IOException
{
// Check for a passive connection, get the incoming socket connection
if (m_passiveSock != null)
m_activeSock = m_passiveSock.accept();
else
{
if (m_localPort != 0)
{
// Use the specified local port
m_activeSock = new Socket(m_clientAddr, m_clientPort, null, m_localPort);
}
else
m_activeSock = new Socket(m_clientAddr, m_clientPort);
}
// Set the socket to close immediately
m_activeSock.setSoLinger(false, 0);
m_activeSock.setTcpNoDelay(true);
// Return the data socket
return m_activeSock;
}
/**
* Close the data connection
*/
public final void closeSession()
{
// If the data connection is active close it
if (m_activeSock != null)
{
try
{
m_activeSock.close();
}
catch (Exception ex)
{
}
m_activeSock = null;
}
// Close the listening socket for a passive connection
if (m_passiveSock != null)
{
try
{
m_passiveSock.close();
}
catch (Exception ex)
{
}
m_passiveSock = null;
}
// Commit, or rollback, any active user transaction
try
{
// Commit or rollback the transaction
endTransaction();
}
catch ( Exception ex)
{
// Debug
if ( logger.isDebugEnabled())
logger.debug("Error committing transaction", ex);
}
}
/**
* Store a file using a seperate thread to receive the data and write the file
*
* @param ftpPath FTPPath
*/
public final void doStoreFile( FTPPath ftpPath, long restartPos, String reqFileName)
{
// Set the transfer details
m_dataCmd = DataCommand.StoreFile;
m_ftpPath = ftpPath;
m_restartPos = restartPos;
m_reqFileName = reqFileName;
// Run the transfer in a seperate thread
m_dataThread = new Thread(this);
m_dataThread.setName(m_cmdSess.getUniqueId() + "_DATA_STORE");
m_dataThread.start();
}
/**
* Return a file using a seperate thread to read the file and send the data
*
* @param ftpPath FTPPath
*/
public final void doReturnFile( FTPPath ftpPath, long restartPos, String reqFileName)
{
// Set the transfer details
m_dataCmd = DataCommand.ReturnFile;
m_ftpPath = ftpPath;
m_restartPos = restartPos;
m_reqFileName = reqFileName;
// Run the transfer in a seperate thread
m_dataThread = new Thread(this);
m_dataThread.setName(m_cmdSess.getUniqueId() + "_DATA_RETURN");
m_dataThread.start();
}
/**
* Run a file send/receive in a seperate thread
*/
public void run()
{
// Setup the authentication context as we are running in a seperate thread from the main FTP session
try
{
// Setup the authentication context for the thread
m_cmdSess.authenticateDataSession();
// Run the required data command
switch ( m_dataCmd)
{
// Store a file
case StoreFile:
runStoreFile();
break;
// Return a file
case ReturnFile:
runReturnFile();
break;
}
}
catch ( org.alfresco.repo.security.authentication.AuthenticationException ex)
{
if ( logger.isErrorEnabled())
logger.error("Failed to authenticate FTP data session", ex);
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession(this);
closeSession();
}
}
/**
* Return a file to the client
*/
private final void runReturnFile()
{
// Send the file to the client
OutputStream os = null;
DiskInterface disk = null;
TreeConnection tree = null;
NetworkFile netFile = null;
Socket dataSock = null;
try
{
// Open an output stream to the client
dataSock = getSocket();
os = dataSock.getOutputStream();
// Create a temporary tree connection
tree = m_cmdSess.getTreeConnection(m_ftpPath.getSharedDevice());
// Check if the file exists and it is a file, if so then open the
// file
disk = (DiskInterface) m_ftpPath.getSharedDevice().getInterface();
// Create the file open parameters
FileOpenParams params = new FileOpenParams(m_ftpPath.getSharePath(), FileAction.OpenIfExists,
AccessMode.ReadOnly, 0);
// Check if the file exists and it is a file
int sts = disk.fileExists( this, tree, m_ftpPath.getSharePath());
if (sts == FileStatus.FileExists)
{
// Open the file
netFile = disk.openFile( this, tree, params);
}
// Commit any current transaction
try
{
// Commit or rollback the transaction
endTransaction();
}
catch ( Exception ex)
{
// Debug
if ( logger.isDebugEnabled())
logger.debug("Error committing transaction", ex);
}
// Check if the file has been opened
if (netFile == null)
{
m_cmdSess.sendFTPResponse(550, "File " + m_reqFileName + " not available");
return;
}
// Allocate the buffer for the file data
byte[] buf = new byte[FTPSrvSession.DEFAULT_BUFFERSIZE];
long filePos = m_restartPos;
int len = -1;
while (filePos < netFile.getFileSize())
{
// Read another block of data from the file
len = disk.readFile( this, tree, netFile, buf, 0, buf.length, filePos);
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Write len=" + len + " bytes");
// Write the current data block to the client, update the file position
if (len > 0)
{
// Write the data to the client
os.write(buf, 0, len);
// Update the file position
filePos += len;
// Update the transfer byte count
m_bytCount += len;
}
// Check if the transfer has been aborted
if ( isTransferAborted())
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILE))
logger.debug(" Transfer aborted (RETR)");
// Send a status to the client
sendFTPResponse( 226, "Aborted data connection");
// Finally block will cleanup
return;
}
}
// Close the output stream to the client
os.close();
os = null;
// Indicate that the file has been transmitted
sendFTPResponse(226, "Closing data connection");
// Close the data session
m_cmdSess.getFTPServer().releaseDataSession(this);
// Close the network file
disk.closeFile( this, tree, netFile);
netFile = null;
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Transfer complete, file closed");
}
catch (SocketException ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Data connection closed by client");
}
catch (Exception ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Error during transmission");
}
finally
{
try
{
// Close the network file
if (netFile != null && disk != null && tree != null)
disk.closeFile(m_cmdSess, tree, netFile);
// Close the output stream to the client
if (os != null)
os.close();
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession( this);
closeSession();
}
catch (Exception ex)
{
if ( logger.isErrorEnabled())
logger.error( "Error during FTP data session close", ex);
}
}
}
/**
* Store a file received from the client
*/
private final void runStoreFile()
{
// Store the file from the client
InputStream is = null;
DiskInterface disk = null;
TreeConnection tree = null;
NetworkFile netFile = null;
Socket dataSock = null;
try
{
// Create a temporary tree connection
tree = m_cmdSess.getTreeConnection(m_ftpPath.getSharedDevice());
// Check if the session has the required access to the filesystem
if (tree == null || tree.hasWriteAccess() == false)
{
// Session does not have write access to the filesystem
sendFTPResponse(550, "Access denied");
return;
}
// Check if the file exists
disk = (DiskInterface) m_ftpPath.getSharedDevice().getInterface();
int sts = disk.fileExists(this, tree, m_ftpPath.getSharePath());
if (sts == FileStatus.DirectoryExists)
{
// Return an error status
sendFTPResponse(500, "Invalid path (existing directory)");
return;
}
// Create the file open parameters
FileOpenParams params = new FileOpenParams(m_ftpPath.getSharePath(),
sts == FileStatus.FileExists ? FileAction.TruncateExisting : FileAction.CreateNotExist,
AccessMode.ReadWrite, 0);
// Create a new file to receive the data
if (sts == FileStatus.FileExists)
{
// Overwrite the existing file
netFile = disk.openFile(this, tree, params);
}
else
{
// Create a new file
netFile = disk.createFile(this, tree, params);
}
// Commit any current transaction
try
{
// Commit or rollback the transaction
endTransaction();
}
catch ( Exception ex)
{
// Debug
if ( logger.isDebugEnabled())
logger.debug("Error committing transaction", ex);
}
// Notify change listeners that a new file has been created
DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext();
if (diskCtx.hasChangeHandler())
diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, m_ftpPath.getSharePath());
// Send the intermediate response
sendFTPResponse(150, "File status okay, about to open data connection");
// Get the data connection socket
try
{
dataSock = getSocket();
}
catch (Exception ex)
{
}
if (dataSock == null)
{
sendFTPResponse(426, "Connection closed; transfer aborted");
return;
}
// Open an input stream from the client
is = dataSock.getInputStream();
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILE))
logger.debug("Storing ftp="
+ m_ftpPath.getFTPPath() + ", share=" + m_ftpPath.getShareName() + ", path="
+ m_ftpPath.getSharePath());
// Allocate the buffer for the file data
byte[] buf = new byte[FTPSrvSession.DEFAULT_BUFFERSIZE];
long filePos = 0;
int len = is.read(buf, 0, buf.length);
while (len > 0)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Receive len=" + len + " bytes");
// Write the current data block to the file, update the file
// position
disk.writeFile(this, tree, netFile, buf, 0, len, filePos);
filePos += len;
// Read another block of data from the client
len = is.read(buf, 0, buf.length);
}
// Close the input stream from the client
is.close();
is = null;
// Close the network file
disk.closeFile(this, tree, netFile);
netFile = null;
// Commit the transaction now before notifying the client that the transfer is finished
endTransaction();
// Indicate that the file has been received
sendFTPResponse(226, "Closing data connection");
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_FILEIO))
logger.debug(" Transfer complete, file closed");
}
catch (SocketException ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file data
sendFTPResponse(426, "Data connection closed by client");
}
catch (Exception ex)
{
// DEBUG
if (logger.isDebugEnabled() && m_cmdSess.hasDebug(FTPSrvSession.DBG_ERROR))
logger.debug(" Error during transfer", ex);
// Indicate that there was an error during transmission of the file
// data
sendFTPResponse(426, "Error during transmission");
}
finally
{
try
{
// Close the network file
if (netFile != null && disk != null && tree != null)
disk.closeFile( this, tree, netFile);
// Close the input stream to the client
if (is != null)
is.close();
// Close the data connection to the client
m_cmdSess.getFTPServer().releaseDataSession(this);
closeSession();
}
catch (Exception ex)
{
if ( logger.isErrorEnabled())
logger.error( "Error during FTP data session close", ex);
}
}
}
/**
* Send an FTP response to the client via the command session
*
* @param stsCode int
* @param msg String
*/
protected final void sendFTPResponse(int stsCode, String msg)
{
try
{
m_cmdSess.sendFTPResponse( stsCode, msg);
}
catch (Exception ex)
{
}
}
/**
* Return the client address
*
* @return InetAddress
*/
public InetAddress getRemoteAddress() {
return m_cmdSess.getRemoteAddress();
}
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* FTP Date Utility Class
*
* @author GKSpencer
*/
public class FTPDate
{
// Constants
//
// Six months in ticks
protected final static long SIX_MONTHS = 183L * 24L * 60L * 60L * 1000L;
// Month names
protected final static String[] _months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
"Nov", "Dec" };
// Machine listing date/time formatters
protected final static SimpleDateFormat _mlstFormat = new SimpleDateFormat( "yyyyMMddHHmmss");
protected final static SimpleDateFormat _mlstFormatLong = new SimpleDateFormat( "yyyyMMddHHmmss.SSS");
/**
* Pack a date string in Unix format The format is 'Mmm dd hh:mm' if the file is less than six
* months old, else the format is 'Mmm dd yyyy'.
*
* @param buf StringBuilder
* @param dt Date
*/
public final static void packUnixDate(StringBuilder buf, Date dt)
{
// Check if the date is valid
if (dt == null)
{
buf.append("------------");
return;
}
// Get the time raw value
long timeVal = dt.getTime();
if (timeVal < 0)
{
buf.append("------------");
return;
}
// Add the month name and date parts to the string
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
buf.append(_months[cal.get(Calendar.MONTH)]);
buf.append(" ");
int dayOfMonth = cal.get(Calendar.DATE);
if (dayOfMonth < 10)
buf.append(" ");
buf.append(dayOfMonth);
buf.append(" ");
// If the file is less than six months old we append the file time, else we append the year
long timeNow = System.currentTimeMillis();
if (Math.abs(timeNow - timeVal) > SIX_MONTHS)
{
// Append the year
buf.append(cal.get(Calendar.YEAR));
}
else
{
// Append the file time as hh:mm
int hr = cal.get(Calendar.HOUR_OF_DAY);
if (hr < 10)
buf.append("0");
buf.append(hr);
buf.append(":");
int min = cal.get(Calendar.MINUTE);
if (min < 10)
buf.append("0");
buf.append(min);
}
}
/**
* Return a machine listing date/time, in the format 'YYYYMMDDHHSS'.
*
* @param dateTime long
* @return String
*/
public final static String packMlstDateTime( long dateTime)
{
long dst = TimeZone.getDefault().getDSTSavings();
return _mlstFormat.format( new Date( dateTime - dst));
}
/**
* Return a machine listing date/time, in the format 'YYYYMMDDHHSS.sss'.
*
* @param dateTime long
* @return String
*/
public final static String packMlstDateTimeLong( long dateTime)
{
long dst = TimeZone.getDefault().getDSTSavings();
return _mlstFormatLong.format( new Date( dateTime - dst));
}
}

View File

@@ -1,649 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import org.alfresco.filesys.server.ServerListener;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.core.SharedDeviceList;
import org.alfresco.filesys.server.filesys.NetworkFileServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <p>
* Create an FTP server on the specified port. The default server port is 21.
*
* @author GKSpencer
*/
public class FTPNetworkServer extends NetworkFileServer implements Runnable
{
// Debug logging
private static final Log logger = LogFactory.getLog("org.alfresco.ftp.protocol");
// Constants
//
// Session Thread group
private static final ThreadGroup THREAD_GROUP_SESSION = new ThreadGroup("FTP_SESSION_GROUP");
// Listen backlog for the server socket
protected static final int LISTEN_BACKLOG = 10;
// Default FTP server port
protected static final int SERVER_PORT = 21;
// Server socket
private ServerSocket m_srvSock;
// Active session list
private FTPSessionList m_sessions;
// List of available shares
private SharedDeviceList m_shares;
// Next available session id
private int m_sessId;
// Root path for new sessions
private FTPPath m_rootPath;
// FTP server thread
private Thread m_srvThread;
// Local server address string, in FTP format (ie. n,n,n,n)
private String m_localFTPaddress;
// SITE command interface
private FTPSiteInterface m_siteInterface;
// Default character encoding to use for file names
private String m_charSet;
/**
* Class constructor
*
* @param serviceResgistry ServiceRegistry
* @param config ServerConfiguration
*/
public FTPNetworkServer(ServerConfiguration config)
{
super("FTP", config);
// Allocate the session lists
m_sessions = new FTPSessionList();
// Enable debug
if (getConfiguration().getFTPDebug() != 0)
setDebug(true);
// Create the root path, if configured
if (getConfiguration().hasFTPRootPath())
{
try
{
// Create the root path
m_rootPath = new FTPPath(getConfiguration().getFTPRootPath());
}
catch (InvalidPathException ex)
{
logger.error(ex);
}
}
// Set the default character set
m_charSet = config.getFTPCharacterSet();
if ( m_charSet == null)
m_charSet = Charset.defaultCharset().name();
}
/**
* Add a new session to the server
*
* @param sess FTPSrvSession
*/
protected final void addSession(FTPSrvSession sess)
{
// Add the session to the session list
m_sessions.addSession(sess);
// Propagate the debug settings to the new session
if (hasDebug())
{
// Enable session debugging, output to the same stream as the server
sess.setDebug(getConfiguration().getFTPDebug());
}
}
/**
* emove a session from the server
*
* @param sess FTPSrvSession
*/
protected final void removeSession(FTPSrvSession sess)
{
// Remove the session from the active session list
if (m_sessions.removeSession(sess) != null)
{
// Inform listeners that a session has closed
fireSessionClosedEvent(sess);
}
}
/**
* Allocate a local port for a data session
*
* @param sess FTPSrvSession
* @param remAddr InetAddress
* @param remPort int
* @return FTPDataSession
* @exception IOException
*/
protected final FTPDataSession allocateDataSession(FTPSrvSession sess, InetAddress remAddr, int remPort)
throws IOException
{
// Create a new FTP data session
FTPDataSession dataSess = null;
if (remAddr != null)
{
// Create a normal data session
dataSess = new FTPDataSession(sess, remAddr, remPort);
}
else
{
// Create a passive data session
dataSess = new FTPDataSession(sess, getBindAddress());
}
// Return the data session
return dataSess;
}
/**
* Release a data session
*
* @param dataSess FTPDataSession
*/
protected final void releaseDataSession(FTPDataSession dataSess)
{
// Close the data session
dataSess.closeSession();
}
/**
* Get the shared device list
*
* @return SharedDeviceList
*/
public final SharedDeviceList getShareList()
{
// Check if the share list has been populated
if (m_shares == null)
m_shares = getConfiguration().getShareMapper()
.getShareList(getConfiguration().getServerName(), null, false);
// Return the share list
return m_shares;
}
/**
* Check if the FTP server is to be bound to a specific network adapter
*
* @return boolean
*/
public final boolean hasBindAddress()
{
return getConfiguration().getFTPBindAddress() != null ? true : false;
}
/**
* Return the address that the FTP server should bind to
*
* @return InetAddress
*/
public final InetAddress getBindAddress()
{
return getConfiguration().getFTPBindAddress();
}
/**
* Check if the root path is set
*
* @return boolean
*/
public final boolean hasRootPath()
{
return m_rootPath != null ? true : false;
}
/**
* Check if anonymous logins are allowed
*
* @return boolean
*/
public final boolean allowAnonymous()
{
return getConfiguration().allowAnonymousFTP();
}
/**
* Return the anonymous login user name
*
* @return String
*/
public final String getAnonymousAccount()
{
return getConfiguration().getAnonymousFTPAccount();
}
/**
* Return the local FTP server address string in n,n,n,n format
*
* @return String
*/
public final String getLocalFTPAddressString()
{
return m_localFTPaddress;
}
/**
* Return the next available session id
*
* @return int
*/
protected final synchronized int getNextSessionId()
{
return m_sessId++;
}
/**
* Return the FTP server port
*
* @return int
*/
public final int getPort()
{
return getConfiguration().getFTPPort();
}
/**
* Return the server socket
*
* @return ServerSocket
*/
protected final ServerSocket getSocket()
{
return m_srvSock;
}
/**
* Return the root path for new sessions
*
* @return FTPPath
*/
public final FTPPath getRootPath()
{
return m_rootPath;
}
/**
* Get the character set to use for file name encoding/decoding
*
* @return String
*/
public final String getCharacterSet()
{
return m_charSet;
}
/**
* Notify the server that a user has logged on.
*
* @param sess SrvSession
*/
protected final void sessionLoggedOn(SrvSession sess)
{
// Notify session listeners that a user has logged on.
fireSessionLoggedOnEvent(sess);
}
/**
* Start the SMB server.
*/
public void run()
{
// Debug
if (logger.isDebugEnabled() && hasDebug())
{
logger.debug("FTP Server starting on port " + getPort());
if ( getCharacterSet() != null)
logger.debug( "Using character set " + getCharacterSet());
}
// Create a server socket to listen for incoming FTP session requests
try
{
// Create the server socket to listen for incoming FTP session requests
if (hasBindAddress())
m_srvSock = new ServerSocket(getPort(), LISTEN_BACKLOG, getBindAddress());
else
m_srvSock = new ServerSocket(getPort(), LISTEN_BACKLOG);
// DEBUG
if (logger.isDebugEnabled() && hasDebug())
{
String ftpAddr = "ALL";
if (hasBindAddress())
ftpAddr = getBindAddress().getHostAddress();
logger.debug("FTP Binding to local address " + ftpAddr);
}
// If a bind address is set then we can set the FTP local address
if (hasBindAddress())
m_localFTPaddress = getBindAddress().getHostAddress().replace('.', ',');
// Indicate that the server is active
setActive(true);
fireServerEvent(ServerListener.ServerActive);
// Wait for incoming connection requests
while (hasShutdown() == false)
{
// Wait for a connection
Socket sessSock = getSocket().accept();
// Set the local address string in FTP format (n,n,n,n), if not already set
if (m_localFTPaddress == null)
{
if (sessSock.getLocalAddress() != null)
m_localFTPaddress = sessSock.getLocalAddress().getHostAddress().replace('.', ',');
}
// Set socket options
sessSock.setTcpNoDelay(true);
// Debug
if (logger.isDebugEnabled() && hasDebug())
logger.debug("FTP session request received from "
+ sessSock.getInetAddress().getHostAddress());
// Create a server session for the new request, and set the session id.
FTPSrvSession srvSess = new FTPSrvSession(sessSock, this);
srvSess.setSessionId(getNextSessionId());
srvSess.setUniqueId("FTP" + srvSess.getSessionId());
// Initialize the root path for the new session, if configured
if (hasRootPath())
srvSess.setRootPath(getRootPath());
// Add the session to the active session list
addSession(srvSess);
// Inform listeners that a new session has been created
fireSessionOpenEvent(srvSess);
// Start the new session in a seperate thread
Thread srvThread = new Thread(THREAD_GROUP_SESSION, srvSess);
srvThread.setDaemon(true);
srvThread.setName("Sess_FTP" + srvSess.getSessionId() + "_"
+ sessSock.getInetAddress().getHostAddress());
srvThread.start();
// Sleep for a while
try
{
Thread.sleep(1000L);
}
catch (InterruptedException ex)
{
}
}
}
catch (SocketException ex)
{
// Do not report an error if the server has shutdown, closing the server socket
// causes an exception to be thrown.
if (hasShutdown() == false)
{
logger.error("FTP Socket error", ex);
// Inform listeners of the error, store the exception
setException(ex);
fireServerEvent(ServerListener.ServerError);
}
}
catch (Exception ex)
{
// Do not report an error if the server has shutdown, closing the server socket
// causes an exception to be thrown.
if (hasShutdown() == false)
{
logger.error("FTP Server error", ex);
}
// Inform listeners of the error, store the exception
setException(ex);
fireServerEvent(ServerListener.ServerError);
}
// Close the active sessions
Enumeration enm = m_sessions.enumerate();
while (enm.hasMoreElements())
{
// Get the session id and associated session
Integer sessId = (Integer) enm.nextElement();
FTPSrvSession sess = m_sessions.findSession(sessId);
// DEBUG
if (logger.isDebugEnabled() && hasDebug())
logger.debug("FTP Close session, id = " + sess.getSessionId());
// Close the session
sess.closeSession();
}
// Debug
if (logger.isDebugEnabled() && hasDebug())
logger.debug("FTP Server shutting down ...");
// Indicate that the server has shutdown, inform listeners
setActive(false);
fireServerEvent(ServerListener.ServerShutdown);
}
/**
* Shutdown the FTP server
*
* @param immediate boolean
*/
public void shutdownServer(boolean immediate)
{
// Set the shutdown flag
setShutdown(true);
// Close the FTP server listening socket to wakeup the main FTP server thread
try
{
if (getSocket() != null)
getSocket().close();
}
catch (IOException ex)
{
}
// Wait for the main server thread to close
if (m_srvThread != null)
{
try
{
m_srvThread.join(3000);
}
catch (Exception ex)
{
}
}
// Fire a shutdown notification event
fireServerEvent(ServerListener.ServerShutdown);
}
/**
* Start the FTP server in a seperate thread
*/
public void startServer()
{
// Create a seperate thread to run the FTP server
m_srvThread = new Thread(this);
m_srvThread.setName("FTP Server");
m_srvThread.start();
// Fire a server startup event
fireServerEvent(ServerListener.ServerStartup);
}
/**
* Check if the site interface is valid
*
* @return boolean
*/
public final boolean hasSiteInterface()
{
return m_siteInterface != null ? true : false;
}
/**
* Return the site interface
*
* @return FTPSiteInterface
*/
public final FTPSiteInterface getSiteInterface()
{
return m_siteInterface;
}
/**
* Set the site specific commands interface
*
* @param siteInterface FTPSiteInterface
*/
public final void setSiteInterface( FTPSiteInterface siteInterface)
{
m_siteInterface = siteInterface;
}
}

View File

@@ -1,600 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
import org.alfresco.filesys.server.filesys.*;
import org.alfresco.filesys.server.core.*;
/**
* FTP Path Class
* <p>
* Converts FTP paths to share/share relative paths.
*
* @author GKSpencer
*/
public class FTPPath
{
// FTP directory seperator
private static final String FTP_SEPERATOR = "/";
private static final char FTP_SEPERATOR_CHAR = '/';
// Share relative path directory seperator
private static final String DIR_SEPERATOR = "\\";
private static final char DIR_SEPERATOR_CHAR = '\\';
// FTP path
private String m_ftpPath;
// Share name nad share relative path
private String m_shareName;
private String m_sharePath;
// Shared device
private DiskSharedDevice m_shareDev;
// Flag to indicate if this is a directory or file path
private boolean m_dir = true;
/**
* Default constructor
*/
public FTPPath()
{
try
{
setFTPPath(null);
}
catch (Exception ex)
{
}
}
/**
* Class constructor
*
* @param ftpPath String
* @exception InvalidPathException
*/
public FTPPath(String ftpPath) throws InvalidPathException
{
setFTPPath(ftpPath);
}
/**
* Class constructor
*
* @param shrName String
* @param shrPath String
* @exception InvalidPathException
*/
public FTPPath(String shrName, String shrPath) throws InvalidPathException
{
setSharePath(shrName, shrPath);
}
/**
* Copy constructor
*
* @param ftpPath FTPPath
*/
public FTPPath(FTPPath ftpPath)
{
try
{
setFTPPath(ftpPath.getFTPPath());
m_shareDev = ftpPath.getSharedDevice();
}
catch (Exception ex)
{
}
}
/**
* Determine if the current FTP path is the root path
*
* @return boolean
*/
public final boolean isRootPath()
{
return m_ftpPath.compareTo(FTP_SEPERATOR) == 0 ? true : false;
}
/**
* Determine if the path is for a directory or file
*
* @return boolean
*/
public final boolean isDirectory()
{
return m_dir;
}
/**
* Check if the FTP path is valid
*
* @return boolean
*/
public final boolean hasFTPPath()
{
return m_ftpPath != null ? true : false;
}
/**
* Return the FTP path
*
* @return String
*/
public final String getFTPPath()
{
return m_ftpPath;
}
/**
* Check if the share name is valid
*
* @return boolean
*/
public final boolean hasShareName()
{
return m_shareName != null ? true : false;
}
/**
* Return the share name
*
* @return String
*/
public final String getShareName()
{
return m_shareName;
}
/**
* Check if the share path is the root path
*
* @return boolean
*/
public final boolean isRootSharePath()
{
if (m_sharePath == null || m_sharePath.compareTo(DIR_SEPERATOR) == 0)
return true;
return false;
}
/**
* Check if the share path is valid
*
* @reutrn boolean
*/
public final boolean hasSharePath()
{
return m_sharePath != null ? true : false;
}
/**
* Return the share relative path
*
* @reutrn String
*/
public final String getSharePath()
{
return m_sharePath;
}
/**
* Check if the shared device has been set
*
* @return boolean
*/
public final boolean hasSharedDevice()
{
return m_shareDev != null ? true : false;
}
/**
* Return the shared device
*
* @return DiskSharedDevice
*/
public final DiskSharedDevice getSharedDevice()
{
return m_shareDev;
}
/**
* Set the paths using the specified FTP path
*
* @param path String
* @exception InvalidPathException
*/
public final void setFTPPath(String path) throws InvalidPathException
{
// Check for a null path or the root path
if (path == null || path.length() == 0 || path.compareTo(FTP_SEPERATOR) == 0)
{
m_ftpPath = FTP_SEPERATOR;
m_shareName = null;
m_sharePath = null;
m_shareDev = null;
return;
}
// Check if the path starts with the FTP seperator
if (path.startsWith(FTP_SEPERATOR) == false)
throw new InvalidPathException("Invalid FTP path, should start with " + FTP_SEPERATOR);
// Save the FTP path
m_ftpPath = path;
// Get the first level directory from the path, this maps to the share name
int pos = path.indexOf(FTP_SEPERATOR, 1);
if (pos != -1)
{
m_shareName = path.substring(1, pos);
if (path.length() > pos)
m_sharePath = path.substring(pos).replace(FTP_SEPERATOR_CHAR, DIR_SEPERATOR_CHAR);
else
m_sharePath = DIR_SEPERATOR;
}
else
{
m_shareName = path.substring(1);
m_sharePath = DIR_SEPERATOR;
}
// Check if the share has changed
if (m_shareDev != null && m_shareName != null && m_shareDev.getName().compareTo(m_shareName) != 0)
m_shareDev = null;
}
/**
* Set the paths using the specified share and share relative path
*
* @param shr String
* @param path String
* @exception InvalidPathException
*/
public final void setSharePath(String shr, String path) throws InvalidPathException
{
// Save the share name and path
m_shareName = shr;
m_sharePath = path != null ? path : DIR_SEPERATOR;
// Build the FTP style path
StringBuffer ftpPath = new StringBuffer();
ftpPath.append(FTP_SEPERATOR);
if (hasShareName())
ftpPath.append(getShareName());
if (hasSharePath())
{
// Convert the share relative path to an FTP style path
String ftp = getSharePath().replace(DIR_SEPERATOR_CHAR, FTP_SEPERATOR_CHAR);
ftpPath.append(ftp);
}
else
ftpPath.append(FTP_SEPERATOR);
// Update the FTP path
m_ftpPath = ftpPath.toString();
}
/**
* Set the shared device
*
* @param shareList SharedDeviceList
* @param sess FTPSrvSession
* @return boolean
*/
public final boolean setSharedDevice(SharedDeviceList shareList, FTPSrvSession sess)
{
// Clear the current shared device
m_shareDev = null;
// Check if the share name is valid
if (hasShareName() == false || shareList == null)
return false;
// Find the required disk share
SharedDevice shr = shareList.findShare(getShareName());
if (shr != null && shr instanceof DiskSharedDevice)
m_shareDev = (DiskSharedDevice) shr;
// Return the status
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
*
* @param fname String
* @return String
*/
public final String makeFTPPathToFile(String fname)
{
// Build the FTP path to a file
StringBuffer path = new StringBuffer(256);
path.append(m_ftpPath);
if (m_ftpPath.endsWith(FTP_SEPERATOR) == false)
path.append(FTP_SEPERATOR);
path.append(fname);
return path.toString();
}
/**
* Build a share relative path to the specified file
*
* @param fname String
* @return String
*/
public final String makeSharePathToFile(String fname)
{
// Build the share relative path to a file
StringBuilder path = new StringBuilder(256);
path.append(m_sharePath);
if (m_sharePath.endsWith(DIR_SEPERATOR) == false)
path.append(DIR_SEPERATOR);
path.append(fname);
return path.toString();
}
/**
* Add a directory to the end of the current path
*
* @param dir String
*/
public final void addDirectory(String dir)
{
// Check if the directory has a trailing seperator
if (dir.length() > 1 && dir.endsWith(FTP_SEPERATOR) || dir.endsWith(DIR_SEPERATOR))
dir = dir.substring(0, dir.length() - 1);
// Append the directory to the FTP path
StringBuilder str = new StringBuilder(256);
str.append(m_ftpPath);
if (m_ftpPath.endsWith(FTP_SEPERATOR) == false)
str.append(FTP_SEPERATOR);
str.append(dir);
if (m_ftpPath.endsWith(FTP_SEPERATOR) == false)
str.append(FTP_SEPERATOR);
m_ftpPath = str.toString();
// Check if there are any incorrect seperators in the FTP path
if (m_ftpPath.indexOf(DIR_SEPERATOR) != -1)
m_ftpPath = m_ftpPath.replace(FTP_SEPERATOR_CHAR, DIR_SEPERATOR_CHAR);
// Append the directory to the share relative path
str.setLength(0);
str.append(m_sharePath);
if (m_sharePath.endsWith(DIR_SEPERATOR) == false)
str.append(DIR_SEPERATOR);
str.append(dir);
m_sharePath = str.toString();
// Check if there are any incorrect seperators in the share relative path
if (m_sharePath.indexOf(FTP_SEPERATOR) != -1)
m_sharePath = m_sharePath.replace(FTP_SEPERATOR_CHAR, DIR_SEPERATOR_CHAR);
// Indicate that the path is to a directory
setDirectory(true);
}
/**
* Add a file to the end of the current path
*
* @param file String
*/
public final void addFile(String file)
{
// Append the file name to the FTP path
StringBuilder str = new StringBuilder(256);
str.append(m_ftpPath);
if (m_ftpPath.endsWith(FTP_SEPERATOR) == false)
str.append(FTP_SEPERATOR);
str.append(file);
m_ftpPath = str.toString();
// Check if there are any incorrect seperators in the FTP path
if (m_ftpPath.indexOf(DIR_SEPERATOR) != -1)
m_ftpPath = m_ftpPath.replace(FTP_SEPERATOR_CHAR, DIR_SEPERATOR_CHAR);
// Append the file name to the share relative path
str.setLength(0);
str.append(m_sharePath);
if (m_sharePath.endsWith(DIR_SEPERATOR) == false)
str.append(DIR_SEPERATOR);
str.append(file);
m_sharePath = str.toString();
// Check if there are any incorrect seperators in the share relative path
if (m_sharePath.indexOf(FTP_SEPERATOR) != -1)
m_sharePath = m_sharePath.replace(FTP_SEPERATOR_CHAR, DIR_SEPERATOR_CHAR);
// Indicate that the path is to a file
setDirectory(false);
}
/**
* Remove the last directory from the end of the path
*/
public final void removeDirectory()
{
// Check if the FTP path has a directory to remove
if (m_ftpPath != null && m_ftpPath.length() > 1)
{
// Find the last directory in the FTP path
int pos = m_ftpPath.length() - 1;
if (m_ftpPath.endsWith(FTP_SEPERATOR))
pos--;
while (pos > 0 && m_ftpPath.charAt(pos) != FTP_SEPERATOR_CHAR)
pos--;
// Set the new FTP path
m_ftpPath = m_ftpPath.substring(0, pos);
// Indicate that the path is to a directory
setDirectory(true);
// Reset the share/share path
try
{
setFTPPath(m_ftpPath);
}
catch (InvalidPathException ex)
{
}
}
}
/**
* Set/clear the directory path flag
*
* @param dir boolean
*/
protected final void setDirectory(boolean dir)
{
m_dir = dir;
}
/**
* Check if an FTP path string contains multiple directories
*
* @param path String
* @return boolean
*/
public final static boolean hasMultipleDirectories(String path)
{
if (path == null)
return false;
if (path.startsWith(FTP_SEPERATOR))
return true;
return false;
}
/**
* Check if the FTP path is a relative path, ie. does not start with a leading slash
*
* @param path String
* @return boolean
*/
public final static boolean isRelativePath(String path)
{
if (path == null)
return false;
return path.startsWith(FTP_SEPERATOR) ? false : true;
}
/**
* Return the FTP path as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("[");
str.append(getFTPPath());
str.append("=");
str.append(getShareName());
str.append(",");
str.append(getSharePath());
str.append("]");
return str.toString();
}
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
/**
* FTP Request Class
* <p>
* Contains the details of an FTP request
*
* @author GKSpencer
*/
public class FTPRequest
{
// FTP command id
private int m_cmd;
// Command argument
private String m_arg;
/**
* Default constructor
*/
public FTPRequest()
{
m_cmd = FTPCommand.InvalidCmd;
}
/**
* Class constructor
*
* @param cmd int
* @param arg String
*/
public FTPRequest(int cmd, String arg)
{
m_cmd = cmd;
m_arg = arg;
}
/**
* Class constructor
*
* @param cmdLine String
*/
public FTPRequest(String cmdLine)
{
// Parse the FTP command record
parseCommandLine(cmdLine);
}
/**
* Return the command index
*
* @return int
*/
public final int isCommand()
{
return m_cmd;
}
/**
* Check if the request has an argument
*
* @return boolean
*/
public final boolean hasArgument()
{
return m_arg != null ? true : false;
}
/**
* Return the request argument
*
* @return String
*/
public final String getArgument()
{
return m_arg;
}
/**
* Set the command line for the request
*
* @param cmdLine String
* @return int
*/
public final int setCommandLine(String cmdLine)
{
// Reset the current values
m_cmd = FTPCommand.InvalidCmd;
m_arg = null;
// Parse the new command line
parseCommandLine(cmdLine);
return isCommand();
}
/**
* Parse a command string
*
* @param cmdLine String
*/
protected final void parseCommandLine(String cmdLine)
{
// Check if the command has an argument
int pos = cmdLine.indexOf(' ');
String cmd = null;
if (pos != -1)
{
cmd = cmdLine.substring(0, pos);
m_arg = cmdLine.substring(pos + 1);
}
else
cmd = cmdLine;
// Validate the FTP command
m_cmd = FTPCommand.getCommandId(cmd);
}
/**
* Update the command argument
*
* @param arg String
*/
protected final void updateArgument(String arg)
{
m_arg = arg;
}
/**
* Return the request as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("[");
str.append(FTPCommand.getCommandName(m_cmd));
str.append(":");
str.append(m_arg);
str.append("]");
return str.toString();
}
}

View File

@@ -1,141 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
import java.util.*;
/**
* FTP Server Session List Class
*
* @author GKSpencer
*/
public class FTPSessionList
{
// Session list
private Hashtable<Integer, FTPSrvSession> m_sessions;
/**
* Class constructor
*/
public FTPSessionList()
{
m_sessions = new Hashtable<Integer, FTPSrvSession>();
}
/**
* Return the number of sessions in the list
*
* @return int
*/
public final int numberOfSessions()
{
return m_sessions.size();
}
/**
* Add a session to the list
*
* @param sess FTPSrvSession
*/
public final void addSession(FTPSrvSession sess)
{
m_sessions.put(new Integer(sess.getSessionId()), sess);
}
/**
* Find the session using the unique session id
*
* @param id int
* @return FTPSrvSession
*/
public final FTPSrvSession findSession(int id)
{
return findSession(new Integer(id));
}
/**
* Find the session using the unique session id
*
* @param id Integer
* @return FTPSrvSession
*/
public final FTPSrvSession findSession(Integer id)
{
return m_sessions.get(id);
}
/**
* Remove a session from the list
*
* @param id int
* @return FTPSrvSession
*/
public final FTPSrvSession removeSession(int id)
{
return removeSession(new Integer(id));
}
/**
* Remove a session from the list
*
* @param sess FTPSrvSession
* @return FTPSrvSession
*/
public final FTPSrvSession removeSession(FTPSrvSession sess)
{
return removeSession(sess.getSessionId());
}
/**
* Remove a session from the list
*
* @param id Integer
* @return FTPSrvSession
*/
public final FTPSrvSession removeSession(Integer id)
{
// Find the required session
FTPSrvSession sess = findSession(id);
// Remove the session and return the removed session
m_sessions.remove(id);
return sess;
}
/**
* Enumerate the session ids
*
* @return Enumeration
*/
public final Enumeration enumerate()
{
return m_sessions.keys();
}
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.ftp;
/**
* FTP SITE Command Interface
*
* <p>Optional interface that is used to provide processing for the FTP SITE command.
*/
public interface FTPSiteInterface {
/**
* Process an FTP SITE specific command
*
* @param sess FTPSrvSession
* @param req FTPRequest
*/
void processFTPSiteCommand( FTPSrvSession sess, FTPRequest req);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.ftp;
/**
* Invalid FTP Path Exception Class
*
* @author GKSpencer
*/
public class InvalidPathException extends Exception {
private static final long serialVersionUID = -3298943582077910226L;
/**
* Default constructor
*/
public InvalidPathException() {
super();
}
/**
* Class constructor
*
* @param msg String
*/
public InvalidPathException(String msg) {
super(msg);
}
}

View File

@@ -1,195 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
/**
* File Lock Class
* <p>
* Contains the details of a single file lock.
*/
public class FileLock
{
// Constants
public static final long LockWholeFile = 0xFFFFFFFFFFFFFFFFL;
// Start lock offset and length
private long m_offset;
private long m_length;
// Owner process id
private int m_pid;
/**
* Class constructor
*
* @param offset long
* @param len long
* @param pid int
*/
public FileLock(long offset, long len, int pid)
{
setOffset(offset);
setLength(len);
setProcessId(pid);
}
/**
* Get the starting lock offset
*
* @return long Starting lock offset.
*/
public final long getOffset()
{
return m_offset;
}
/**
* Set the starting lock offset.
*
* @param long Starting lock offset
*/
public final void setOffset(long offset)
{
m_offset = offset;
}
/**
* Get the locked section length
*
* @return long Locked section length
*/
public final long getLength()
{
return m_length;
}
/**
* Set the locked section length
*
* @param long Locked section length
*/
public final void setLength(long len)
{
if (len < 0)
m_length = LockWholeFile;
else
m_length = len;
}
/**
* Get the owner process id for the lock
*
* @return int
*/
public final int getProcessId()
{
return m_pid;
}
/**
* Deterine if the lock is locking the whole file
*
* @return boolean
*/
public final boolean isWholeFile()
{
return m_length == LockWholeFile ? true : false;
}
/**
* Set the process id of the owner of this lock
*
* @param pid int
*/
public final void setProcessId(int pid)
{
m_pid = pid;
}
/**
* Check if the specified locks byte range overlaps this locks byte range.
*
* @param lock FileLock
*/
public final boolean hasOverlap(FileLock lock)
{
return hasOverlap(lock.getOffset(), lock.getLength());
}
/**
* Check if the specified locks byte range overlaps this locks byte range.
*
* @param offset long
* @param len long
*/
public final boolean hasOverlap(long offset, long len)
{
// Check if the lock is for the whole file
if ( isWholeFile())
return true;
// Check if the locks overlap
long endOff = getOffset() + ( getLength() - 1);
if (getOffset() < offset && endOff < offset)
return false;
endOff = offset + ( len - 1);
if ( getOffset() > endOff)
return false;
// Locks overlap
return true;
}
/**
* Return the lock details as a string
*
* @return String
*/
public String toString()
{
StringBuffer str = new StringBuffer();
str.append("[PID=");
str.append(getProcessId());
str.append(",Offset=");
str.append(getOffset());
str.append(",Len=");
str.append(getLength());
str.append("]");
return str.toString();
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
import java.io.IOException;
/**
* File Lock Exception Class
*/
public class FileLockException extends IOException
{
private static final long serialVersionUID = 3257845472092893751L;
/**
* Class constructor.
*/
public FileLockException()
{
super();
}
/**
* Class constructor.
*
* @param s java.lang.String
*/
public FileLockException(String s)
{
super(s);
}
}

View File

@@ -1,254 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
import java.util.Vector;
/**
* File Lock List Class
* <p>
* Contains a list of the current locks on a file.
*/
public class FileLockList
{
// List of file locks
private Vector<FileLock> m_lockList;
/**
* Construct an empty file lock list.
*/
public FileLockList()
{
m_lockList = new Vector<FileLock>();
}
/**
* Add a lock to the list
*
* @param lock Lock to be added to the list.
*/
public final void addLock(FileLock lock)
{
m_lockList.add(lock);
}
/**
* Remove a lock from the list
*
* @param lock FileLock
* @return FileLock
*/
public final FileLock removeLock(FileLock lock)
{
return removeLock(lock.getOffset(), lock.getLength(), lock.getProcessId());
}
/**
* Remove a lock from the list
*
* @param long offset Starting offset of the lock
* @param long len Locked section length
* @param int pid Owner process id
* @return FileLock
*/
public final FileLock removeLock(long offset, long len, int pid)
{
// Check if there are any locks in the list
if (numberOfLocks() == 0)
return null;
// Search for the required lock
for (int i = 0; i < numberOfLocks(); i++)
{
// Get the current lock details
FileLock curLock = getLockAt(i);
if (curLock.getOffset() == offset && curLock.getLength() == len && curLock.getProcessId() == pid)
{
// Remove the lock from the list
m_lockList.removeElementAt(i);
return curLock;
}
}
// Lock not found
return null;
}
/**
* Remove all locks from the list
*/
public final void removeAllLocks()
{
m_lockList.removeAllElements();
}
/**
* Return the specified lock details
*
* @param int Lock index
* @return FileLock
*/
public final FileLock getLockAt(int idx)
{
if (idx < m_lockList.size())
return m_lockList.elementAt(idx);
return null;
}
/**
* Check if the new lock should be allowed by comparing with the locks in the list.
*
* @param lock FileLock
* @return boolean true if the lock can be granted, else false.
*/
public final boolean allowsLock(FileLock lock)
{
// If the list is empty we can allow the lock request
if (numberOfLocks() == 0)
return true;
// Search for any overlapping locks
for (int i = 0; i < numberOfLocks(); i++)
{
// Get the current lock details
FileLock curLock = getLockAt(i);
if (curLock.hasOverlap(lock))
return false;
}
// The lock does not overlap with any existing locks
return true;
}
/**
* Check if the file is readable for the specified section of the file and process id
*
* @param offset long
* @param len long
* @param pid int
* @return boolean
*/
public final boolean canReadFile(long offset, long len, int pid)
{
// If the list is empty we can allow the read request
if (numberOfLocks() == 0)
return true;
// Search for a lock that prevents the read
for (int i = 0; i < numberOfLocks(); i++)
{
// Get the current lock details
FileLock curLock = getLockAt(i);
// Check if the process owns the lock, if not then check if there is an overlap
if (curLock.getProcessId() != pid)
{
// Check if the read overlaps with the locked area
if (curLock.hasOverlap(offset, len) == true)
return false;
}
}
// The lock does not overlap with any existing locks
return true;
}
/**
* Check if the file is writeable for the specified section of the file and process id
*
* @param offset long
* @param len long
* @param pid int
* @return boolean
*/
public final boolean canWriteFile(long offset, long len, int pid)
{
// If the list is empty we can allow the read request
if (numberOfLocks() == 0)
return true;
// Search for a lock that prevents the read
for (int i = 0; i < numberOfLocks(); i++)
{
// Get the current lock details
FileLock curLock = getLockAt(i);
// Check if the process owns the lock, if not then check if there is an overlap
if (curLock.getProcessId() != pid)
{
// Check if the read overlaps with the locked area
if (curLock.hasOverlap(offset, len) == true)
return false;
}
}
// The lock does not overlap with any existing locks
return true;
}
/**
* Return the count of locks in the list.
*
* @return int Number of locks in the list.
*/
public final int numberOfLocks()
{
return m_lockList.size();
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
import java.io.IOException;
/**
* File Unlock Exception Class
*/
public class FileUnlockException extends IOException
{
private static final long serialVersionUID = 3257290240262484786L;
/**
* Class constructor.
*/
public FileUnlockException()
{
super();
}
/**
* Class constructor.
*
* @param s java.lang.String
*/
public FileUnlockException(String s)
{
super(s);
}
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
import java.io.IOException;
/**
* Lock Conflict Exception Class
* <p>
* Thrown when a lock request overlaps with an existing lock on a file.
*/
public class LockConflictException extends IOException
{
// Serializable version id
private static final long serialVersionUID = 0;
/**
* Class constructor.
*/
public LockConflictException()
{
super();
}
/**
* Class constructor.
*
* @param s java.lang.String
*/
public LockConflictException(String s)
{
super(s);
}
}

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.locking;
import java.io.IOException;
/**
* Not Locked Exception Class
* <p>
* Thrown when an unlock request is received that has not active lock on a file.
*/
public class NotLockedException extends IOException
{
private static final long serialVersionUID = 3834594296543261488L;
/**
* Class constructor.
*/
public NotLockedException()
{
super();
}
/**
* Class constructor.
*
* @param s java.lang.String
*/
public NotLockedException(String s)
{
super(s);
}
}

View File

@@ -1,680 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.alfresco.filesys.util.DataPacker;
/**
* NetBIOS datagram class.
*/
public class NetBIOSDatagram
{
// Datagram types
public static final int DIRECT_UNIQUE = 0x10;
public static final int DIRECT_GROUP = 0x11;
public static final int BROADCAST = 0x12;
public static final int DATAGRAM_ERROR = 0x13;
public static final int DATAGRAM_QUERY = 0x14;
public static final int POSITIVE_RESP = 0x15;
public static final int NEGATIVE_RESP = 0x16;
// Datagram flags
public static final int FLG_MOREFRAGMENTS = 0x01;
public static final int FLG_FIRSTPKT = 0x02;
// Default NetBIOS packet buffer size to allocate
public static final int DEFBUFSIZE = 4096;
// NetBIOS datagram offsets
public static final int NB_MSGTYPE = 0;
public static final int NB_FLAGS = 1;
public static final int NB_DATAGRAMID = 2;
public static final int NB_SOURCEIP = 4;
public static final int NB_SOURCEPORT = 8;
public static final int NB_DATAGRAMLEN = 10;
public static final int NB_PKTOFFSET = 12;
public static final int NB_FROMNAME = 14;
public static final int NB_TONAME = 48;
public static final int NB_USERDATA = 82;
public static final int NB_MINLENGTH = 82;
public static final int NB_MINSMBLEN = 100;
// NetBIOS packet buffer
protected byte[] m_buf;
// Next available datagram id
private static int m_nextId;
/**
* NetBIOS Datagram constructor
*/
public NetBIOSDatagram()
{
// Allocaet a NetBIOS packet buffer
m_buf = new byte[DEFBUFSIZE];
}
/**
* Create a new NetBIOS datagram using the specified packet buffer.
*
* @param pkt byte[]
*/
public NetBIOSDatagram(byte[] pkt)
{
m_buf = pkt;
}
/**
* Create a new NetBIOS datagram with the specified buffer size.
*
* @param bufSize int
*/
public NetBIOSDatagram(int bufSize)
{
m_buf = new byte[bufSize];
}
/**
* Return the next available datagram id.
*/
public final static synchronized int getNextDatagramId()
{
// Update and return the next available datagram id
return m_nextId++;
}
/**
* Return the NetBIOS buffer.
*
* @return byte[]
*/
public final byte[] getBuffer()
{
return m_buf;
}
/**
* Get the datagram id.
*
* @return int
*/
public final int getDatagramId()
{
return DataPacker.getIntelShort(m_buf, NB_DATAGRAMID);
}
/**
* Get the datagram destination name.
*
* @return NetBIOSName
*/
public final NetBIOSName getDestinationName()
{
// Decode the NetBIOS name to a string
String name = NetBIOSSession.DecodeName(m_buf, NB_TONAME + 1);
if (name != null)
{
// Convert the name string to a NetBIOS name
NetBIOSName nbName = new NetBIOSName(name.substring(0, 14), name.charAt(15), false);
if (getMessageType() == DIRECT_GROUP)
nbName.setGroup(true);
return nbName;
}
return null;
}
/**
* Return the datagram flags value.
*
* @return int
*/
public final int getFlags()
{
return m_buf[NB_FLAGS] & 0xFF;
}
/**
* Return the datagram length.
*
* @return int
*/
public final int getLength()
{
return DataPacker.getShort(m_buf, NB_DATAGRAMLEN);
}
/**
* Return the user data length
*
* @return int
*/
public final int getDataLength()
{
return getLength() - NB_USERDATA;
}
/**
* Get the NetBIOS datagram message type.
*
* @return int
*/
public final int getMessageType()
{
return m_buf[NB_MSGTYPE] & 0xFF;
}
/**
* Return the datagram source IP address.
*
* @return byte[]
*/
public final byte[] getSourceIPAddress()
{
// Allocate a 4 byte array for the IP address
byte[] ipaddr = new byte[4];
// Copy the IP address bytes from the datagram
for (int i = 0; i < 4; i++)
ipaddr[i] = m_buf[NB_SOURCEIP + i];
// Return the IP address bytes
return ipaddr;
}
/**
* Return the datagram source IP address, as a string
*
* @return String
*/
public final String getSourceAddress()
{
// Get the IP address
byte[] addr = getSourceIPAddress();
// Build the IP address string
StringBuffer addrStr = new StringBuffer();
addrStr.append(addr[0]);
addrStr.append(".");
addrStr.append(addr[1]);
addrStr.append(".");
addrStr.append(addr[2]);
addrStr.append(".");
addrStr.append(addr[3]);
return addrStr.toString();
}
/**
* Get the source NetBIOS name.
*
* @return java.lang.String
*/
public final NetBIOSName getSourceName()
{
// Decode the NetBIOS name string
String name = NetBIOSSession.DecodeName(m_buf, NB_FROMNAME + 1);
// Convert the name to a NetBIOS name
if (name != null)
{
// Convert the name string to a NetBIOS name
NetBIOSName nbName = new NetBIOSName(name.substring(0, 14), name.charAt(15), false);
return nbName;
}
return null;
}
/**
* Get the source port/socket for the datagram.
*
* @return int
*/
public final int getSourcePort()
{
return DataPacker.getIntelShort(m_buf, NB_SOURCEPORT);
}
/**
* Check if the user data is an SMB packet
*
* @return boolean
*/
public final boolean isSMBData()
{
if (m_buf[NB_USERDATA] == (byte) 0xFF && m_buf[NB_USERDATA + 1] == (byte) 'S'
&& m_buf[NB_USERDATA + 2] == (byte) 'M' && m_buf[NB_USERDATA + 3] == (byte) 'B'
&& getLength() >= NB_MINSMBLEN)
return true;
return false;
}
/**
* Return the message type as a string
*
* @return String
*/
public final String getMessageTypeString()
{
// Determine the message type
String typ = null;
switch (getMessageType())
{
case DIRECT_GROUP:
typ = "DIRECT GROUP";
break;
case DIRECT_UNIQUE:
typ = "DIRECT UNIQUE";
break;
case DATAGRAM_ERROR:
typ = "DATAGRAM ERROR";
break;
case DATAGRAM_QUERY:
typ = "DATAGRAM QUERY";
break;
case BROADCAST:
typ = "BROADCAST";
break;
case POSITIVE_RESP:
typ = "POSITIVE RESP";
break;
case NEGATIVE_RESP:
typ = "NEGATIVE RESP";
break;
default:
typ = "UNKNOWN";
break;
}
// Return the message type string
return typ;
}
/**
* Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
*
* @param dgramTyp Datagram type
* @param fromName From NetBIOS name
* @param fromNameTyp From NetBIOS name type.
* @param toName To NetBIOS name
* @param toNameType To NetBIOS name type.
* @param userData User data buffer
* @param userLen User data length.
* @param userOff Offset of data within user buffer.
* @param addr Address to send to
* @param port Port to send to
* @exception java.io.IOException Error occurred sending datagram
* @exception UnknownHostException Failed to generate the broadcast mask for the network
*/
public final void SendDatagram(int dgramTyp, String fromName, char fromNameType, String toName, char toNameType,
byte[] userData, int userLen, int userOff, InetAddress addr, int port) throws IOException,
UnknownHostException
{
// Set the datagram header values
setMessageType(dgramTyp);
setSourceName(fromName, fromNameType);
setDestinationName(toName, toNameType);
setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
setSourceIPAddress(InetAddress.getLocalHost().getAddress());
setFlags(FLG_FIRSTPKT);
if (m_nextId == 0)
m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
setDatagramId(m_nextId++);
// Set the user data and length
setLength(userLen + NB_USERDATA);
setUserData(userData, userLen, userOff);
// Use the global NetBIOS datagram socket to sent the broadcast datagram
NetBIOSDatagramSocket nbSocket = NetBIOSDatagramSocket.getInstance();
nbSocket.sendDatagram(this, addr, port);
}
/**
* Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
*
* @param dgramTyp Datagram type
* @param fromName From NetBIOS name
* @param fromNameTyp From NetBIOS name type.
* @param toName To NetBIOS name
* @param toNameType To NetBIOS name type.
* @param userData User data buffer
* @param userLen User data length.
* @param userOff Offset of data within user buffer.
* @exception java.io.IOException Error occurred sending datagram
* @exception UnknownHostException Failed to generate the broadcast mask for the network
*/
public final void SendDatagram(int dgramTyp, String fromName, char fromNameType, String toName, char toNameType,
byte[] userData, int userLen, int userOff) throws IOException, UnknownHostException
{
// Set the datagram header values
setMessageType(dgramTyp);
setSourceName(fromName, fromNameType);
setDestinationName(toName, toNameType);
setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
setSourceIPAddress(InetAddress.getLocalHost().getAddress());
setFlags(FLG_FIRSTPKT);
if (m_nextId == 0)
m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
setDatagramId(m_nextId++);
// Set the user data and length
setLength(userLen + NB_USERDATA);
setUserData(userData, userLen, userOff);
// Use the global NetBIOS datagram socket to sent the broadcast datagram
NetBIOSDatagramSocket nbSocket = NetBIOSDatagramSocket.getInstance();
nbSocket.sendBroadcastDatagram(this);
}
/**
* Send a datagram to the specified NetBIOS name using the global NetBIOS datagram socket
*
* @param dgramTyp Datagram type
* @param fromName From NetBIOS name
* @param fromNameTyp From NetBIOS name type.
* @param toName To NetBIOS name
* @param toNameType To NetBIOS name type.
* @param userData User data buffer
* @param userLen User data length.
* @exception java.io.IOException Error occurred sending datagram
* @exception UnknownHostException Failed to generate the broadcast mask for the network
*/
public final void SendDatagram(int dgramTyp, String fromName, String toName, byte[] userData, int userLen)
throws IOException, UnknownHostException
{
// Send the datagram from the standard port
SendDatagram(dgramTyp, fromName, NetBIOSName.FileServer, toName, NetBIOSName.FileServer, userData, userLen, 0);
}
/**
* Send a datagram to the specified NetBIOS name using the supplised datagram socket.
*
* @param dgramTyp Datagram type
* @param sock Datagram socket to use to send the datagram packet.
* @param fromName From NetBIOS name
* @param fromNameTyp From NetBIOS name type.
* @param toName To NetBIOS name
* @param toNameType To NetBIOS name type.
* @param userData User data buffer
* @param userLen User data length.
* @param userOff Offset of data within user buffer.
* @exception java.io.IOException The exception description.
*/
public final void SendDatagram(int dgramTyp, DatagramSocket sock, String fromName, char fromNameType,
String toName, char toNameType, byte[] userData, int userLen, int userOff) throws IOException
{
// Set the datagram header values
setMessageType(dgramTyp);
setSourceName(fromName, fromNameType);
setDestinationName(toName, toNameType);
setSourcePort(RFCNetBIOSProtocol.DATAGRAM);
setSourceIPAddress(InetAddress.getLocalHost().getAddress());
setFlags(FLG_FIRSTPKT);
if (m_nextId == 0)
m_nextId = (int) (System.currentTimeMillis() & 0x7FFF);
setDatagramId(m_nextId++);
// Set the user data and length
setLength(userLen + NB_USERDATA);
setUserData(userData, userLen, userOff);
// Build a broadcast destination address
InetAddress destAddr = InetAddress.getByName(NetworkSettings.GenerateBroadcastMask(null));
DatagramPacket dgram = new DatagramPacket(m_buf, userLen + NB_USERDATA, destAddr, RFCNetBIOSProtocol.DATAGRAM);
// Debug
// HexDump.Dump( m_buf, userLen + NB_USERDATA, 0);
// Send the datagram
sock.send(dgram);
}
/**
* Send a datagram to the specified NetBIOS name using the supplied datagram socket.
*
* @param fromName java.lang.String
* @param toName java.lang.String
* @param userData byte[]
* @param userLen int
* @exception java.io.IOException The exception description.
*/
public final void SendDatagram(int dgramTyp, DatagramSocket sock, String fromName, String toName, byte[] userData,
int userLen) throws IOException
{
// Send the datagram from the standard port
SendDatagram(dgramTyp, sock, fromName, NetBIOSName.FileServer, toName, NetBIOSName.FileServer, userData,
userLen, 0);
}
/**
* Set the datagram id.
*
* @param id int
*/
public final void setDatagramId(int id)
{
DataPacker.putIntelShort(id, m_buf, NB_DATAGRAMID);
}
/**
* Set the datagram destination name.
*
* @param name java.lang.String
*/
public final void setDestinationName(String name)
{
setDestinationName(name, NetBIOSName.FileServer);
}
/**
* Set the datagram destination name.
*
* @param name java.lang.String
*/
public final void setDestinationName(String name, char typ)
{
// Convert the name to NetBIOS RFC encoded name
NetBIOSSession.EncodeName(name, typ, m_buf, NB_TONAME);
}
/**
* Set the datagram flags value.
*
* @param flg int
*/
public final void setFlags(int flg)
{
m_buf[NB_FLAGS] = (byte) (flg & 0xFF);
}
/**
* Set the datagram length.
*
* @param len int
*/
public final void setLength(int len)
{
DataPacker.putShort((short) len, m_buf, NB_DATAGRAMLEN);
}
/**
* Set the NetBIOS datagram message type.
*
* @param msg int
*/
public final void setMessageType(int msg)
{
m_buf[NB_MSGTYPE] = (byte) (msg & 0xFF);
}
/**
* Set the source IP address for the datagram.
*
* @param ipaddr byte[]
*/
public final void setSourceIPAddress(byte[] ipaddr)
{
// Pack the IP address into the datagram buffer
for (int i = 0; i < 4; i++)
m_buf[NB_SOURCEIP + i] = ipaddr[i];
}
/**
* Set the datagram source NetBIOS name.
*
* @param name java.lang.String
*/
public final void setSourceName(String name)
{
// Convert the name to NetBIOS RFC encoded name
NetBIOSSession.EncodeName(name, NetBIOSName.FileServer, m_buf, NB_FROMNAME);
}
/**
* Set the datagram source NetBIOS name.
*
* @param name java.lang.String
*/
public final void setSourceName(String name, char typ)
{
// Convert the name to NetBIOS RFC encoded name
NetBIOSSession.EncodeName(name, typ, m_buf, NB_FROMNAME);
}
/**
* Set the source port/socket for the datagram.
*
* @param port int
*/
public final void setSourcePort(int port)
{
DataPacker.putShort((short) port, m_buf, NB_SOURCEPORT);
}
/**
* Set the user data portion of the datagram.
*
* @param buf byte[]
* @param len int
*/
public final void setUserData(byte[] buf, int len)
{
// Copy the user data
System.arraycopy(buf, 0, m_buf, NB_USERDATA, len);
}
/**
* Set the user data portion of the datagram.
*
* @param buf User data buffer
* @param len Length of user data
* @param off Offset to start of data within buffer.
*/
public final void setUserData(byte[] buf, int len, int off)
{
// Copy the user data
System.arraycopy(buf, off, m_buf, NB_USERDATA, len);
}
/**
* Common constructor initialization code.
*/
protected final void CommonInit()
{
}
}

View File

@@ -1,180 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* NetBIOS Datagram Socket Class
* <p>
* Singleton class that allows multiple users of the socket.
*/
public class NetBIOSDatagramSocket
{
// Global NetBIOS datagram socket instance
private static NetBIOSDatagramSocket m_nbSocket;
// Default port and bind address
private static int m_defPort = RFCNetBIOSProtocol.DATAGRAM;
private static InetAddress m_defBindAddr;
// Datagram socket
private DatagramSocket m_socket;
// Broadcast address
private InetAddress m_broadcastAddr;
/**
* Class constructor
*
* @exception SocketException
* @exception UnknownHostException
*/
private NetBIOSDatagramSocket() throws SocketException, UnknownHostException
{
// Create the datagram socket
if (m_defBindAddr == null)
m_socket = new DatagramSocket(m_defPort);
else
m_socket = new DatagramSocket(m_defPort, m_defBindAddr);
// Generate the broadcast mask
if (m_defBindAddr == null)
m_broadcastAddr = InetAddress.getByName(NetworkSettings.GenerateBroadcastMask(null));
else
m_broadcastAddr = InetAddress.getByName(NetworkSettings.GenerateBroadcastMask(m_defBindAddr
.getHostAddress()));
}
/**
* Return the global NetBIOS datagram instance
*
* @return NetBIOSDatagramSocket
* @exception SocketException
* @exception UnknownHostException
*/
public final static synchronized NetBIOSDatagramSocket getInstance() throws SocketException, UnknownHostException
{
// Check if the datagram socket has been created
if (m_nbSocket == null)
m_nbSocket = new NetBIOSDatagramSocket();
// Return the global NetBIOS datagram socket instance
return m_nbSocket;
}
/**
* Set the default port to use
*
* @param port int
*/
public final static void setDefaultPort(int port)
{
m_defPort = port;
}
/**
* Set the address to bind the datagram socket to
*
* @param bindAddr InetAddress
*/
public final static void setBindAddress(InetAddress bindAddr)
{
m_defBindAddr = bindAddr;
}
/**
* Receive a NetBIOS datagram
*
* @param dgram NetBIOSDatagram
* @return int
* @exception IOException
*/
public final int receiveDatagram(NetBIOSDatagram dgram) throws IOException
{
// Create a datagram packet using the NetBIOS datagram buffer
DatagramPacket pkt = new DatagramPacket(dgram.getBuffer(), dgram.getBuffer().length);
// Receive a datagram
m_socket.receive(pkt);
return pkt.getLength();
}
/**
* Send a NetBIOS datagram
*
* @param dgram NetBIOSDatagram
* @param destAddr InetAddress
* @param destPort int
* @exception IOException
*/
public final void sendDatagram(NetBIOSDatagram dgram, InetAddress destAddr, int destPort) throws IOException
{
// Create a datagram packet using the NetBIOS datagram buffer
DatagramPacket pkt = new DatagramPacket(dgram.getBuffer(), dgram.getLength(), destAddr, destPort);
// Send the NetBIOS datagram
m_socket.send(pkt);
}
/**
* Send a broadcast NetBIOS datagram
*
* @param dgram NetBIOSDatagram
* @exception IOException
*/
public final void sendBroadcastDatagram(NetBIOSDatagram dgram) throws IOException
{
// Create a datagram packet using the NetBIOS datagram buffer
DatagramPacket pkt = new DatagramPacket(dgram.getBuffer(), dgram.getLength(), m_broadcastAddr, m_defPort);
// Send the NetBIOS datagram
m_socket.send(pkt);
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
/**
* NetBIOS exception class.
*/
public class NetBIOSException extends Exception
{
private static final long serialVersionUID = 3256438122995988025L;
/**
* NetBIOSException constructor comment.
*/
public NetBIOSException()
{
super();
}
/**
* NetBIOSException constructor comment.
*
* @param s java.lang.String
*/
public NetBIOSException(String s)
{
super(s);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,206 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
import java.util.Vector;
/**
* NetBIOS Name List Class
*/
public class NetBIOSNameList
{
// List of NetBIOS names
private Vector<NetBIOSName> m_nameList;
/**
* Class constructor
*/
public NetBIOSNameList()
{
m_nameList = new Vector<NetBIOSName>();
}
/**
* Add a name to the list
*
* @param name NetBIOSName
*/
public final void addName(NetBIOSName name)
{
m_nameList.add(name);
}
/**
* Get a name from the list
*
* @param idx int
* @return NetBIOSName
*/
public final NetBIOSName getName(int idx)
{
if (idx < m_nameList.size())
return m_nameList.get(idx);
return null;
}
/**
* Return the number of names in the list
*
* @return int
*/
public final int numberOfNames()
{
return m_nameList.size();
}
/**
* Find names of the specified name of different types and return a subset of the available
* names.
*
* @param name String
* @return NetBIOSNameList
*/
public final NetBIOSNameList findNames(String name)
{
// Allocate the sub list and search for required names
NetBIOSNameList subList = new NetBIOSNameList();
for (int i = 0; i < m_nameList.size(); i++)
{
NetBIOSName nbName = getName(i);
if (nbName.getName().compareTo(name) == 0)
subList.addName(nbName);
}
// Return the sub list of names
return subList;
}
/**
* Find the first name of the specified type
*
* @param typ char
* @param group boolean
* @return NetBIOSName
*/
public final NetBIOSName findName(char typ, boolean group)
{
// Search for the first name of the required type
for (int i = 0; i < m_nameList.size(); i++)
{
NetBIOSName name = getName(i);
if (name.getType() == typ && name.isGroupName() == group)
return name;
}
// Name type not found
return null;
}
/**
* Find the specified name and type
*
* @param name String
* @param typ char
* @param group boolean
* @return NetBIOSName
*/
public final NetBIOSName findName(String name, char typ, boolean group)
{
// Search for the first name of the required type
for (int i = 0; i < m_nameList.size(); i++)
{
NetBIOSName nbName = getName(i);
if (nbName.getName().equals(name) && nbName.getType() == typ && nbName.isGroupName() == group)
return nbName;
}
// Name/type not found
return null;
}
/**
* Find names of the specified type and return a subset of the available names
*
* @param typ char
* @param group boolean
* @return NetBIOSNameList
*/
public final NetBIOSNameList findNames(char typ, boolean group)
{
// Allocate the sub list and search for names of the required type
NetBIOSNameList subList = new NetBIOSNameList();
for (int i = 0; i < m_nameList.size(); i++)
{
NetBIOSName name = getName(i);
if (name.getType() == typ && name.isGroupName() == group)
subList.addName(name);
}
// Return the sub list of names
return subList;
}
/**
* Remove a name from the list
*
* @param name NetBIOSName
* @return NetBIOSName
*/
public final NetBIOSName removeName(NetBIOSName name)
{
for (int i = 0; i < m_nameList.size(); i++)
{
NetBIOSName curName = getName(i);
if (curName.equals(name))
{
m_nameList.removeElementAt(i);
return curName;
}
}
return null;
}
/**
* Delete all names from the list
*/
public final void removeAllNames()
{
m_nameList.removeAllElements();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,210 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
import java.net.InetAddress;
/**
* The network settings class contains various Windows Networking settings that are needed by the
* NetBIOS and SMB layers.
*/
public class NetworkSettings
{
// Broadcast mask for broadcast messages
private static String m_broadcastMask;
// Domain name/workgroup that this node is part of
private static String m_domain;
// Subnet mask address
private static InetAddress m_subnetAddr;
/**
* Determine the boradcast mask from the local hosts TCP/IP address
*
* @param addr TCP/IP address to set the broadcast mask for, in 'nnn.nnn.nnn.nnn' format.
*/
public static String GenerateBroadcastMask(String addr) throws java.net.UnknownHostException
{
// Check if the broadcast mask has already been set
if (m_broadcastMask != null)
return m_broadcastMask;
// Set the TCP/IP address string
String localIP = addr;
if (localIP == null)
localIP = InetAddress.getLocalHost().getHostAddress();
// Find the location of the first dot in the TCP/IP address
int dotPos = localIP.indexOf('.');
if (dotPos != -1)
{
// Extract the leading IP address value
String ipStr = localIP.substring(0, dotPos);
int ipVal = Integer.valueOf(ipStr).intValue();
// Determine the broadcast mask to use
if (ipVal <= 127)
{
// Class A address
m_broadcastMask = "" + ipVal + ".255.255.255";
}
else if (ipVal <= 191)
{
// Class B adddress
dotPos++;
while (localIP.charAt(dotPos) != '.' && dotPos < localIP.length())
dotPos++;
if (dotPos < localIP.length())
m_broadcastMask = localIP.substring(0, dotPos) + ".255.255";
}
else if (ipVal <= 223)
{
// Class C address
dotPos++;
int dotCnt = 1;
while (dotCnt < 3 && dotPos < localIP.length())
{
// Check if the current character is a dot
if (localIP.charAt(dotPos++) == '.')
dotCnt++;
}
if (dotPos < localIP.length())
m_broadcastMask = localIP.substring(0, dotPos - 1) + ".255";
}
}
// Check if the broadcast mask has been set, if not then use a general
// broadcast mask
if (m_broadcastMask == null)
{
// Invalid TCP/IP address string format, use a general broadcast mask
// for now.
m_broadcastMask = "255.255.255.255";
}
// Return the broadcast mask string
return m_broadcastMask;
}
/**
* Return the broadcast mask as an address.
*
* @return java.net.InetAddress
*/
public final static InetAddress getBroadcastAddress() throws java.net.UnknownHostException
{
// Check if the subnet address is valid
if (m_subnetAddr == null)
{
// Generate the subnet mask
String subnet = GenerateBroadcastMask(null);
m_subnetAddr = InetAddress.getByName(subnet);
}
// Return the subnet mask address
return m_subnetAddr;
}
/**
* Get the broadcast mask.
*
* @return java.lang.String
*/
public static String getBroadcastMask()
{
return m_broadcastMask;
}
/**
* Get the local domain/workgroup name.
*/
public static String getDomain()
{
return m_domain;
}
/**
* Determine if the broadcast mask has been setup.
*/
public static boolean hasBroadcastMask()
{
if (m_broadcastMask == null)
return false;
return true;
}
/**
* Set the broadcast mask to be used for broadcast packets.
*
* @param mask java.lang.String
*/
public static void setBroadcastMask(String mask)
{
m_broadcastMask = mask;
}
/**
* Set the local domain/workgroup name.
*
* @param domain java.lang.String
*/
public static void setDomain(String domain)
{
m_domain = domain;
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios;
/**
* RFC NetBIOS constants.
*/
public final class RFCNetBIOSProtocol
{
// RFC NetBIOS default port/socket
public static final int PORT = 139;
// RFC NetBIOS datagram port
public static final int DATAGRAM = 138;
// RFC NetBIOS default name lookup datagram port
public static final int NAME_PORT = 137;
// RFC NetBIOS default socket timeout
public static final int TMO = 30000; // 30 seconds, in milliseconds
// RFC NetBIOS message types.
public static final int SESSION_MESSAGE = 0x00;
public static final int SESSION_REQUEST = 0x81;
public static final int SESSION_ACK = 0x82;
public static final int SESSION_REJECT = 0x83;
public static final int SESSION_RETARGET = 0x84;
public static final int SESSION_KEEPALIVE = 0x85;
// RFC NetBIOS packet header length, and various message lengths.
public static final int HEADER_LEN = 4;
public static final int SESSREQ_LEN = 72;
public static final int SESSRESP_LEN = 9;
// Maximum packet size that RFC NetBIOS can handle (17bit value)
public static final int MaxPacketSize = 0x01FFFF + HEADER_LEN;
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
/**
* NetBIOS add name listener interface.
*/
public interface AddNameListener
{
/**
* Signal that a NetBIOS name has been added, or an error occurred whilst trying to add a new
* NetBIOS name.
*
* @param evt NetBIOSNameEvent
*/
public void netbiosNameAdded(NetBIOSNameEvent evt);
}

View File

@@ -1,90 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
import org.alfresco.filesys.netbios.NetBIOSName;
/**
* NetBIOS name server event class.
*/
public class NetBIOSNameEvent
{
/*
* NetBIOS name event status codes
*/
public static final int ADD_SUCCESS = 0; // local name added successfully
public static final int ADD_FAILED = 1; // local name add failure
public static final int ADD_DUPLICATE = 2; // local name already in use
public static final int ADD_IOERROR = 3; // I/O error during add name broadcast
public static final int QUERY_NAME = 4; // query for local name
public static final int REGISTER_NAME = 5; // remote name registered
public static final int REFRESH_NAME = 6; // name refresh
public static final int REFRESH_IOERROR = 7; // refresh name I/O error
/**
* NetBIOS name details
*/
private NetBIOSName m_name;
/**
* Name status
*/
private int m_status;
/**
* Create a NetBIOS name event.
*
* @param name NetBIOSName
* @param sts int
*/
protected NetBIOSNameEvent(NetBIOSName name, int sts)
{
m_name = name;
m_status = sts;
}
/**
* Return the NetBIOS name details.
*
* @return NetBIOSName
*/
public final NetBIOSName getNetBIOSName()
{
return m_name;
}
/**
* Return the NetBIOS name status.
*
* @return int
*/
public final int getStatus()
{
return m_status;
}
}

View File

@@ -1,247 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
import org.alfresco.filesys.netbios.NetBIOSName;
/**
* NetBIOS Request Class
* <p>
* Contains the details of NetBIOS server request, such as an add name request.
*/
class NetBIOSRequest
{
// Request types
public final static int AddName = 0;
public final static int DeleteName = 1;
public final static int RefreshName = 2;
// Default retry count and interval
public final static int DefaultRetries = 5;
public final static long DefaultInterval = 2000; // ms
// Requets type strings
private final static String[] _typeNames = { "AddName", "DelName", "RefreshName" };
// Request type
private int m_type;
// NetBIOS name details
private NetBIOSName m_nbName;
// Retry count and interval
private int m_retry;
private long m_retryIntvl;
// Response status
private boolean m_error;
// Transaction id for this request
private int m_tranId;
/**
* Class constructor
*
* @param typ int
* @param nbName NetBIOSName
* @param tranId int
*/
public NetBIOSRequest(int typ, NetBIOSName nbName, int tranId)
{
m_type = typ;
m_nbName = nbName;
m_tranId = tranId;
m_retry = DefaultRetries;
m_retryIntvl = DefaultInterval;
m_error = false;
}
/**
* Class constructor
*
* @param typ int
* @param nbName NetBIOSName
* @param tranId int
* @param retry int
*/
public NetBIOSRequest(int typ, NetBIOSName nbName, int tranId, int retry)
{
m_type = typ;
m_nbName = nbName;
m_tranId = tranId;
m_retry = retry;
m_retryIntvl = DefaultInterval;
m_error = false;
}
/**
* Return the request type
*
* @return int
*/
public final int isType()
{
return m_type;
}
/**
* Return the type as a string
*
* @return String
*/
public final String getTypeAsString()
{
if (m_type < 0 || m_type >= _typeNames.length)
return "";
return _typeNames[m_type];
}
/**
* Return the NetBIOS name details
*
* @return NetBIOSName
*/
public final NetBIOSName getNetBIOSName()
{
return m_nbName;
}
/**
* Return the retry count
*
* @return int
*/
public final int getRetryCount()
{
return m_retry;
}
/**
* Return the retry interval
*
* @return long
*/
public final long getRetryInterval()
{
return m_retryIntvl;
}
/**
* Return the transaction id
*
* @return int
*/
public final int getTransactionId()
{
return m_tranId;
}
/**
* Check if the request has an error status
*
* @return boolean
*/
public final boolean hasErrorStatus()
{
return m_error;
}
/**
* Decrement the retry count
*
* @return int
*/
protected final int decrementRetryCount()
{
return m_retry--;
}
/**
* Set the error status
*
* @param sts boolean
*/
protected final void setErrorStatus(boolean sts)
{
m_error = sts;
}
/**
* Set the request retry count
*
* @param retry int
*/
public final void setRetryCount(int retry)
{
m_retry = retry;
}
/**
* Set the retry interval, in milliseconds
*
* @param interval long
*/
public final void setRetryInterval(long interval)
{
m_retryIntvl = interval;
}
/**
* Return the request as a string
*
* @return String
*/
public String toString()
{
StringBuffer str = new StringBuffer();
str.append("[");
str.append(getTypeAsString());
str.append(":");
str.append(getNetBIOSName());
str.append(",");
str.append(getRetryCount());
str.append(",");
str.append(getRetryInterval());
str.append(",");
str.append(getTransactionId());
str.append("]");
return str.toString();
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
import java.io.IOException;
import java.net.DatagramSocket;
/**
* Interface for NetBIOS packet receivers.
*/
public interface PacketReceiver
{
/**
* Receive packets on the specified datagram socket.
*
* @param sock java.net.DatagramSocket
* @exception java.io.IOException The exception description.
*/
void ReceivePacket(DatagramSocket sock) throws IOException;
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
import java.net.InetAddress;
/**
* NetBIOS name query listener interface.
*/
public interface QueryNameListener
{
/**
* Signal that a NetBIOS name query has been received, for the specified local NetBIOS name.
*
* @param evt Local NetBIOS name details.
* @param addr IP address of the remote node that sent the name query request.
*/
public void netbiosNameQuery(NetBIOSNameEvent evt, InetAddress addr);
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.server;
import java.net.InetAddress;
/**
* NetBIOS remote name listener interface.
*/
public interface RemoteNameListener
{
/**
* Signal that a remote host has added a new NetBIOS name.
*
* @param evt NetBIOSNameEvent
* @param addr java.net.InetAddress
*/
public void netbiosAddRemoteName(NetBIOSNameEvent evt, InetAddress addr);
/**
* Signal that a remote host has released a NetBIOS name.
*
* @param evt NetBIOSNameEvent
* @param addr java.net.InetAddress
*/
public void netbiosReleaseRemoteName(NetBIOSNameEvent evt, InetAddress addr);
}

View File

@@ -1,268 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
/**
* NetBIOS API Constants Class
*/
public class NetBIOS
{
// NetBIOS command codes
public final static int NCBCall = 0x10;
public final static int NCBListen = 0x11;
public final static int NCBHangup = 0x12;
public final static int NCBSend = 0x14;
public final static int NCBRecv = 0x15;
public final static int NCBRecvAny = 0x16;
public final static int NCBChainSend = 0x17;
public final static int NCBDGSend = 0x20;
public final static int NCBDGRecv = 0x21;
public final static int NCBDGSendBc = 0x22;
public final static int NCBDGRecvBc = 0x23;
public final static int NCBAddName = 0x30;
public final static int NCBDelName = 0x31;
public final static int NCBReset = 0x32;
public final static int NCBAStat = 0x33;
public final static int NCBSStat = 0x34;
public final static int NCBCancel = 0x35;
public final static int NCBAddGrName = 0x36;
public final static int NCBEnum = 0x37;
public final static int NCBUnlink = 0x70;
public final static int NCBSendNA = 0x71;
public final static int NCBChainSendNA = 0x72;
public final static int NCBLANStAlert = 0x73;
public final static int NCBAction = 0x77;
public final static int NCBFindName = 0x78;
public final static int NCBTrace = 0x79;
public final static int Asynch = 0x80;
// Status codes
public final static int NRC_GoodRet = 0x00;
public final static int NRC_BufLen = 0x01;
public final static int NRC_IllCmd = 0x03;
public final static int NRC_CmdTmo = 0x05;
public final static int NRC_Incomp = 0x06;
public final static int NRC_Baddr = 0x07;
public final static int NRC_SNumOut = 0x08;
public final static int NRC_NoRes = 0x09;
public final static int NRC_SClosed = 0x0A;
public final static int NRC_CmdCan = 0x0B;
public final static int NRC_DupName = 0x0D;
public final static int NRC_NamTFul = 0x0E;
public final static int NRC_ActSes = 0x0F;
public final static int NRC_LocTFul = 0x11;
public final static int NRC_RemTFul = 0x12;
public final static int NRC_IllNN = 0x13;
public final static int NRC_NoCall = 0x14;
public final static int NRC_NoWild = 0x15;
public final static int NRC_InUse = 0x16;
public final static int NRC_NamErr = 0x17;
public final static int NRC_SAbort = 0x18;
public final static int NRC_NamConf = 0x19;
public final static int NRC_IfBusy = 0x21;
public final static int NRC_TooMany = 0x22;
public final static int NRC_Bridge = 0x23;
public final static int NRC_CanOccr = 0x24;
public final static int NRC_Cancel = 0x26;
public final static int NRC_DupEnv = 0x30;
public final static int NRC_EnvNotDef = 0x34;
public final static int NRC_OSResNotAv = 0x35;
public final static int NRC_MaxApps = 0x36;
public final static int NRC_NoSaps = 0x37;
public final static int NRC_NoResources = 0x38;
public final static int NRC_InvAddress = 0x39;
public final static int NRC_InvDDid = 0x3B;
public final static int NRC_LockFail = 0x3C;
public final static int NRC_OpenErr = 0x3F;
public final static int NRC_System = 0x40;
public final static int NRC_Pending = 0xFF;
// Various constants
public final static int NCBNameSize = 16;
public final static int MaxLANA = 254;
public final static int NameFlagsMask = 0x87;
public final static int GroupName = 0x80;
public final static int UniqueName = 0x00;
public final static int Registering = 0x00;
public final static int Registered = 0x04;
public final static int Deregistered = 0x05;
public final static int Duplicate = 0x06;
public final static int DuplicateDereg = 0x07;
public final static int ListenOutstanding = 0x01;
public final static int CallPending = 0x02;
public final static int SessionEstablished = 0x03;
public final static int HangupPending = 0x04;
public final static int HangupComplete = 0x05;
public final static int SessionAborted = 0x06;
public final static String AllTransports = "M\0\0\0";
// Maximum receive size (16bits)
//
// Multiple receives must be issued to receive data packets over this size
public final static int MaxReceiveSize = 0xFFFF;
/**
* Return the status string for a NetBIOS error code
*
* @param nbError int
* @return String
*/
public final static String getErrorString(int nbError)
{
String str = "";
switch (nbError)
{
case NRC_GoodRet:
str = "Success status";
break;
case NRC_BufLen:
str = "Illegal buffer length";
break;
case NRC_IllCmd:
str = "Illegal command";
break;
case NRC_CmdTmo:
str = "Command timed out";
break;
case NRC_Incomp:
str = "Message incomplete, issue another command";
break;
case NRC_Baddr:
str = "Illegal buffer address";
break;
case NRC_SNumOut:
str = "Session number out of range";
break;
case NRC_NoRes:
str = "No resource available";
break;
case NRC_SClosed:
str = "Session closed";
break;
case NRC_CmdCan:
str = "Command cancelled";
break;
case NRC_DupName:
str = "Duplicate name";
break;
case NRC_NamTFul:
str = "Name table full";
break;
case NRC_ActSes:
str = "No deletions, name has active sessions";
break;
case NRC_LocTFul:
str = "Local session table full";
break;
case NRC_RemTFul:
str = "Remote session table full";
break;
case NRC_IllNN:
str = "Illegal name number";
break;
case NRC_NoCall:
str = "No callname";
break;
case NRC_NoWild:
str = "Cannot put * in ncb_name";
break;
case NRC_InUse:
str = "Name in use on remote adapter";
break;
case NRC_NamErr:
str = "Name deleted";
break;
case NRC_SAbort:
str = "Session ended abnormally";
break;
case NRC_NamConf:
str = "Name conflict detected";
break;
case NRC_IfBusy:
str = "Interface busy, IRET before retrying";
break;
case NRC_TooMany:
str = "Too many commands outstanding, try later";
break;
case NRC_Bridge:
str = "ncb_lana_num field invalid";
break;
case NRC_CanOccr:
str = "Command completed whilst cancel occurring";
break;
case NRC_Cancel:
str = "Command not valid to cancel";
break;
case NRC_DupEnv:
str = "Name defined by another local process";
break;
case NRC_EnvNotDef:
str = "Environment undefined, RESET required";
break;
case NRC_OSResNotAv:
str = "Require OS resources exhausted";
break;
case NRC_MaxApps:
str = "Max number of applications exceeded";
break;
case NRC_NoSaps:
str = "No saps available for NetBIOS";
break;
case NRC_NoResources:
str = "Requested resources not available";
break;
case NRC_InvAddress:
str = "Invalid ncb address or length";
break;
case NRC_InvDDid:
str = "Ivalid NCB DDID";
break;
case NRC_LockFail:
str = "Lock of user area failed";
break;
case NRC_OpenErr:
str = "NetBIOS not loaded";
break;
case NRC_System:
str = "System error";
break;
case NRC_Pending:
str = "Asyncrhonous command pending";
break;
}
return str;
}
}

View File

@@ -1,408 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
import org.alfresco.filesys.netbios.NetBIOSName;
/**
* NetBIOS Socket Class
*
* <p>Contains the details of a Winsock NetBIOS socket that was opened using native code.
*
* @author GKSpencer
*/
public class NetBIOSSocket
{
// Socket types
private static final int TypeNormal = 0;
private static final int TypeListener = 1;
private static final int TypeDatagram = 2;
// Flag to indicate if the NetBIOS socket interface has been initialized
private static boolean _nbSocketInit;
// NetBIOS LANA that the socket is associated with
private int m_lana;
// Socket pointer (Windows SOCKET)
private int m_socket;
// NetBIOS name, either listening name or callers name
private NetBIOSName m_nbName;
// Socket type
private int m_socketType;
/**
* Initialize the Winsock NetBIOS interface
*/
public static final void initializeSockets()
throws WinsockNetBIOSException {
// Check if the NetBIOS socket interface has been initialized
if ( _nbSocketInit == false)
{
// Initialize the NetBIOS socket interface
Win32NetBIOS.InitializeSockets();
// Indicate that the NetBIOS socket interface is initialized
_nbSocketInit = true;
}
}
/**
* Shutdown the Winsock NetBIOS interface
*/
public static final void shutdownSockets()
{
// Check if the NetBIOS socket interface has been initialized
if ( _nbSocketInit == true)
{
// Indicate that the NetBIOS socket interface is not initialized
_nbSocketInit = false;
// Initialize the NetBIOS socket interface
Win32NetBIOS.ShutdownSockets();
}
}
/**
* Determine if the Winsock NetBIOS interface is initialized
*
* @return boolean
*/
public static final boolean isInitialized()
{
return _nbSocketInit;
}
/**
* Create a NetBIOS socket to listen for incoming sessions on the specified LANA
*
* @param lana int
* @param nbName NetBIOSName
* @return NetBIOSSocket
* @exception NetBIOSSocketException
* @exception WinsockNetBIOSException
*/
public static final NetBIOSSocket createListenerSocket(int lana, NetBIOSName nbName)
throws WinsockNetBIOSException, NetBIOSSocketException
{
// Initialize the Winsock NetBIOS interface
initializeSockets();
// Create a new NetBIOS socket
int sockPtr = Win32NetBIOS.CreateSocket(lana);
if ( sockPtr == 0)
throw new NetBIOSSocketException("Failed to create NetBIOS socket");
// Bind the socket to a NetBIOS name
if ( Win32NetBIOS.BindSocket( sockPtr, nbName.getNetBIOSName()) != 0)
throw new NetBIOSSocketException("Failed to bind NetBIOS socket");
// Return the NetBIOS socket
return new NetBIOSSocket(lana, sockPtr, nbName, TypeListener);
}
/**
* Create a NetBIOS datagram socket to send out mailslot announcements on the specified LANA
*
* @param lana int
* @return NetBIOSSocket
* @exception NetBIOSSocketException
* @exception WinsockNetBIOSException
*/
public static final NetBIOSSocket createDatagramSocket(int lana)
throws WinsockNetBIOSException, NetBIOSSocketException
{
// Initialize the Winsock NetBIOS interface
initializeSockets();
// Create a new NetBIOS socket
int sockPtr = Win32NetBIOS.CreateDatagramSocket(lana);
if ( sockPtr == 0)
throw new NetBIOSSocketException("Failed to create NetBIOS datagram socket");
// Return the NetBIOS socket
return new NetBIOSSocket(lana, sockPtr, null, TypeDatagram);
}
/**
* Class constructor
*
* @param lana int
* @param sockPtr int
* @param nbName NetBIOSName
* @param sockerType int
*/
private NetBIOSSocket(int lana, int sockPtr, NetBIOSName nbName, int socketType)
{
m_lana = lana;
m_nbName = nbName;
m_socket = sockPtr;
m_socketType = socketType;
}
/**
* Return the NetBIOS LANA the socket is associated with
*
* @return int
*/
public final int getLana()
{
return m_lana;
}
/**
* Determine if this is a datagram socket
*
* @return boolean
*/
public final boolean isDatagramSocket()
{
return m_socketType == TypeDatagram ? true : false;
}
/**
* Determine if this is a listener type socket
*
* @return boolean
*/
public final boolean isListener()
{
return m_socketType == TypeListener ? true : false;
}
/**
* Determine if the socket is valid
*
* @return boolean
*/
public final boolean hasSocket()
{
return m_socket != 0 ? true : false;
}
/**
* Return the socket pointer
*
* @return int
*/
public final int getSocket()
{
return m_socket;
}
/**
* Return the NetBIOS name. For a listening socket this is the local name, for a session
* socket this is the remote callers name.
*
* @return NetBIOSName
*/
public final NetBIOSName getName()
{
return m_nbName;
}
/**
* Write data to the session socket
*
* @param buf byte[]
* @param off int
* @param len int
* @return int
* @exception WinsockNetBIOSException
*/
public final int write(byte[] buf, int off, int len)
throws WinsockNetBIOSException
{
// Check if this is a datagram socket
if ( isDatagramSocket())
throw new WinsockNetBIOSException("Write not allowed for datagram socket");
return Win32NetBIOS.SendSocket( getSocket(), buf, off, len);
}
/**
* Read data from the session socket
*
* @param buf byte[]
* @param off int
* @param maxLen int
* @return int
* @exception WinsockNetBIOSException
*/
public final int read(byte[] buf, int off, int maxLen)
throws WinsockNetBIOSException
{
// Check if this is a datagram socket
if ( isDatagramSocket())
throw new WinsockNetBIOSException("Read not allowed for datagram socket");
return Win32NetBIOS.ReceiveSocket( getSocket(), buf, off, maxLen);
}
/**
* Send a datagram to a group name
*
* @param toName NetBIOSName
* @param buf byte[]
* @param off int
* @param len int
* @return int
* @exception WinsockNetBIOSException
*/
public final int sendDatagram(NetBIOSName toName, byte[] buf, int off, int len)
throws WinsockNetBIOSException
{
// Check if this is a datagram socket
if ( isDatagramSocket() == false)
throw new WinsockNetBIOSException("Not a datagram type socket");
return Win32NetBIOS.SendSocketDatagram( getSocket(), toName.getNetBIOSName(), buf, off, len);
}
/**
* Listen for an incoming session connection and create a session socket for the new session
*
* @return NetBIOSSocket
* @exception NetBIOSSocketException
* @exception winsockNetBIOSException
*/
public final NetBIOSSocket listen()
throws WinsockNetBIOSException, NetBIOSSocketException
{
// Check if this socket is a listener socket, and the socket is valid
if ( isListener() == false)
throw new NetBIOSSocketException("Not a listener type socket");
if ( hasSocket() == false)
throw new NetBIOSSocketException("NetBIOS socket not valid");
// Wait for an incoming session request
byte[] callerName = new byte[NetBIOSName.NameLength];
int sessSockPtr = Win32NetBIOS.ListenSocket( getSocket(), callerName);
if ( sessSockPtr == 0)
throw new NetBIOSSocketException("NetBIOS socket listen failed");
// Return the new NetBIOS socket session
return new NetBIOSSocket(getLana(), sessSockPtr, new NetBIOSName(callerName, 0), TypeNormal);
}
/**
* Close the socket
*/
public final void closeSocket()
{
// Close the native socket, if valid
if ( hasSocket())
{
Win32NetBIOS.CloseSocket( getSocket());
setSocket(0);
}
}
/**
* Set the socket pointer
*
* @param sockPtr int
*/
protected final void setSocket(int sockPtr)
{
m_socket = sockPtr;
}
/**
* Return the NetBIOS socket details as a string
*
* @return String
*/
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("[LANA:");
str.append(getLana());
str.append(",Name:");
if ( getName() != null)
str.append(getName());
else
str.append("<None>");
str.append(",Socket:");
if ( hasSocket())
{
str.append("0x");
str.append(Integer.toHexString(getSocket()));
}
else
str.append("<None>");
switch( m_socketType)
{
case TypeNormal:
str.append("Session");
break;
case TypeListener:
str.append("Listener");
break;
case TypeDatagram:
str.append("Datagram");
break;
}
str.append("]");
return str.toString();
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
/**
* NetBIOS Socket Exception Class
*
* @author GKSpencer
*/
public class NetBIOSSocketException extends Exception
{
private static final long serialVersionUID = 2363178480979507007L;
/**
* Class constructor
*
* @param msg String
*/
public NetBIOSSocketException(String msg)
{
super(msg);
}
}

View File

@@ -1,730 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Hashtable;
import org.alfresco.filesys.netbios.NetBIOSName;
import org.alfresco.filesys.util.DataBuffer;
import org.alfresco.filesys.util.IPAddress;
import org.alfresco.filesys.util.X64;
/**
* Win32 NetBIOS Native Call Wrapper Class
*/
public class Win32NetBIOS
{
// Constants
//
// FIND_NAME_BUFFER structure length
protected final static int FindNameBufferLen = 33;
// Exception if the native code DLL load failed
private static Throwable m_loadDLLException;
/**
* Check if the native code was loaded successfully
*
* @return boolean
*/
public static final boolean isInitialized()
{
return m_loadDLLException == null ? true : false;
}
/**
* Return the native code load exception
*
* @return Throwable
*/
public static final Throwable getInitializationException()
{
return m_loadDLLException;
}
/**
* Check if NetBIOS is enabled on any network adapters
*
* @return boolean
*/
public static final boolean isAvailable() {
// Check if the DLL was loaded successfully
if ( isInitialized() == false)
return false;
// Check if there are any valid LANAs, if not then NetBIOS is not enabled or network
// adapters that have NetBIOS enabled are not currently enabled
int[] lanas = LanaEnum();
if ( lanas != null && lanas.length > 0)
return true;
return false;
}
/**
* Add a NetBIOS name to the local name table
*
* @param lana int
* @param name byte[]
* @return int
*/
public static native int AddName(int lana, byte[] name);
/**
* Add a group NetBIOS name to the local name table
*
* @param lana int
* @param name byte[]
* @return int
*/
public static native int AddGroupName(int lana, byte[] name);
/**
* Find a NetBIOS name, return the name buffer
*
* @param lana int
* @param name byte[]
* @param nameBuf byte[]
* @param bufLen int
* @return int
*/
public static native int FindNameRaw(int lana, byte[] name, byte[] nameBuf, int bufLen);
/**
* Find a NetBIOS name
*
* @param lana int
* @param name NetBIOSName
* @return int
*/
public static int FindName(int lana, NetBIOSName nbName)
{
// Allocate a buffer to receive the name details
byte[] nameBuf = new byte[nbName.isGroupName() ? 65535 : 4096];
// Get the raw NetBIOS name data
int sts = FindNameRaw(lana, nbName.getNetBIOSName(), nameBuf, nameBuf.length);
if (sts != NetBIOS.NRC_GoodRet)
return -sts;
// Unpack the FIND_NAME_HEADER structure
DataBuffer buf = new DataBuffer(nameBuf, 0, nameBuf.length);
int nodeCount = buf.getShort();
buf.skipBytes(1);
boolean isGroupName = buf.getByte() == 0 ? false : true;
// Unpack the FIND_NAME_BUFFER structures
int curPos = buf.getPosition();
for (int i = 0; i < nodeCount; i++)
{
// FIND_NAME_BUFFER:
// UCHAR length
// UCHAR access_control
// UCHAR frame_control
// UCHAR destination_addr[6]
// UCHAR source_addr[6]
// UCHAR routing_info[18]
// Skip to the source_addr field
buf.skipBytes(9);
// Source address field format should be 0.0.n.n.n.n for TCP/IP address
if (buf.getByte() == 0 && buf.getByte() == 0)
{
// Looks like a TCP/IP format address, unpack it
byte[] ipAddr = new byte[4];
ipAddr[0] = (byte) buf.getByte();
ipAddr[1] = (byte) buf.getByte();
ipAddr[2] = (byte) buf.getByte();
ipAddr[3] = (byte) buf.getByte();
// Add the address to the list of TCP/IP addresses for the NetBIOS name
nbName.addIPAddress(ipAddr);
// Skip to the start of the next FIND_NAME_BUFFER structure
curPos += FindNameBufferLen;
buf.setPosition(curPos);
}
}
// Return the node count
return nodeCount;
}
/**
* Delete a NetBIOS name from the local name table
*
* @param lana int
* @param name byte[]
* @return int
*/
public static native int DeleteName(int lana, byte[] name);
/**
* Enumerate the available LANAs
*
* @return int[]
*/
public static int[] LanaEnumerate()
{
// Make sure that there is an active network adapter as making calls to the LanaEnum native call
// causes problems when there are no active network adapters.
boolean adapterAvail = false;
try
{
// Enumerate the available network adapters and check for an active adapter, not including
// the loopback adapter
Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
while ( nis.hasMoreElements() && adapterAvail == false)
{
NetworkInterface ni = nis.nextElement();
if ( ni.getName().equals("lo") == false)
{
// Make sure the adapter has a valid IP address
Enumeration<InetAddress> addrs = ni.getInetAddresses();
if ( addrs.hasMoreElements())
adapterAvail = true;
}
}
}
catch ( SocketException ex)
{
}
// Check if there are network adapter(s) available
if ( adapterAvail == false)
return null;
// Call the native code to return the available LANA list
return LanaEnum();
}
/**
* Enumerate the available LANAs
*
* @return int[]
*/
private static native int[] LanaEnum();
/**
* Reset the NetBIOS environment
*
* @param lana int
* @return int
*/
public static native int Reset(int lana);
/**
* Listen for an incoming session request
*
* @param lana int
* @param toName byte[]
* @param fromName byte[]
* @param callerName byte[]
* @return int
*/
public static native int Listen(int lana, byte[] toName, byte[] fromName, byte[] callerName);
/**
* Receive a data packet on a session
*
* @param lana int
* @param lsn int
* @param buf byte[]
* @param off int
* @param maxLen int
* @return int
*/
public static native int Receive(int lana, int lsn, byte[] buf, int off, int maxLen);
/**
* Send a data packet on a session
*
* @param lana int
* @param lsn int
* @param buf byte[]
* @param off int
* @param len int
* @return int
*/
public static native int Send(int lana, int lsn, byte[] buf, int off, int len);
/**
* Send a datagram to a specified name
*
* @param lana int
* @param srcNum int
* @param destName byte[]
* @param buf byte[]
* @param off int
* @param len int
* @return int
*/
public static native int SendDatagram(int lana, int srcNum, byte[] destName, byte[] buf, int off, int len);
/**
* Send a broadcast datagram
*
* @param lana
* @param buf byte[]
* @param off int
* @param len int
* @return int
*/
public static native int SendBroadcastDatagram(int lana, byte[] buf, int off, int len);
/**
* Receive a datagram on a specified name
*
* @param lana int
* @param nameNum int
* @param buf byte[]
* @param off int
* @param maxLen int
* @return int
*/
public static native int ReceiveDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
/**
* Receive a broadcast datagram
*
* @param lana int
* @param nameNum int
* @param buf byte[]
* @param off int
* @param maxLen int
* @return int
*/
public static native int ReceiveBroadcastDatagram(int lana, int nameNum, byte[] buf, int off, int maxLen);
/**
* Hangup a session
*
* @param lsn int
* @return int
*/
public static native int Hangup(int lana, int lsn);
/**
* Return the local computers NetBIOS name
*
* @return String
*/
public static native String GetLocalNetBIOSName();
/**
* Return the local domain name
*
* @return String
*/
public static native String GetLocalDomainName();
/**
* Return a comma delimeted list of WINS server TCP/IP addresses, or null if no WINS servers are
* configured.
*
* @return String
*/
public static native String getWINSServerList();
/**
* Find the TCP/IP address for a LANA
*
* @param lana int
* @return String
*/
public static final String getIPAddressForLANA(int lana)
{
// Get the local NetBIOS name
String localName = GetLocalNetBIOSName();
if (localName == null)
return null;
// Create a NetBIOS name for the local name
NetBIOSName nbName = new NetBIOSName(localName, NetBIOSName.WorkStation, false);
// Get the local NetBIOS name details
int sts = FindName(lana, nbName);
if (sts == -NetBIOS.NRC_EnvNotDef)
{
// Reset the LANA then try the name lookup again
Reset(lana);
sts = FindName(lana, nbName);
}
// Check if the name lookup was successful
String ipAddr = null;
if (sts >= 0)
{
// Get the first IP address from the list
ipAddr = nbName.getIPAddressString(0);
}
// Return the TCP/IP address for the LANA
return ipAddr;
}
/**
* Find the adapter name for a LANA
*
* @param lana int
* @return String
*/
public static final String getAdapterNameForLANA(int lana)
{
// Get the TCP/IP address for a LANA
String ipAddr = getIPAddressForLANA(lana);
if (ipAddr == null)
return null;
// Get the list of available network adapters
Hashtable<String, NetworkInterface> adapters = getNetworkAdapterList();
String adapterName = null;
if (adapters != null)
{
// Find the network adapter for the TCP/IP address
NetworkInterface ni = adapters.get(ipAddr);
if (ni != null)
adapterName = ni.getDisplayName();
}
// Return the adapter name for the LANA
return adapterName;
}
/**
* Find the LANA for a TCP/IP address
*
* @param addr String
* @return int
*/
public static final int getLANAForIPAddress(String addr)
{
// Check if the address is a numeric TCP/IP address
if (IPAddress.isNumericAddress(addr) == false)
return -1;
// Get a list of the available NetBIOS LANAs
int[] lanas = LanaEnum();
if (lanas == null || lanas.length == 0)
return -1;
// Search for the LANA with the matching TCP/IP address
for (int i = 0; i < lanas.length; i++)
{
// Get the current LANAs TCP/IP address
String curAddr = getIPAddressForLANA(lanas[i]);
if (curAddr != null && curAddr.equals(addr))
return lanas[i];
}
// Failed to find the LANA for the specified TCP/IP address
return -1;
}
/**
* Find the LANA for a network adapter
*
* @param name String
* @return int
*/
public static final int getLANAForAdapterName(String name)
{
// Get the list of available network adapters
Hashtable<String, NetworkInterface> niList = getNetworkAdapterList();
// Search for the address of the specified network adapter
Enumeration<String> niEnum = niList.keys();
while (niEnum.hasMoreElements())
{
// Get the current TCP/IP address
String ipAddr = niEnum.nextElement();
NetworkInterface ni = niList.get(ipAddr);
if (ni.getName().equalsIgnoreCase(name))
{
// Return the LANA for the network adapters TCP/IP address
return getLANAForIPAddress(ipAddr);
}
}
// Failed to find matching network adapter
return -1;
}
/**
* Return a hashtable of NetworkInterfaces indexed by TCP/IP address
*
* @return Hashtable<String,NetworkInterface>
*/
private static final Hashtable<String, NetworkInterface> getNetworkAdapterList()
{
// Get a list of the local network adapters
Hashtable<String, NetworkInterface> niList = new Hashtable<String, NetworkInterface>();
try
{
// Enumerate the available network adapters
Enumeration<NetworkInterface> niEnum = NetworkInterface.getNetworkInterfaces();
while (niEnum.hasMoreElements())
{
// Get the current network interface details
NetworkInterface ni = niEnum.nextElement();
Enumeration<InetAddress> addrEnum = ni.getInetAddresses();
while (addrEnum.hasMoreElements())
{
// Get the address and add the adapter to the list indexed via the numeric IP
// address string
InetAddress addr = addrEnum.nextElement();
niList.put(addr.getHostAddress(), ni);
}
}
}
catch (Exception ex)
{
}
// Return the network adapter list
return niList;
}
//---------- Winsock based NetBIOS interface ----------//
/**
* Initialize the NetBIOS socket interface
*
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native void InitializeSockets()
throws WinsockNetBIOSException;
/**
* Shutdown the NetBIOS socket interface
*/
protected static native void ShutdownSockets();
/**
* Create a NetBIOS socket
*
* @param lana int
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int CreateSocket(int lana)
throws WinsockNetBIOSException;
/**
* Create a NetBIOS datagram socket
*
* @param lana int
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int CreateDatagramSocket(int lana)
throws WinsockNetBIOSException;
/**
* Bind a NetBIOS socket to a name to listen for incoming sessions
*
* @param sockPtr int
* @param name byte[]
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int BindSocket(int sockPtr, byte[] name)
throws WinsockNetBIOSException;
/**
* Listen for an incoming connection
*
* @param sockPtr int
* @param callerName byte[]
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int ListenSocket(int sockPtr, byte[] callerName)
throws WinsockNetBIOSException;
/**
* Close a NetBIOS socket
*
* @param sockPtr int
*/
protected static native void CloseSocket(int sockPtr);
/**
* Send data on a session socket
*
* @param sockPtr int
* @param buf byte[]
* @param off int
* @param len int
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int SendSocket(int sockPtr, byte[] buf, int off, int len)
throws WinsockNetBIOSException;
/**
* Receive data on a session socket
*
* @param sockPtr int
* @param toName byte[]
* @param buf byte[]
* @param off int
* @param maxLen int
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int ReceiveSocket(int sockPtr, byte[] buf, int off, int maxLen)
throws WinsockNetBIOSException;
/**
* Send data on a datagram socket
*
* @param sockPtr int
* @param toName byte[]
* @param buf byte[]
* @param off int
* @param len int
* @return int
* @exception WinsockNetBIOSException If a Winsock error occurs
*/
protected static native int SendSocketDatagram(int sockPtr, byte[] toName, byte[] buf, int off, int len)
throws WinsockNetBIOSException;
/**
* Wait for a network address change event, block until a change occurs or the Winsock NetBIOS
* interface is shut down
*/
public static native void waitForNetworkAddressChange();
/**
* Static initializer used to load the native code library
*/
static
{
// Check if we are running under 64 bit Windows
String dllName = "Win32NetBIOS";
if ( X64.isWindows64())
dllName = "Win32NetBIOSx64";
// Load the Win32 NetBIOS interface library
try
{
System.loadLibrary( dllName);
}
catch (Throwable ex)
{
ex.printStackTrace();
// Save the native code load exception
m_loadDLLException = ex;
}
}
}

View File

@@ -1,231 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
/**
* Winsock Error Codes Class
*
* <p>Contains a list of the error codes that the Win32 Winsock calls may generate, and a method to convert
* to an error text string.
*
* @author GKSpencer
*/
public class WinsockError
{
// Winsock error code constants
public static final int WsaEIntr = 10004;
public static final int WsaEAcces = 10013;
public static final int WsaEFault = 10014;
public static final int WsaEInval = 10022;
public static final int WsaEMfile = 10024;
public static final int WsaEWouldBlock = 10035;
public static final int WsaEInProgress = 10036;
public static final int WsaEAlready = 10037;
public static final int WsaENotSock = 10038;
public static final int WsaEDestAddrReq = 10039;
public static final int WsaEMsgSize = 10040;
public static final int WsaEPrototype = 10041;
public static final int WsaENoProtoOpt = 10042;
public static final int WsaEProtoNoSupp = 10043;
public static final int WsaESocktNoSupp = 10044;
public static final int WsaEOpNotSupp = 10045;
public static final int WsaEPFNoSupport = 10046;
public static final int WsaEAFNoSupport = 10047;
public static final int WsaEAddrInUse = 10048;
public static final int WsaEAddrNotAvail= 10049;
public static final int WsaENetDown = 10050;
public static final int WsaENetUnReach = 10051;
public static final int WsaENetReset = 10052;
public static final int WsaEConnAborted = 10053;
public static final int WsaEConnReset = 10054;
public static final int WsaENoBufs = 10055;
public static final int WsaEIsConn = 10056;
public static final int WsaENotConn = 10057;
public static final int WsaEShutdown = 10058;
public static final int WsaETimedout = 10060;
public static final int WsaEConnRefused = 10061;
public static final int WsaEHostDown = 10064;
public static final int WsaEHostUnreach = 10065;
public static final int WsaEProcLim = 10067;
public static final int WsaSysNotReady = 10091;
public static final int WsaVerNotSupp = 10092;
public static final int WsaNotInit = 10093;
public static final int WsaEDiscon = 10101;
public static final int WsaTypeNotFound = 10109;
public static final int WsaHostNotFound = 11001;
public static final int WsaTryAgain = 11002;
public static final int WsaNoRecovery = 11003;
public static final int WsaNoData = 11004;
/**
* Convert a Winsock error code to a text string
*
* @param sts int
* @return String
*/
public static final String asString(int sts)
{
String errText = null;
switch ( sts)
{
case WsaEIntr:
errText = "Interrupted function call";
break;
case WsaEAcces:
errText = "Permission denied";
break;
case WsaEFault:
errText = "Bad address";
break;
case WsaEInval:
errText = "Invalid argument";
break;
case WsaEMfile:
errText = "Too many open files";
break;
case WsaEWouldBlock:
errText = "Resource temporarily unavailable";
break;
case WsaEInProgress:
errText = "Operation now in progress";
break;
case WsaEAlready:
errText = "Operation already in progress";
break;
case WsaENotSock:
errText = "Socket operation on nonsocket";
break;
case WsaEDestAddrReq:
errText = "Destination address required";
break;
case WsaEMsgSize:
errText = "Message too long";
break;
case WsaEPrototype:
errText = "Protocol wrong type for socket";
break;
case WsaENoProtoOpt:
errText = "Bad protocol option";
break;
case WsaEProtoNoSupp:
errText = "Protocol not supported";
break;
case WsaESocktNoSupp:
errText = "Socket type not supported";
break;
case WsaEOpNotSupp:
errText = "Operation not supported";
break;
case WsaEPFNoSupport:
errText = "Protocol family not supported";
break;
case WsaEAFNoSupport:
errText = "Address family not supported by protocol family";
break;
case WsaEAddrInUse:
errText = "Address already in use";
break;
case WsaEAddrNotAvail:
errText = "Cannot assign requested address";
break;
case WsaENetDown:
errText = "Network is down";
break;
case WsaENetUnReach:
errText = "Network is unreachable";
break;
case WsaENetReset:
errText = "Network dropped connection on reset";
break;
case WsaEConnAborted:
errText = "Software caused connection abort";
break;
case WsaEConnReset:
errText = "Connection reset by peer";
break;
case WsaENoBufs:
errText = "No buffer space available";
break;
case WsaEIsConn:
errText = "Socket is already connected";
break;
case WsaENotConn:
errText = "Socket is not connected";
break;
case WsaEShutdown:
errText = "Cannot send after socket shutdown";
break;
case WsaETimedout:
errText = "Connection timed out";
break;
case WsaEConnRefused:
errText = "Connection refused";
break;
case WsaEHostDown:
errText = "Host is down";
break;
case WsaEHostUnreach:
errText = "No route to host";
break;
case WsaEProcLim:
errText = "Too many processes";
break;
case WsaSysNotReady:
errText = "Network subsystem is unavailable";
break;
case WsaVerNotSupp:
errText = "Winsock.dll version out of range";
break;
case WsaNotInit:
errText = "Successful WSAStartup not yet performed";
break;
case WsaEDiscon:
errText = "Graceful shutdown in progress";
break;
case WsaTypeNotFound:
errText = "Class type not found";
break;
case WsaHostNotFound:
errText = "Host not found";
break;
case WsaTryAgain:
errText = "Nonauthoritative host not found";
break;
case WsaNoRecovery:
errText = "This is a nonrecoverable error";
break;
case WsaNoData:
errText = "Valid name, no data record of requested type";
break;
default:
errText = "Unknown Winsock error 0x" + Integer.toHexString(sts);
break;
}
return errText;
}
}

View File

@@ -1,122 +0,0 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.netbios.win32;
import java.io.IOException;
/**
* Winsock NetBIOS Exception Class
*
* <p>Contains the Winsock error code from the failed Winsock call.
*
* @author GKSpencer
*/
public class WinsockNetBIOSException extends IOException
{
private static final long serialVersionUID = 5933702607108016674L;
// Winsock error code
private int m_errCode;
/**
* Default constructor
*/
public WinsockNetBIOSException()
{
super();
}
/**
* Class constructor
*
* @param msg String
*/
public WinsockNetBIOSException(String msg)
{
super(msg);
// Split out the error code
if ( msg != null)
{
int pos = msg.indexOf(":");
if ( pos != -1)
m_errCode = Integer.valueOf(msg.substring(0, pos));
}
}
/**
* Class constructor
*
* @param sts int
*/
public WinsockNetBIOSException(int sts)
{
super();
m_errCode = sts;
}
/**
* Return the Winsock error code
*
* @return int
*/
public final int getErrorCode()
{
return m_errCode;
}
/**
* Set the error code
*
* @param sts int
*/
public final void setErrorCode(int sts)
{
m_errCode = sts;
}
/**
* Return the error message string
*
* @return String
*/
public String getMessage()
{
StringBuilder msg = new StringBuilder();
msg.append( super.getMessage());
String winsockErr = WinsockError.asString(getErrorCode());
if ( winsockErr != null)
{
msg.append(" - ");
msg.append(winsockErr);
}
return msg.toString();
}
}

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.FileNotFoundException;
import java.io.Serializable;
@@ -33,10 +33,10 @@ import java.util.Stack;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileExistsException;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.util.WildCard;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileExistsException;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.util.WildCard;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileFolderService;

View File

@@ -22,10 +22,11 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import org.alfresco.filesys.CIFSServer;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.CIFSServerBean;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -41,7 +42,7 @@ public class CifsIntegrationTest extends BaseAlfrescoTestCase
public void testGetServerName()
{
CIFSServer cifsServer = (CIFSServer) ctx.getBean("cifsServer");
CIFSServerBean cifsServer = (CIFSServerBean) ctx.getBean("cifsServer");
assertNotNull("No CIFS server available", cifsServer);
// the server might, quite legitimately, not start
if (!cifsServer.isStarted())
@@ -56,7 +57,8 @@ public class CifsIntegrationTest extends BaseAlfrescoTestCase
// Get the primary filesystem, might be null if the home folder mapper is configured
DiskSharedDevice mainFilesys = cifsServer.getConfiguration().getPrimaryFilesystem();
FilesystemsConfigSection filesysConfig = (FilesystemsConfigSection) cifsServer.getConfiguration().getConfigSection(FilesystemsConfigSection.SectionName);
DiskSharedDevice mainFilesys = (DiskSharedDevice) filesysConfig.getShares().enumerateShares().nextElement();
if ( mainFilesys != null)
{

View File

@@ -22,11 +22,12 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.IOControlHandler;
import org.alfresco.filesys.server.filesys.*;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileSystem;
import org.alfresco.service.cmr.repository.*;
/**

View File

@@ -22,7 +22,7 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -34,35 +34,37 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.core.DeviceContext;
import org.alfresco.filesys.server.core.DeviceContextException;
import org.alfresco.filesys.server.core.DeviceInterface;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.AccessMode;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.FileOpenParams;
import org.alfresco.filesys.server.filesys.FileSharingException;
import org.alfresco.filesys.server.filesys.FileStatus;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.filesys.server.filesys.TreeConnection;
import org.alfresco.filesys.server.locking.FileLockingInterface;
import org.alfresco.filesys.server.locking.LockManager;
import org.alfresco.filesys.server.pseudo.MemoryNetworkFile;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFileInterface;
import org.alfresco.filesys.server.pseudo.PseudoFileList;
import org.alfresco.filesys.server.pseudo.PseudoNetworkFile;
import org.alfresco.filesys.server.state.FileState;
import org.alfresco.filesys.server.state.FileStateLockManager;
import org.alfresco.filesys.server.state.FileState.FileStateStatus;
import org.alfresco.filesys.smb.SharingMode;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.util.WildCard;
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
import org.alfresco.filesys.state.FileState;
import org.alfresco.filesys.state.FileState.FileStateStatus;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.core.DeviceContext;
import org.alfresco.jlan.server.core.DeviceContextException;
import org.alfresco.jlan.server.core.DeviceInterface;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.AccessMode;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileOpenParams;
import org.alfresco.jlan.server.filesys.FileSharingException;
import org.alfresco.jlan.server.filesys.FileStatus;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.TreeConnection;
import org.alfresco.jlan.server.filesys.cache.FileStateLockManager;
import org.alfresco.jlan.server.filesys.pseudo.MemoryNetworkFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileInterface;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.jlan.server.filesys.pseudo.PseudoNetworkFile;
import org.alfresco.jlan.server.locking.FileLockingInterface;
import org.alfresco.jlan.server.locking.LockManager;
import org.alfresco.jlan.smb.SharingMode;
import org.alfresco.jlan.smb.server.SMBServer;
import org.alfresco.jlan.smb.server.SMBSrvSession;
import org.alfresco.jlan.util.WildCard;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.cmr.lock.NodeLockedException;
@@ -107,7 +109,6 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Services and helpers
private CifsHelper cifsHelper;
private TransactionService transactionService;
private NamespaceService namespaceService;
private NodeService nodeService;
private SearchService searchService;
@@ -153,16 +154,6 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
return authService;
}
/**
* Return the transaction service
*
* @return TransactionService
*/
public final TransactionService getTransactionService()
{
return this.transactionService;
}
/**
* Return the node service
*
@@ -234,14 +225,6 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
this.searchService = searchService;
}
/**
* @param transactionService the transaction service
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
/**
* Set the permission service
*
@@ -295,13 +278,12 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
* of the shared device. The same DeviceInterface implementation may be used for multiple
* shares.
*
* @param devIface DeviceInterface
* @param name String
* @param shareName String
* @param args ConfigElement
* @return DeviceContext
* @exception DeviceContextException
*/
public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement cfg) throws DeviceContextException
public DeviceContext createContext(String shareName, ConfigElement cfg) throws DeviceContextException
{
// Use the system user as the authenticated context for the filesystem initialization
@@ -309,7 +291,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Wrap the initialization in a transaction
UserTransaction tx = transactionService.getUserTransaction(true);
UserTransaction tx = getTransactionService().getUserTransaction(true);
ContentContext context = null;
@@ -401,7 +383,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the context
context = new ContentContext(name, storeValue, rootPath, rootNodeRef);
context = new ContentContext(shareName, storeValue, rootPath, rootNodeRef);
}
catch (Exception ex)
{
@@ -569,7 +551,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Start a transaction
session.beginReadTransaction(transactionService);
beginReadTransaction( session);
// Get the device root
@@ -731,14 +713,8 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
}
catch (FileNotFoundException e)
{
// Check if there is a transaction active
// Debug
if ( session.hasUserTransaction() == false) {
System.out.println("***** getFileInformation() - no transaction active");
e.printStackTrace();
}
// a valid use case
if (logger.isDebugEnabled())
logger.debug("Getting file information - File not found: \n" +
" path: " + path);
@@ -793,7 +769,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Create the transaction
sess.beginReadTransaction(transactionService);
beginReadTransaction( sess);
// If the state table is available see if we can speed up the search using either cached
// file information or find the folder node to be searched without having to walk the path
@@ -1001,7 +977,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Get the node for the folder path
sess.beginReadTransaction(transactionService);
beginReadTransaction( sess);
fstate.setNodeRef( getNodeForPath( tree, paths[0]));
// Add pseudo files to the folder
@@ -1022,7 +998,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginReadTransaction(transactionService);
beginReadTransaction( sess);
// Get the node for the folder path
@@ -1064,7 +1040,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginReadTransaction(transactionService);
beginReadTransaction( sess);
// Get the file information to check if the file/folder exists
@@ -1120,7 +1096,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginReadTransaction( sess);
try
{
@@ -1252,7 +1228,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
// Check if the node is a link node
NodeRef linkRef = (NodeRef) nodeService.getProperty(nodeRef, ContentModel.PROP_LINK_DESTINATION);
NetworkFile netFile = null;
AlfrescoNetworkFile netFile = null;
if ( linkRef == null)
{
@@ -1262,10 +1238,28 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
}
else
{
// Convert the target node to a path, convert to URL format
String path = getPathForNode( tree, linkRef);
path = path.replace( FileName.DOS_SEPERATOR, '/');
// Get the CIFS server name
String srvName = null;
SMBServer cifsServer = (SMBServer) sess.getServer().getConfiguration().findServer( "CIFS");
if ( cifsServer != null)
{
// Use the CIFS server name in the URL
srvName = cifsServer.getServerName();
}
else
{
// Use the local server name in the URL
srvName = InetAddress.getLocalHost().getHostName();
}
// Convert the target node to a path, convert to URL format
String path = getPathForNode( tree, linkRef);
path = path.replace( FileName.DOS_SEPERATOR, '/');
// Build the URL file data
@@ -1273,7 +1267,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
urlStr.append("[InternetShortcut]\r\n");
urlStr.append("URL=file://");
urlStr.append( sess.getServer().getServerName());
urlStr.append( srvName);
urlStr.append("/");
urlStr.append( tree.getSharedDevice().getName());
urlStr.append( path);
@@ -1380,7 +1374,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
try
{
@@ -1512,7 +1506,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
try
{
@@ -1619,7 +1613,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
// get the device root
@@ -1707,7 +1701,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
// Get the associated file state
@@ -1799,7 +1793,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
// Get the device context
@@ -1876,7 +1870,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
{
// Create the transaction
sess.beginWriteTransaction(transactionService);
beginWriteTransaction( sess);
try
{
@@ -2205,7 +2199,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
ContentNetworkFile contentFile = (ContentNetworkFile) file;
if ( contentFile.hasContent() == false)
sess.beginReadTransaction( transactionService);
beginReadTransaction( sess);
}
// Read a block of data from the file
@@ -2255,7 +2249,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
ContentNetworkFile contentFile = (ContentNetworkFile) file;
if ( contentFile.hasContent() == false)
sess.beginReadTransaction( transactionService);
beginReadTransaction( sess);
// Set the file position
@@ -2285,7 +2279,7 @@ public class ContentDiskDriver extends AlfrescoDiskDriver implements DiskInterfa
ContentNetworkFile contentFile = (ContentNetworkFile) file;
if ( contentFile.hasContent() == false)
sess.beginWriteTransaction( transactionService);
beginReadTransaction( sess);
}
// Write to the file

View File

@@ -22,9 +22,9 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import org.alfresco.filesys.server.filesys.DiskInterface;
import org.alfresco.jlan.server.filesys.DiskInterface;
import org.alfresco.service.cmr.repository.NodeRef;
/**

View File

@@ -20,9 +20,9 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
/**

View File

@@ -22,10 +22,11 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.FileNotFoundException;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.filesys.alfresco.AlfrescoContext;
import org.alfresco.filesys.alfresco.AlfrescoDiskDriver;
import org.alfresco.filesys.alfresco.DesktopAction;
@@ -35,17 +36,15 @@ import org.alfresco.filesys.alfresco.DesktopResponse;
import org.alfresco.filesys.alfresco.DesktopTarget;
import org.alfresco.filesys.alfresco.IOControl;
import org.alfresco.filesys.alfresco.IOControlHandler;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.filesys.IOControlNotImplementedException;
import org.alfresco.filesys.server.filesys.NetworkFile;
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.util.DataBuffer;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.filesys.IOControlNotImplementedException;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.server.filesys.TreeConnection;
import org.alfresco.jlan.smb.SMBException;
import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.jlan.smb.nt.NTIOCtl;
import org.alfresco.jlan.util.DataBuffer;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.cmr.lock.LockType;
@@ -168,7 +167,7 @@ public class ContentIOControlHandler implements IOControlHandler
* @exception IOControlNotImplementedException
* @exception SMBException
*/
public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf,
public org.alfresco.jlan.util.DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf,
boolean isFSCtrl, int filter)
throws IOControlNotImplementedException, SMBException
{
@@ -316,7 +315,7 @@ public class ContentIOControlHandler implements IOControlHandler
{
// Start a transaction
sess.beginReadTransaction( getTransactionService());
contentDriver.beginReadTransaction( sess);
// Get the file name from the request
@@ -562,7 +561,7 @@ public class ContentIOControlHandler implements IOControlHandler
// Start a transaction
sess.beginReadTransaction( getTransactionService());
contentDriver.beginReadTransaction( sess);
// Get an authentication ticket for the client, or validate the existing ticket. The ticket can be used when
// generating URLs for the client-side application so that the user does not have to re-authenticate
@@ -572,7 +571,7 @@ public class ContentIOControlHandler implements IOControlHandler
// Get the list of targets for the action
int targetCnt = reqBuf.getInt();
DesktopParams deskParams = new DesktopParams(sess, folderNode, netFile);
DesktopParams deskParams = new DesktopParams(sess, contentDriver, folderNode, netFile);
while ( reqBuf.getAvailableLength() > 4 && targetCnt > 0)
{
@@ -707,7 +706,7 @@ public class ContentIOControlHandler implements IOControlHandler
// Start a transaction
sess.beginReadTransaction( getTransactionService());
contentDriver.beginReadTransaction( sess);
// Get an authentication ticket for the client, or validate the existing ticket. The ticket can be used when
// generating URLs for the client-side application so that the user does not have to re-authenticate
@@ -716,7 +715,7 @@ public class ContentIOControlHandler implements IOControlHandler
// Pack the response
ClientInfo cInfo = sess.getClientInformation();
AlfrescoClientInfo cInfo = (AlfrescoClientInfo) sess.getClientInformation();
if ( cInfo != null && cInfo.getAuthenticationTicket() != null) {
respBuf.putInt(DesktopAction.StsAuthTicket);
@@ -741,7 +740,7 @@ public class ContentIOControlHandler implements IOControlHandler
{
// Get the client information and check if there is a ticket allocated
ClientInfo cInfo = sess.getClientInformation();
AlfrescoClientInfo cInfo = (AlfrescoClientInfo) sess.getClientInformation();
if ( cInfo == null)
return;

View File

@@ -22,7 +22,7 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
@@ -34,14 +34,14 @@ import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.DiskFullException;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileOpenParams;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.smb.SeekType;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.jlan.server.filesys.AccessDeniedException;
import org.alfresco.jlan.server.filesys.DiskFullException;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileOpenParams;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.jlan.smb.SeekType;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
import org.alfresco.repo.content.filestore.FileContentReader;

View File

@@ -22,18 +22,18 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.FileNotFoundException;
import java.util.List;
import org.alfresco.filesys.server.filesys.FileAttribute;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.FileType;
import org.alfresco.filesys.server.filesys.SearchContext;
import org.alfresco.filesys.server.pseudo.PseudoFile;
import org.alfresco.filesys.server.pseudo.PseudoFileList;
import org.alfresco.jlan.server.filesys.FileAttribute;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.FileType;
import org.alfresco.jlan.server.filesys.SearchContext;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFile;
import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

View File

@@ -23,23 +23,24 @@
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.util.Enumeration;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.ClientInfo;
import org.alfresco.jlan.server.auth.InvalidUserException;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.server.config.ServerConfiguration;
import org.alfresco.jlan.server.core.InvalidDeviceInterfaceException;
import org.alfresco.jlan.server.core.ShareMapper;
import org.alfresco.jlan.server.core.ShareType;
import org.alfresco.jlan.server.core.SharedDevice;
import org.alfresco.jlan.server.core.SharedDeviceList;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection;
import org.alfresco.config.ConfigElement;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.auth.InvalidUserException;
import org.alfresco.filesys.server.config.InvalidConfigurationException;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.server.core.ShareMapper;
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.DiskSharedDevice;
import org.alfresco.filesys.smb.server.repo.ContentContext;
import org.alfresco.filesys.smb.server.repo.ContentDiskDriver;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -61,10 +62,15 @@ public class HomeShareMapper implements ShareMapper
public static final String HOME_FOLDER_SHARE = "HOME";
// Server configuration
// Server configuration and sections
private ServerConfiguration m_config;
private FilesystemsConfigSection m_filesysConfig;
// Filesystem driver to be used to create home shares
private ContentDiskDriver m_driver;
// Home folder share name
private String m_homeShareName = HOME_FOLDER_SHARE;
@@ -92,6 +98,7 @@ public class HomeShareMapper implements ShareMapper
// Save the server configuration
m_config = config;
m_filesysConfig = (FilesystemsConfigSection) m_config.getConfigSection(FilesystemsConfigSection.SectionName);
// Check if the home share name has been specified
@@ -103,6 +110,28 @@ public class HomeShareMapper implements ShareMapper
if (params != null && params.getChild("debug") != null)
m_debug = true;
// Search for a filesystem that uses the content driver to use the driver when creating the home shares
SharedDeviceList shares = m_filesysConfig.getShares();
if ( shares != null)
{
Enumeration<SharedDevice> shrEnum = shares.enumerateShares();
while ( shrEnum.hasMoreElements() && m_driver == null)
{
try
{
SharedDevice curShare = shrEnum.nextElement();
if ( curShare.getInterface() instanceof ContentDiskDriver)
m_driver = (ContentDiskDriver) curShare.getInterface();
}
catch (InvalidDeviceInterfaceException ex)
{
}
}
}
}
/**
@@ -138,26 +167,27 @@ public class HomeShareMapper implements ShareMapper
// Check if the user has a home folder, and the session does not currently have any
// dynamic shares defined
if ( sess != null && sess.hasClientInformation() && sess.hasDynamicShares() == false)
if ( sess != null && sess.hasClientInformation() && sess.hasDynamicShares() == false &&
sess.getClientInformation() instanceof AlfrescoClientInfo)
{
ClientInfo client = sess.getClientInformation();
if ( client.hasHomeFolder())
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) sess.getClientInformation();
if ( alfClient.hasHomeFolder())
{
// Create the home folder share
DiskSharedDevice homeShare = createHomeDiskShare(client);
DiskSharedDevice homeShare = createHomeDiskShare( alfClient);
sess.addDynamicShare(homeShare);
// Debug
if ( logger.isDebugEnabled())
logger.debug("Added " + getHomeFolderName() + " share to list of shares for " + client.getUserName());
logger.debug("Added " + getHomeFolderName() + " share to list of shares for " + alfClient.getUserName());
}
}
// Make a copy of the global share list and add the per session dynamic shares
SharedDeviceList shrList = new SharedDeviceList(m_config.getShares());
SharedDeviceList shrList = new SharedDeviceList(m_filesysConfig.getShares());
if ( sess != null && sess.hasDynamicShares()) {
@@ -193,7 +223,7 @@ public class HomeShareMapper implements ShareMapper
SharedDevice share = null;
if (( typ == ShareType.DISK || typ == ShareType.UNKNOWN) && name.equalsIgnoreCase(getHomeFolderName()) &&
sess.getClientInformation() != null) {
sess.getClientInformation() != null && m_driver != null) {
// Get the client details
@@ -206,56 +236,63 @@ public class HomeShareMapper implements ShareMapper
// Check if the user has a home folder node
if ( client != null && client.hasHomeFolder()) {
if ( client != null && client instanceof AlfrescoClientInfo) {
// Access the extended client information
AlfrescoClientInfo alfClient = (AlfrescoClientInfo) client;
// Check if the share has already been created for the session
if ( sess.hasDynamicShares()) {
// Check if the required share exists in the sessions dynamic share list
share = sess.getDynamicShareList().findShare(name, typ, false);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug(" Reusing existing dynamic share for " + name);
}
// Check if we found a share, if not then create a new dynamic share for the home directory
if ( share == null && create == true) {
// Create the home share mapped to the users home folder
DiskSharedDevice diskShare = createHomeDiskShare(client);
// Add the new share to the sessions dynamic share list
sess.addDynamicShare(diskShare);
share = diskShare;
// DEBUG
if (logger.isDebugEnabled())
logger.debug(" Mapped share " + name + " to " + client.getHomeFolder());
}
if ( alfClient.hasHomeFolder()) {
// Check if the share has already been created for the session
if ( sess.hasDynamicShares()) {
// Check if the required share exists in the sessions dynamic share list
share = sess.getDynamicShareList().findShare(name, typ, false);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug(" Reusing existing dynamic share for " + name);
}
// Check if we found a share, if not then create a new dynamic share for the home directory
if ( share == null && create == true) {
// Create the home share mapped to the users home folder
DiskSharedDevice diskShare = createHomeDiskShare( alfClient);
// Add the new share to the sessions dynamic share list
sess.addDynamicShare(diskShare);
share = diskShare;
// DEBUG
if (logger.isDebugEnabled())
logger.debug(" Mapped share " + name + " to " + alfClient.getHomeFolder());
}
}
else
throw new InvalidUserException("No home directory");
}
else
throw new InvalidUserException("No home directory");
}
else {
// Find the required share by name/type. Use a case sensitive search first, if that fails use a case
// insensitive search.
share = m_config.getShares().findShare(name, typ, false);
share = m_filesysConfig.getShares().findShare(name, typ, false);
if ( share == null) {
// Try a case insensitive search for the required share
share = m_config.getShares().findShare(name, typ, true);
share = m_filesysConfig.getShares().findShare(name, typ, true);
}
}
@@ -291,7 +328,7 @@ public class HomeShareMapper implements ShareMapper
// Get the current share from the list
SharedDevice shr = (SharedDevice) enm.nextElement();
SharedDevice shr = enm.nextElement();
// Close the shared device
@@ -320,20 +357,27 @@ public class HomeShareMapper implements ShareMapper
/**
* Create a disk share for the home folder
*
* @param client ClientInfo
* @param alfClient AlfrescoClientInfo
* @return DiskSharedDevice
*/
private final DiskSharedDevice createHomeDiskShare(ClientInfo client)
private final DiskSharedDevice createHomeDiskShare(AlfrescoClientInfo alfClient)
{
// Create the disk driver and context
// Make sure the client is an Alfresco client
if ( alfClient != null) {
ContentDiskDriver diskDrv = ( ContentDiskDriver) m_config.getDiskInterface();
ContentContext diskCtx = new ContentContext( getHomeFolderName(), "", "", client.getHomeFolder());
// Create the disk driver and context
ContentContext diskCtx = new ContentContext( getHomeFolderName(), "", "", alfClient.getHomeFolder());
diskCtx.enableStateTable( true, m_driver.getStateReaper());
// Create a temporary shared device for the users home directory
return new DiskSharedDevice(getHomeFolderName(), m_driver, diskCtx, SharedDevice.Temporary);
}
diskCtx.enableStateTable( true, diskDrv.getStateReaper());
// Create a temporary shared device for the users home directory
// Invalid client type
return new DiskSharedDevice(getHomeFolderName(), diskDrv, diskCtx, SharedDevice.Temporary);
return null;
}
}

View File

@@ -23,12 +23,12 @@
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import java.io.IOException;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.smb.SeekType;
import org.alfresco.jlan.server.filesys.FileInfo;
import org.alfresco.jlan.smb.SeekType;
import org.alfresco.service.cmr.repository.NodeRef;
/**

View File

@@ -20,17 +20,19 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo;
package org.alfresco.filesys.repo;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.alfresco.AlfrescoNetworkFile;
import org.alfresco.jlan.server.filesys.NetworkFile;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* NodeRef Based Network File Class
*
* @author gkspencer
*/
public abstract class NodeRefNetworkFile extends NetworkFile {
public abstract class NodeRefNetworkFile extends AlfrescoNetworkFile {
// Associated node ref

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo.desk;
package org.alfresco.filesys.repo.desk;
import java.io.Serializable;
import java.util.HashMap;
@@ -30,8 +30,8 @@ import org.alfresco.filesys.alfresco.DesktopAction;
import org.alfresco.filesys.alfresco.DesktopParams;
import org.alfresco.filesys.alfresco.DesktopResponse;
import org.alfresco.filesys.alfresco.DesktopTarget;
import org.alfresco.filesys.server.filesys.FileName;
import org.alfresco.filesys.server.filesys.NotifyChange;
import org.alfresco.jlan.server.filesys.FileName;
import org.alfresco.jlan.server.filesys.NotifyChange;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -85,12 +85,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
// Get required services
TransactionService transService = getServiceRegistry().getTransactionService();
NodeService nodeService = getServiceRegistry().getNodeService();
// Start a transaction
params.getSession().beginWriteTransaction( transService);
params.getDriver().beginWriteTransaction( params.getSession());
// Process the list of target nodes

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo.desk;
package org.alfresco.filesys.repo.desk;
import org.alfresco.filesys.alfresco.DesktopAction;
import org.alfresco.filesys.alfresco.DesktopParams;

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo.desk;
package org.alfresco.filesys.repo.desk;
import java.util.Date;

View File

@@ -21,7 +21,7 @@
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo.desk;
package org.alfresco.filesys.repo.desk;
import java.io.BufferedReader;
import java.io.File;
@@ -39,7 +39,7 @@ import org.alfresco.filesys.alfresco.DesktopAction;
import org.alfresco.filesys.alfresco.DesktopActionException;
import org.alfresco.filesys.alfresco.DesktopParams;
import org.alfresco.filesys.alfresco.DesktopResponse;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.service.cmr.repository.ScriptException;
import org.alfresco.service.cmr.repository.ScriptService;
import org.alfresco.service.transaction.TransactionService;
@@ -280,8 +280,7 @@ public class JavaScriptDesktopAction extends DesktopAction {
// Start a transaction
TransactionService transService = getServiceRegistry().getTransactionService();
params.getSession().beginWriteTransaction( transService);
params.getDriver().beginWriteTransaction( params.getSession());
// Access the script service
@@ -300,7 +299,7 @@ public class JavaScriptDesktopAction extends DesktopAction {
// Start a transaction
params.getSession().beginWriteTransaction( transService);
params.getDriver().beginWriteTransaction( params.getSession());
// Run the script

View File

@@ -20,7 +20,7 @@
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.filesys.smb.server.repo.desk;
package org.alfresco.filesys.repo.desk;
import java.net.InetAddress;
import java.net.UnknownHostException;

Some files were not shown because too many files have changed in this diff Show More