diff --git a/.classpath b/.classpath index df1d168e2b..243cbebc41 100644 --- a/.classpath +++ b/.classpath @@ -1,12 +1,13 @@ - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/.project b/.project index 7e072e9002..2d5992d043 100644 --- a/.project +++ b/.project @@ -1,28 +1,18 @@ - - - Repository - JavaCC Nature - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.ui.externaltools.ExternalToolBuilder - auto,incremental, - - - LaunchConfigHandle - <project>/.externalToolBuilders/JibX.launch - - - - - - org.eclipse.jdt.core.javanature - rk.eclipse.javacc.javaccnature - - + + + Repository + JavaCC Nature + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + rk.eclipse.javacc.javaccnature + + diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index e8f6a6a63d..a927e8abaf 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -399,13 +399,13 @@ - + - + @@ -413,7 +413,7 @@ - + @@ -421,7 +421,7 @@ - + diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 291a7c4168..2abdb1369b 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -115,7 +115,7 @@ + class="org.alfresco.filesys.FileServerConfig"> diff --git a/config/alfresco/file-servers.xml b/config/alfresco/file-servers.xml index 1966844b43..808e225fc9 100644 --- a/config/alfresco/file-servers.xml +++ b/config/alfresco/file-servers.xml @@ -25,6 +25,10 @@ + + + + + + + + + @@ -133,27 +146,25 @@ - - - + + + + + + diff --git a/config/alfresco/network-protocol-context.xml b/config/alfresco/network-protocol-context.xml index 7818434ac1..df6824a477 100644 --- a/config/alfresco/network-protocol-context.xml +++ b/config/alfresco/network-protocol-context.xml @@ -58,7 +58,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -103,7 +103,7 @@ - \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/AlfrescoConfigSection.java b/source/java/org/alfresco/filesys/AlfrescoConfigSection.java new file mode 100644 index 0000000000..3ba8c9a2c9 --- /dev/null +++ b/source/java/org/alfresco/filesys/AlfrescoConfigSection.java @@ -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; + } +} diff --git a/source/java/org/alfresco/filesys/CIFSServer.java b/source/java/org/alfresco/filesys/CIFSServerBean.java similarity index 81% rename from source/java/org/alfresco/filesys/CIFSServer.java rename to source/java/org/alfresco/filesys/CIFSServerBean.java index 784ee5417c..b397ab27ab 100644 --- a/source/java/org/alfresco/filesys/CIFSServer.java +++ b/source/java/org/alfresco/filesys/CIFSServerBean.java @@ -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 serverList = new Vector(); @@ -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 diff --git a/source/java/org/alfresco/filesys/FTPServer.java b/source/java/org/alfresco/filesys/FTPServerBean.java similarity index 85% rename from source/java/org/alfresco/filesys/FTPServer.java rename to source/java/org/alfresco/filesys/FTPServerBean.java index dbf4918eaa..01cb84eba5 100644 --- a/source/java/org/alfresco/filesys/FTPServer.java +++ b/source/java/org/alfresco/filesys/FTPServerBean.java @@ -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 diff --git a/source/java/org/alfresco/filesys/server/config/FileServerConfig.java b/source/java/org/alfresco/filesys/FileServerConfig.java similarity index 79% rename from source/java/org/alfresco/filesys/server/config/FileServerConfig.java rename to source/java/org/alfresco/filesys/FileServerConfig.java index fd9c335b52..000a91c57e 100644 --- a/source/java/org/alfresco/filesys/server/config/FileServerConfig.java +++ b/source/java/org/alfresco/filesys/FileServerConfig.java @@ -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()); } } diff --git a/source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java b/source/java/org/alfresco/filesys/FileServerConfigMBean.java similarity index 97% rename from source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java rename to source/java/org/alfresco/filesys/FileServerConfigMBean.java index a9650d1de2..b9c17b29ab 100644 --- a/source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java +++ b/source/java/org/alfresco/filesys/FileServerConfigMBean.java @@ -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 diff --git a/source/java/org/alfresco/filesys/NFSServer.java b/source/java/org/alfresco/filesys/NFSServerBean.java similarity index 88% rename from source/java/org/alfresco/filesys/NFSServer.java rename to source/java/org/alfresco/filesys/NFSServerBean.java index fd90159a3d..39bafe4df8 100644 --- a/source/java/org/alfresco/filesys/NFSServer.java +++ b/source/java/org/alfresco/filesys/NFSServerBean.java @@ -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 diff --git a/source/java/org/alfresco/filesys/ServerConfigurationBean.java b/source/java/org/alfresco/filesys/ServerConfigurationBean.java new file mode 100644 index 0000000000..3d3a195b22 --- /dev/null +++ b/source/java/org/alfresco/filesys/ServerConfigurationBean.java @@ -0,0 +1,2882 @@ +/* + * 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 java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.Socket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.StringTokenizer; + +import org.alfresco.jlan.debug.DebugConfigSection; +import org.alfresco.jlan.ftp.FTPConfigSection; +import org.alfresco.jlan.ftp.FTPPath; +import org.alfresco.jlan.ftp.InvalidPathException; +import org.alfresco.jlan.netbios.NetBIOSName; +import org.alfresco.jlan.netbios.NetBIOSNameList; +import org.alfresco.jlan.netbios.NetBIOSSession; +import org.alfresco.jlan.netbios.RFCNetBIOSProtocol; +import org.alfresco.jlan.netbios.win32.Win32NetBIOS; +import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection; +import org.alfresco.jlan.server.auth.CifsAuthenticator; +import org.alfresco.jlan.server.auth.ClientInfo; +import org.alfresco.jlan.server.auth.acl.ACLParseException; +import org.alfresco.jlan.server.auth.acl.AccessControl; +import org.alfresco.jlan.server.auth.acl.AccessControlList; +import org.alfresco.jlan.server.auth.acl.AccessControlParser; +import org.alfresco.jlan.server.auth.acl.InvalidACLTypeException; +import org.alfresco.jlan.server.auth.passthru.DomainMapping; +import org.alfresco.jlan.server.auth.passthru.RangeDomainMapping; +import org.alfresco.jlan.server.auth.passthru.SubnetDomainMapping; +import org.alfresco.jlan.server.config.GlobalConfigSection; +import org.alfresco.jlan.server.config.InvalidConfigurationException; +import org.alfresco.jlan.server.config.SecurityConfigSection; +import org.alfresco.jlan.server.config.ServerConfiguration; +import org.alfresco.jlan.server.core.DeviceContextException; +import org.alfresco.jlan.server.core.ShareType; +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.smb.server.CIFSConfigSection; +import org.alfresco.jlan.util.IPAddress; +import org.alfresco.jlan.util.Platform; +import org.alfresco.jlan.util.StringList; +import org.alfresco.jlan.util.X64; +import org.alfresco.config.Config; +import org.alfresco.config.ConfigElement; +import org.alfresco.config.ConfigLookupContext; +import org.alfresco.config.ConfigService; +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.filesys.alfresco.AlfrescoClientInfoFactory; +import org.alfresco.filesys.alfresco.DesktopAction; +import org.alfresco.filesys.alfresco.DesktopActionException; +import org.alfresco.filesys.alfresco.DesktopActionTable; +import org.alfresco.filesys.avm.AVMContext; +import org.alfresco.filesys.avm.AVMDiskDriver; +import org.alfresco.filesys.repo.ContentContext; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.repo.security.authentication.NTLMMode; +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; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.w3c.dom.Element; + +import net.sf.acegisecurity.AuthenticationManager; + +/** + * Alfresco File Server Configuration Bean Class + * + * @author gkspencer + */ +public class ServerConfigurationBean extends ServerConfiguration implements ApplicationListener, ApplicationContextAware { + + // Debug logging + + private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); + + // Filesystem configuration constants + + private static final String ConfigArea = "file-servers"; + private static final String ConfigCIFS = "CIFS Server"; + private static final String ConfigFTP = "FTP Server"; + private static final String ConfigNFS = "NFS Server"; + private static final String ConfigFilesystems = "Filesystems"; + private static final String ConfigSecurity = "Filesystem Security"; + + // Server configuration bean name + + public static final String SERVER_CONFIGURATION = "fileServerConfiguration"; + + // SMB/CIFS session debug type strings + // + // Must match the bit mask order + + private static final String m_sessDbgStr[] = { "NETBIOS", "STATE", "RXDATA", "TXDATA", "DUMPDATA", "NEGOTIATE", "TREE", "SEARCH", "INFO", "FILE", + "FILEIO", "TRANSACT", "ECHO", "ERROR", "IPC", "LOCK", "PKTTYPE", "DCERPC", "STATECACHE", "TIMING", "NOTIFY", + "STREAMS", "SOCKET" }; + + // FTP server debug type strings + + private static final String m_ftpDebugStr[] = { "STATE", "SEARCH", "INFO", "FILE", "FILEIO", "ERROR", "PKTTYPE", + "TIMING", "DATAPORT", "DIRECTORY" }; + + // Default FTP server port + + private static final int DefaultFTPServerPort = 21; + + // Default FTP anonymous account name + + private static final String DefaultFTPAnonymousAccount = "anonymous"; + + // NFS server debug type strings + + private static final String m_nfsDebugStr[] = { "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE", + "FILEIO", "ERROR", "TIMING", "DIRECTORY", "SESSION" }; + + // Token name to substitute current server name into the CIFS server name + + private static final String TokenLocalName = "${localname}"; + + // Authentication manager + + private AuthenticationManager m_authenticationManager; + + // Configuration service + + private ConfigService m_configService; + + // Disk interface to use for shared filesystems + + private DiskInterface m_repoDiskInterface; + + // AVM filesystem interface + + private DiskInterface m_avmDiskInterface; + + // Runtime platform type + + private Platform.Type m_platform = Platform.Type.Unchecked; + + // flag to indicate successful initialization + + private boolean m_initialised; + + // 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; + + // Local server name and domain/workgroup name + + private String m_localName; + private String m_localDomain; + + /** + * Default constructor + */ + public ServerConfigurationBean() + { + super ( ""); + } + + /** + * Class constructor + * + * @param srvName String + */ + public ServerConfigurationBean( String srvName) + { + super( srvName); + } + + /** + * Set the authentication manager + * + * @param authenticationManager AuthenticationManager + */ + public void setAuthenticationManager(AuthenticationManager authenticationManager) + { + m_authenticationManager = authenticationManager; + } + + /** + * Set the authentication service + * + * @param authenticationService AuthenticationService + */ + public void setAuthenticationService(AuthenticationService authenticationService) + { + m_authenticationService = authenticationService; + } + + /** + * Set the configuration service + * + * @param configService ConfigService + */ + public void setConfigService(ConfigService configService) + { + m_configService = configService; + } + + /** + * Set the filesystem driver for the node service based filesystem + * + * @param diskInterface DiskInterface + */ + public void setDiskInterface(DiskInterface diskInterface) + { + m_repoDiskInterface = diskInterface; + } + + /** + * Set the filesystem driver for the AVM based filesystem + * + */ + public void setAvmDiskInterface(DiskInterface diskInterface) + { + m_avmDiskInterface = diskInterface; + } + + /** + * Set the authentication component + * + * @param component AuthenticationComponent + */ + public void setAuthenticationComponent(AuthenticationComponent component) + { + m_authenticationComponent = component; + } + + /** + * Set the node service + * + * @param service NodeService + */ + public void setNodeService(NodeService service) + { + m_nodeService = service; + } + + /** + * Set the person service + * + * @param service PersonService + */ + public void setPersonService(PersonService service) + { + m_personService = service; + } + + /** + * Set the transaction service + * + * @param service TransactionService + */ + public void setTransactionService(TransactionService service) + { + m_transactionService = service; + } + + /** + * Set the tenant service + * + * @param tenantService TenantService + */ + public void setTenantService(TenantService tenantService) + { + m_tenantService = tenantService; + } + + /** + * Set the search service + * + * @param searchService SearchService + */ + public void setSearchService(SearchService searchService) + { + m_searchService = searchService; + } + + /** + * Set the namespace service + * + * @param namespaceService NamespaceService + */ + public void setNamespaceService(NamespaceService namespaceService) + { + m_namespaceService = namespaceService; + } + + /** + * Check if the configuration has been initialized + * + * @return Returns true if the configuration was fully initialised + */ + public boolean isInitialised() + { + return m_initialised; + } + + /** + * Check if the SMB server is enabled + * + * @return boolean + */ + public final boolean isSMBServerEnabled() + { + return hasConfigSection( CIFSConfigSection.SectionName); + } + + /** + * Check if the FTP server is enabled + * + * @return boolean + */ + public final boolean isFTPServerEnabled() + { + return hasConfigSection( FTPConfigSection.SectionName); + } + + /** + * Check if the NFS server is enabled + * + * @return boolean + */ + public final boolean isNFSServerEnabled() + { + return hasConfigSection( NFSConfigSection.SectionName); + } + + /** + * 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; + } + + /** + * Initialize the configuration using the configuration service + */ + public void init() + { + // check that all required properties have been set + if (m_authenticationManager == null) + { + throw new AlfrescoRuntimeException("Property 'authenticationManager' not set"); + } + else if (m_authenticationComponent == null) + { + throw new AlfrescoRuntimeException("Property 'authenticationComponent' not set"); + } + else if (m_authenticationService == null) + { + throw new AlfrescoRuntimeException("Property 'authenticationService' not set"); + } + else if (m_nodeService == null) + { + throw new AlfrescoRuntimeException("Property 'nodeService' not set"); + } + else if (m_personService == null) + { + throw new AlfrescoRuntimeException("Property 'personService' not set"); + } + else if (m_transactionService == null) + { + throw new AlfrescoRuntimeException("Property 'transactionService' not set"); + } + else if (m_repoDiskInterface == null) + { + throw new AlfrescoRuntimeException("Property 'diskInterface' not set"); + } + else if (m_configService == null) + { + throw new AlfrescoRuntimeException("Property 'configService' not set"); + } + + // Create the configuration context + + ConfigLookupContext configCtx = new ConfigLookupContext(ConfigArea); + + // Set the platform type + + determinePlatformType(); + + // Create the debug output configuration using a logger for all file server debug output + + DebugConfigSection debugConfig = new DebugConfigSection( this); + try + { + debugConfig.setDebug("org.alfresco.filesys.debug.FileServerDebugInterface", null); + } + catch ( InvalidConfigurationException ex) + { + } + + // Create the global configuration and Alfresco configuration sections + + new GlobalConfigSection( this); + new AlfrescoConfigSection( this); + + // Install the Alfresco client information factory + + ClientInfo.setFactory( new AlfrescoClientInfoFactory()); + + // Initialize the filesystems + + boolean filesysInitOK = false; + Config config = null; + + try + { + // Process the security configuration + + config = m_configService.getConfig(ConfigSecurity, configCtx); + processSecurityConfig(config); + + // Process the filesystems configuration + + config = m_configService.getConfig(ConfigFilesystems, configCtx); + processFilesystemsConfig(config); + + // Indicate that the filesystems were initialized + + filesysInitOK = true; + } + catch (Exception ex) + { + // Configuration error + + logger.error("File server configuration error, " + ex.getMessage(), ex); + } + + // Initialize the CIFS and FTP servers, if the filesystem(s) initialized successfully + + if ( filesysInitOK == true) + { + // Initialize the CIFS server + + try + { + + // Process the CIFS server configuration + + config = m_configService.getConfig(ConfigCIFS, configCtx); + processCIFSServerConfig(config); + + // Log the successful startup + + logger.info("CIFS server " + (isSMBServerEnabled() ? "" : "NOT ") + "started"); + } + catch (UnsatisfiedLinkError ex) + { + // Error accessing the Win32NetBIOS DLL code + + logger.error("Error accessing Win32 NetBIOS, check DLL is on the path"); + + // Disable the CIFS server + + removeConfigSection( CIFSConfigSection.SectionName); + } + catch (Throwable ex) + { + // Configuration error + + logger.error("CIFS server configuration error, " + ex.getMessage(), ex); + + // Disable the CIFS server + + removeConfigSection( CIFSConfigSection.SectionName); + } + + // Initialize the FTP server + + try + { + // Process the FTP server configuration + + config = m_configService.getConfig(ConfigFTP, configCtx); + processFTPServerConfig(config); + + // Log the successful startup + + logger.info("FTP server " + (isFTPServerEnabled() ? "" : "NOT ") + "started"); + } + catch (Exception ex) + { + // Configuration error + + logger.error("FTP server configuration error, " + ex.getMessage(), ex); + } + + // Initialize the NFS server + + try + { + // Process the NFS server configuration + + config = m_configService.getConfig(ConfigNFS, configCtx); + processNFSServerConfig(config); + + // Log the successful startup + + logger.info("NFS server " + (isNFSServerEnabled() ? "" : "NOT ") + "started"); + } + catch (Exception ex) + { + // Configuration error + + logger.error("NFS server configuration error, " + ex.getMessage(), ex); + } + } + else + { + // Log the error + + logger.error("CIFS and FTP servers not started due to filesystem initialization error"); + } + } + + /** + * Close the configuration bean + */ + public final void closeConfiguration() + { + super.closeConfiguration(); + } + + /** + * Determine the platform type + */ + private final void determinePlatformType() + { + if ( m_platform == Platform.Type.Unchecked) + m_platform = Platform.isPlatformType(); + } + + /** + * Process the CIFS server configuration + * + * @param config Config + */ + private final void processCIFSServerConfig(Config config) + { + // If the configuration section is not valid then CIFS is disabled + + if ( config == null) + { + removeConfigSection( CIFSConfigSection.SectionName); + return; + } + + // Check if the server has been disabled + + ConfigElement elem = config.getConfigElement( "serverEnable"); + if ( elem != null) + { + // Check for the enabled attribute + + String srvEnable = elem.getAttribute( "enabled"); + if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) + { + removeConfigSection( CIFSConfigSection.SectionName); + return; + } + } + + // Create the CIFS server configuration section + + CIFSConfigSection cifsConfig = new CIFSConfigSection( this); + + try + { + // Get the network broadcast address + // + // Note: We need to set this first as the call to getLocalDomainName() may use a NetBIOS + // name lookup, so the broadcast mask must be set before then. + + elem = config.getConfigElement("broadcast"); + if (elem != null) + { + + // Check if the broadcast mask is a valid numeric IP address + + if (IPAddress.isNumericAddress(elem.getValue()) == false) + throw new AlfrescoRuntimeException("Invalid broadcast mask, must be n.n.n.n format"); + + // Set the network broadcast mask + + cifsConfig.setBroadcastMask(elem.getValue()); + } + + // Get the host configuration + + elem = config.getConfigElement("host"); + if (elem == null) + throw new AlfrescoRuntimeException("CIFS server host settings not specified"); + + String hostName = elem.getAttribute("name"); + if (hostName == null || hostName.length() == 0) + throw new AlfrescoRuntimeException("Host name not specified or invalid"); + + // Check if the host name contains the local name token + + int pos = hostName.indexOf(TokenLocalName); + if (pos != -1) + { + + // Get the local server name + + String srvName = getLocalServerName(true); + + // Rebuild the host name substituting the token with the local server name + + StringBuilder hostStr = new StringBuilder(); + + hostStr.append(hostName.substring(0, pos)); + hostStr.append(srvName); + + pos += TokenLocalName.length(); + if (pos < hostName.length()) + hostStr.append(hostName.substring(pos)); + + hostName = hostStr.toString(); + + // Make sure the CIFS server name does not match the local server name + + if (hostName.equals(srvName) && getPlatformType() == Platform.Type.WINDOWS) + throw new AlfrescoRuntimeException("CIFS server name must be unique"); + } + + // Check if the host name is longer than 15 characters. NetBIOS only allows a maximum of 16 characters in the + // server name with the last character reserved for the service type. + + if ( hostName.length() > 15) + { + // Truncate the CIFS server name + + hostName = hostName.substring(0, 15); + + // Output a warning + + logger.warn("CIFS server name is longer than 15 characters, truncated to " + hostName); + } + + // Set the CIFS server name + + cifsConfig.setServerName(hostName.toUpperCase()); + setServerName(hostName.toUpperCase()); + + // Get the domain/workgroup name + + String domain = elem.getAttribute("domain"); + if (domain != null && domain.length() > 0) + { + // Set the domain/workgroup name + + cifsConfig.setDomainName(domain.toUpperCase()); + } + else + { + // Get the local domain/workgroup name + + String localDomain = getLocalDomainName(); + + if ( localDomain == null && getPlatformType() != Platform.Type.WINDOWS) + { + // Use a default domain/workgroup name + + localDomain = "WORKGROUP"; + + // Output a warning + + logger.error("Failed to get local domain/workgroup name, using default of " + localDomain); + logger.error("(This may be due to firewall settings or incorrect setting)"); + } + + // Set the local domain/workgroup that the CIFS server belongs to + + cifsConfig.setDomainName( localDomain); + } + + // Check for a server comment + + elem = config.getConfigElement("comment"); + if (elem != null) + cifsConfig.setComment(elem.getValue()); + + // Check for a bind address + + elem = config.getConfigElement("bindto"); + if (elem != null) + { + // Check if the network adapter name has been specified + + if ( elem.hasAttribute("adapter")) { + + // Get the IP address for the adapter + + InetAddress bindAddr = parseAdapterName( elem.getAttribute("adapter")); + + // Set the bind address for the server + + cifsConfig.setSMBBindAddress(bindAddr); + } + else { + + // Validate the bind address + + String bindText = elem.getValue(); + + try + { + // Check the bind address + + InetAddress bindAddr = InetAddress.getByName(bindText); + + // Set the bind address for the server + + cifsConfig.setSMBBindAddress(bindAddr); + } + catch (UnknownHostException ex) + { + throw new AlfrescoRuntimeException("Invalid CIFS server bind address"); + } + } + } + + // Check if an authenticator has been specified + + ConfigElement authElem = config.getConfigElement("authenticator"); + if (authElem != null) + { + // Get the authenticator type + + String authType = authElem.getAttribute("type"); + if (authType == null) + authType = "alfresco"; + + // Get the authentication component type + + NTLMMode ntlmMode = m_authenticationComponent.getNTLMMode(); + + // Set the authenticator class to use + + String authClass = "org.alfresco.filesys.auth.cifs.AlfrescoCifsAuthenticator"; + + if (authType.equalsIgnoreCase("passthru")) + { + // Check if the appropriate authentication component type is configured + + if ( ntlmMode == NTLMMode.MD4_PROVIDER) + throw new AlfrescoRuntimeException("Wrong authentication setup for passthru authenticator (cannot be used with Alfresco users)"); + + // Use the passthru authenticator class + + authClass = "org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator"; + } + else if (authType.equalsIgnoreCase("alfresco")) + { + // Standard authenticator requires MD4 or passthru based authentication + + if ( ntlmMode == NTLMMode.NONE) + throw new AlfrescoRuntimeException("Wrong authentication setup for alfresco authenticator"); + } + else if( authType.equalsIgnoreCase("enterprise")) + { + // Load the Enterprise authenticator dynamically + + authClass = "org.alfresco.filesys.auth.cifs.EnterpriseCifsAuthenticator"; + } + else + throw new AlfrescoRuntimeException("Invalid authenticator type, " + authType); + + // Get the allow guest and map unknown user to guest settings + + boolean allowGuest = authElem.getChild("allowGuest") != null ? true : false; + + // Initialize and set the authenticator class + + cifsConfig.setAuthenticator(authClass, authElem, CifsAuthenticator.USER_MODE, allowGuest); + } + else + throw new AlfrescoRuntimeException("CIFS authenticator not specified"); + + // Check if the host announcer should be enabled + + elem = config.getConfigElement("hostAnnounce"); + if (elem != null) + { + + // Check for an announcement interval + + String interval = elem.getAttribute("interval"); + if (interval != null && interval.length() > 0) + { + try + { + cifsConfig.setHostAnnounceInterval(Integer.parseInt(interval)); + } + catch (NumberFormatException ex) + { + throw new AlfrescoRuntimeException("Invalid host announcement interval"); + } + } + + // Check if the domain name has been set, this is required if the + // host announcer is enabled + + if (cifsConfig.getDomainName() == null) + throw new AlfrescoRuntimeException("Domain name must be specified if host announcement is enabled"); + + // Enable host announcement + + cifsConfig.setHostAnnouncer(true); + } + + // Check if NetBIOS SMB is enabled + + elem = config.getConfigElement("netBIOSSMB"); + if (elem != null) + { + // Check if NetBIOS over TCP/IP is enabled for the current platform + + String platformsStr = elem.getAttribute("platforms"); + boolean platformOK = false; + + if (platformsStr != null) + { + // Parse the list of platforms that NetBIOS over TCP/IP is to be enabled for and + // check if the current platform is included + + EnumSet enabledPlatforms = parsePlatformString(platformsStr); + if (enabledPlatforms.contains(getPlatformType())) + platformOK = true; + } + else + { + // No restriction on platforms + + platformOK = true; + } + + // Enable the NetBIOS SMB support, if enabled for this platform + + cifsConfig.setNetBIOSSMB(platformOK); + + // Parse/check NetBIOS settings, if enabled + + if ( cifsConfig.hasNetBIOSSMB()) + { + // Check if the broadcast mask has been specified + + if (cifsConfig.getBroadcastMask() == null) + throw new AlfrescoRuntimeException("Network broadcast mask not specified"); + + // Check for a bind address + + String bindto = elem.getAttribute("bindto"); + if (bindto != null && bindto.length() > 0) + { + + // Validate the bind address + + try + { + + // Check the bind address + + InetAddress bindAddr = InetAddress.getByName(bindto); + + // Set the bind address for the NetBIOS name server + + cifsConfig.setNetBIOSBindAddress(bindAddr); + } + catch (UnknownHostException ex) + { + throw new AlfrescoRuntimeException("Invalid NetBIOS bind address"); + } + } + else if (cifsConfig.hasSMBBindAddress()) + { + + // Use the SMB bind address for the NetBIOS name server + + cifsConfig.setNetBIOSBindAddress(cifsConfig.getSMBBindAddress()); + } + else + { + // Get a list of all the local addresses + + InetAddress[] addrs = null; + + try + { + // Get the local server IP address list + + addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); + } + catch (UnknownHostException ex) + { + logger.error("Failed to get local address list", ex); + } + + // Check the address list for one or more valid local addresses filtering out the loopback address + + int addrCnt = 0; + + if ( addrs != null) + { + for (int i = 0; i < addrs.length; i++) + { + + // Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses + + if (addrs[i].getHostAddress().equals("127.0.0.1") == false + && addrs[i].getHostAddress().equals("0.0.0.0") == false) + addrCnt++; + } + } + + // Check if any addresses were found + + if ( addrCnt == 0) + { + // Enumerate the network adapter list + + Enumeration niEnum = null; + + try + { + niEnum = NetworkInterface.getNetworkInterfaces(); + } + catch (SocketException ex) + { + } + + if ( niEnum != null) + { + while ( niEnum.hasMoreElements()) + { + // Get the current network interface + + NetworkInterface ni = niEnum.nextElement(); + + // Enumerate the addresses for the network adapter + + Enumeration niAddrs = ni.getInetAddresses(); + if ( niAddrs != null) + { + // Check for any valid addresses + + while ( niAddrs.hasMoreElements()) + { + InetAddress curAddr = niAddrs.nextElement(); + + if ( curAddr.getHostAddress().equals("127.0.0.1") == false && + curAddr.getHostAddress().equals("0.0.0.0") == false) + addrCnt++; + } + } + } + + // DEBUG + + if ( addrCnt > 0 && logger.isDebugEnabled()) + logger.debug("Found valid IP address from interface list"); + } + + // Check if we found any valid network addresses + + if ( addrCnt == 0) + { + // Log the available IP addresses + + if ( logger.isDebugEnabled()) + { + logger.debug("Local address list dump :-"); + if ( addrs != null) + { + for ( int i = 0; i < addrs.length; i++) + logger.debug( " Address: " + addrs[i]); + } + else + logger.debug(" No addresses"); + } + + // Throw an exception to stop the CIFS/NetBIOS name server from starting + + throw new AlfrescoRuntimeException( "Failed to get IP address(es) for the local server, check hosts file and/or DNS setup"); + } + } + } + + // Check if the session port has been specified + + String portNum = elem.getAttribute("sessionPort"); + if ( portNum != null && portNum.length() > 0) { + try { + cifsConfig.setSessionPort(Integer.parseInt(portNum)); + if ( cifsConfig.getSessionPort() <= 0 || cifsConfig.getSessionPort() >= 65535) + throw new AlfrescoRuntimeException("NetBIOS session port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NetBIOS session port"); + } + } + + // Check if the name port has been specified + + portNum = elem.getAttribute("namePort"); + if ( portNum != null && portNum.length() > 0) { + try { + cifsConfig.setNameServerPort(Integer.parseInt(portNum)); + if ( cifsConfig.getNameServerPort() <= 0 || cifsConfig.getNameServerPort() >= 65535) + throw new AlfrescoRuntimeException("NetBIOS name port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NetBIOS name port"); + } + } + + // Check if the datagram port has been specified + + portNum = elem.getAttribute("datagramPort"); + if ( portNum != null && portNum.length() > 0) { + try { + cifsConfig.setDatagramPort(Integer.parseInt(portNum)); + if ( cifsConfig.getDatagramPort() <= 0 || cifsConfig.getDatagramPort() >= 65535) + throw new AlfrescoRuntimeException("NetBIOS datagram port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NetBIOS datagram port"); + } + } + + // Check for a bind address + + String attr = elem.getAttribute("bindto"); + if ( attr != null && attr.length() > 0) { + + // Validate the bind address + + try { + + // Check the bind address + + InetAddress bindAddr = InetAddress.getByName(attr); + + // Set the bind address for the NetBIOS name server + + cifsConfig.setNetBIOSBindAddress(bindAddr); + } + catch (UnknownHostException ex) { + throw new InvalidConfigurationException(ex.toString()); + } + } + + // Check for a bind address using the adapter name + + else if ( elem.hasAttribute("adapter")) { + + // Get the bind address via the network adapter name + + InetAddress bindAddr = parseAdapterName( elem.getAttribute("adapter")); + cifsConfig.setNetBIOSBindAddress( bindAddr); + } + else if ( cifsConfig.hasSMBBindAddress()) { + + // Use the SMB bind address for the NetBIOS name server + + cifsConfig.setNetBIOSBindAddress(cifsConfig.getSMBBindAddress()); + } + + } + } + else + { + + // Disable NetBIOS SMB support + + cifsConfig.setNetBIOSSMB(false); + } + + // Check if TCP/IP SMB is enabled + + elem = config.getConfigElement("tcpipSMB"); + if (elem != null) + { + + // Check if native SMB is enabled for the current platform + + String platformsStr = elem.getAttribute("platforms"); + boolean platformOK = false; + + if (platformsStr != null) + { + // Parse the list of platforms that native SMB is to be enabled for and + // check if the current platform is included + + EnumSet enabledPlatforms = parsePlatformString(platformsStr); + if (enabledPlatforms.contains(getPlatformType())) + platformOK = true; + } + else + { + // No restriction on platforms + + platformOK = true; + } + + // Enable the TCP/IP SMB support, if enabled for this platform + + cifsConfig.setTcpipSMB(platformOK); + + // Check if the port has been specified + + String portNum = elem.getAttribute("port"); + if ( portNum != null && portNum.length() > 0) { + try { + cifsConfig.setTcpipSMBPort(Integer.parseInt(portNum)); + if ( cifsConfig.getTcpipSMBPort() <= 0 || cifsConfig.getTcpipSMBPort() >= 65535) + throw new AlfrescoRuntimeException("TCP/IP SMB port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid TCP/IP SMB port"); + } + } + } + else + { + + // Disable TCP/IP SMB support + + cifsConfig.setTcpipSMB(false); + } + + // Check if Win32 NetBIOS is enabled + + elem = config.getConfigElement("Win32NetBIOS"); + if (elem != null) + { + + // Check if the Win32 NetBIOS server name has been specified + + String win32Name = elem.getAttribute("name"); + if (win32Name != null && win32Name.length() > 0) + { + + // Validate the name + + if (win32Name.length() > 16) + throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS name, " + win32Name); + + // Set the Win32 NetBIOS file server name + + cifsConfig.setWin32NetBIOSName(win32Name); + } + + // Check if the Win32 NetBIOS LANA has been specified + + String lanaStr = elem.getAttribute("lana"); + if (lanaStr != null && lanaStr.length() > 0) + { + // Check if the LANA has been specified as an IP address or adapter name + + int lana = -1; + + if ( IPAddress.isNumericAddress( lanaStr)) + { + + // Convert the IP address to a LANA id + + lana = Win32NetBIOS.getLANAForIPAddress( lanaStr); + if ( lana == -1) + throw new AlfrescoRuntimeException( "Failed to convert IP address " + lanaStr + " to a LANA"); + } + else if ( lanaStr.length() > 1 && Character.isLetter( lanaStr.charAt( 0))) { + + // Convert the network adapter to a LANA id + + lana = Win32NetBIOS.getLANAForAdapterName( lanaStr); + if ( lana == -1) + throw new AlfrescoRuntimeException( "Failed to convert network adapter " + lanaStr + " to a LANA"); + } + else { + + try + { + lana = Integer.parseInt(lanaStr); + } + catch (NumberFormatException ex) + { + throw new AlfrescoRuntimeException("Invalid win32 NetBIOS LANA specified"); + } + } + + // LANA should be in the range 0-255 + + if (lana < 0 || lana > 255) + throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS LANA number, " + lana); + + // Set the LANA number + + cifsConfig.setWin32LANA(lana); + } + + // Check if the native NetBIOS interface has been specified, either 'winsock' or 'netbios' + + String nativeAPI = elem.getAttribute("api"); + if ( nativeAPI != null && nativeAPI.length() > 0) + { + // Validate the API type + + boolean useWinsock = true; + + if ( nativeAPI.equalsIgnoreCase("netbios")) + useWinsock = false; + else if ( nativeAPI.equalsIgnoreCase("winsock") == false) + throw new AlfrescoRuntimeException("Invalid NetBIOS API type, spefify 'winsock' or 'netbios'"); + + // Set the NetBIOS API to use + + cifsConfig.setWin32WinsockNetBIOS( useWinsock); + } + + // Force the older NetBIOS API code to be used on 64Bit Windows + + if ( cifsConfig.useWinsockNetBIOS() == true && X64.isWindows64()) + { + // Log a warning + + logger.warn("Using older Netbios() API code"); + + // Use the older NetBIOS API code + + cifsConfig.setWin32WinsockNetBIOS( false); + } + + // Check if the current operating system is supported by the Win32 + // NetBIOS handler + + String osName = System.getProperty("os.name"); + if (osName.startsWith("Windows") + && (osName.endsWith("95") == false && osName.endsWith("98") == false && osName.endsWith("ME") == false)) + { + + // Call the Win32NetBIOS native code to make sure it is initialized + + if ( Win32NetBIOS.LanaEnumerate() != null) + { + // Enable Win32 NetBIOS + + cifsConfig.setWin32NetBIOS(true); + } + else + { + logger.warn("No NetBIOS LANAs available"); + } + } + else + { + + // Win32 NetBIOS not supported on the current operating system + + cifsConfig.setWin32NetBIOS(false); + } + } + else + { + + // Disable Win32 NetBIOS + + cifsConfig.setWin32NetBIOS(false); + } + + // Check if the host announcer should be enabled + + elem = config.getConfigElement("Win32Announce"); + if (elem != null) + { + + // Check for an announcement interval + + String interval = elem.getAttribute("interval"); + if (interval != null && interval.length() > 0) + { + try + { + cifsConfig.setWin32HostAnnounceInterval(Integer.parseInt(interval)); + } + catch (NumberFormatException ex) + { + throw new AlfrescoRuntimeException("Invalid host announcement interval"); + } + } + + // Check if the domain name has been set, this is required if the + // host announcer is enabled + + if (cifsConfig.getDomainName() == null) + throw new AlfrescoRuntimeException("Domain name must be specified if host announcement is enabled"); + + // Enable Win32 NetBIOS host announcement + + cifsConfig.setWin32HostAnnouncer(true); + } + + // Check if NetBIOS and/or TCP/IP SMB have been enabled + + if (cifsConfig.hasNetBIOSSMB() == false && cifsConfig.hasTcpipSMB() == false && cifsConfig.hasWin32NetBIOS() == false) + throw new AlfrescoRuntimeException("NetBIOS SMB, TCP/IP SMB or Win32 NetBIOS must be enabled"); + + // Check if WINS servers are configured + + elem = config.getConfigElement("WINS"); + + if (elem != null) + { + + // Get the primary WINS server + + ConfigElement priWinsElem = elem.getChild("primary"); + + if (priWinsElem == null || priWinsElem.getValue().length() == 0) + throw new AlfrescoRuntimeException("No primary WINS server configured"); + + // Validate the WINS server address + + InetAddress primaryWINS = null; + + try + { + primaryWINS = InetAddress.getByName(priWinsElem.getValue()); + } + catch (UnknownHostException ex) + { + throw new AlfrescoRuntimeException("Invalid primary WINS server address, " + priWinsElem.getValue()); + } + + // Check if a secondary WINS server has been specified + + ConfigElement secWinsElem = elem.getChild("secondary"); + InetAddress secondaryWINS = null; + + if (secWinsElem != null) + { + + // Validate the secondary WINS server address + + try + { + secondaryWINS = InetAddress.getByName(secWinsElem.getValue()); + } + catch (UnknownHostException ex) + { + throw new AlfrescoRuntimeException("Invalid secondary WINS server address, " + + secWinsElem.getValue()); + } + } + + // Set the WINS server address(es) + + cifsConfig.setPrimaryWINSServer(primaryWINS); + if (secondaryWINS != null) + cifsConfig.setSecondaryWINSServer(secondaryWINS); + + // Pass the setting to the NetBIOS session class + + NetBIOSSession.setDefaultWINSServer(primaryWINS); + } + + // Check if WINS is configured, if we are running on Windows and socket based NetBIOS is enabled + + else if (cifsConfig.hasNetBIOSSMB() && getPlatformType() == Platform.Type.WINDOWS) + { + // Get the WINS server list + + String winsServers = Win32NetBIOS.getWINSServerList(); + + if (winsServers != null) + { + // Use the first WINS server address for now + + StringTokenizer tokens = new StringTokenizer(winsServers, ","); + String addr = tokens.nextToken(); + + try + { + // Convert to a network address and check if the WINS server is accessible + + InetAddress winsAddr = InetAddress.getByName(addr); + + Socket winsSocket = new Socket(); + InetSocketAddress sockAddr = new InetSocketAddress( winsAddr, RFCNetBIOSProtocol.NAME_PORT); + + winsSocket.connect(sockAddr, 3000); + winsSocket.close(); + + // Set the primary WINS server address + + cifsConfig.setPrimaryWINSServer(winsAddr); + + // Debug + + if (logger.isDebugEnabled()) + logger.debug("Configuring to use WINS server " + addr); + } + catch (UnknownHostException ex) + { + throw new AlfrescoRuntimeException("Invalid auto WINS server address, " + addr); + } + catch (IOException ex) + { + if ( logger.isDebugEnabled()) + logger.debug("Failed to connect to auto WINS server " + addr); + } + } + } + + // Check if session debug is enabled + + elem = config.getConfigElement("sessionDebug"); + if (elem != null) + { + + // Check for session debug flags + + String flags = elem.getAttribute("flags"); + int sessDbg = 0; + + if (flags != null) + { + + // Parse the flags + + flags = flags.toUpperCase(); + StringTokenizer token = new StringTokenizer(flags, ","); + + while (token.hasMoreTokens()) + { + + // Get the current debug flag token + + String dbg = token.nextToken().trim(); + + // Find the debug flag name + + int idx = 0; + + while (idx < m_sessDbgStr.length && m_sessDbgStr[idx].equalsIgnoreCase(dbg) == false) + idx++; + + if (idx > m_sessDbgStr.length) + throw new AlfrescoRuntimeException("Invalid session debug flag, " + dbg); + + // Set the debug flag + + sessDbg += 1 << idx; + } + } + + // Set the session debug flags + + cifsConfig.setSessionDebugFlags(sessDbg); + } + } + catch ( InvalidConfigurationException ex) + { + throw new AlfrescoRuntimeException( ex.getMessage()); + } + } + + /** + * Process the FTP server configuration + * + * @param config Config + */ + private final void processFTPServerConfig(Config config) + { + // If the configuration section is not valid then FTP is disabled + + if ( config == null) + { + removeConfigSection( FTPConfigSection.SectionName); + return; + } + + // Check if the server has been disabled + + ConfigElement elem = config.getConfigElement( "serverEnable"); + if ( elem != null) + { + // Check for the enabled attribute + + String srvEnable = elem.getAttribute( "enabled"); + if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) + { + removeConfigSection( FTPConfigSection.SectionName); + return; + } + } + + // Create the FTP configuration section + + FTPConfigSection ftpConfig = new FTPConfigSection( this); + + try + { + // Check for a bind address + + elem = config.getConfigElement("bindto"); + if ( elem != null) { + + // Validate the bind address + + String bindText = elem.getValue(); + + try { + + // Check the bind address + + InetAddress bindAddr = InetAddress.getByName(bindText); + + // Set the bind address for the FTP server + + ftpConfig.setFTPBindAddress(bindAddr); + } + catch (UnknownHostException ex) { + throw new AlfrescoRuntimeException("Invalid FTP bindto address, " + elem.getValue()); + } + } + + // Check for an FTP server port + + elem = config.getConfigElement("port"); + if ( elem != null) { + try { + ftpConfig.setFTPPort(Integer.parseInt(elem.getValue())); + if ( ftpConfig.getFTPPort() <= 0 || ftpConfig.getFTPPort() >= 65535) + throw new AlfrescoRuntimeException("FTP server port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid FTP server port"); + } + } + else { + + // Use the default FTP port + + ftpConfig.setFTPPort(DefaultFTPServerPort); + } + + // Check if anonymous login is allowed + + elem = config.getConfigElement("allowAnonymous"); + if ( elem != null) { + + // Enable anonymous login to the FTP server + + ftpConfig.setAllowAnonymousFTP(true); + + // Check if an anonymous account has been specified + + String anonAcc = elem.getAttribute("user"); + if ( anonAcc != null && anonAcc.length() > 0) { + + // Set the anonymous account name + + ftpConfig.setAnonymousFTPAccount(anonAcc); + + // Check if the anonymous account name is valid + + if ( ftpConfig.getAnonymousFTPAccount() == null || ftpConfig.getAnonymousFTPAccount().length() == 0) + throw new AlfrescoRuntimeException("Anonymous FTP account invalid"); + } + else { + + // Use the default anonymous account name + + ftpConfig.setAnonymousFTPAccount(DefaultFTPAnonymousAccount); + } + } + else { + + // Disable anonymous logins + + ftpConfig.setAllowAnonymousFTP(false); + } + + // Check if a root path has been specified + + elem = config.getConfigElement("rootDirectory"); + if ( elem != null) { + + // Get the root path + + String rootPath = elem.getValue(); + + // Validate the root path + + try { + + // Parse the path + + new FTPPath(rootPath); + + // Set the root path + + ftpConfig.setFTPRootPath(rootPath); + } + catch (InvalidPathException ex) { + throw new AlfrescoRuntimeException("Invalid FTP root directory, " + rootPath); + } + } + + // Check if FTP debug is enabled + + elem = config.getConfigElement("debug"); + if (elem != null) { + + // Check for FTP debug flags + + String flags = elem.getAttribute("flags"); + int ftpDbg = 0; + + if ( flags != null) { + + // Parse the flags + + flags = flags.toUpperCase(); + StringTokenizer token = new StringTokenizer(flags,","); + + while ( token.hasMoreTokens()) { + + // Get the current debug flag token + + String dbg = token.nextToken().trim(); + + // Find the debug flag name + + int idx = 0; + + while ( idx < m_ftpDebugStr.length && m_ftpDebugStr[idx].equalsIgnoreCase(dbg) == false) + idx++; + + if ( idx >= m_ftpDebugStr.length) + throw new AlfrescoRuntimeException("Invalid FTP debug flag, " + dbg); + + // Set the debug flag + + ftpDbg += 1 << idx; + } + } + + // Set the FTP debug flags + + ftpConfig.setFTPDebug(ftpDbg); + } + + // Check if a character set has been specified + + elem = config.getConfigElement( "charSet"); + if ( elem != null) { + + try { + + // Validate the character set name + + Charset.forName( elem.getValue()); + + // Set the FTP character set + + ftpConfig.setFTPCharacterSet( elem.getValue()); + } + catch ( IllegalCharsetNameException ex) { + throw new AlfrescoRuntimeException("Illegal character set name, " + elem.getValue()); + } + catch ( UnsupportedCharsetException ex) { + throw new AlfrescoRuntimeException("Unsupported character set name, " + elem.getValue()); + } + } + + // Check if an authenticator has been specified + + ConfigElement authElem = config.getConfigElement("authenticator"); + if (authElem != null) + { + // Get the authenticator type + + String authType = authElem.getAttribute("type"); + if (authType == null) + authType = "alfresco"; + + // Get the authentication component type + + NTLMMode ntlmMode = m_authenticationComponent.getNTLMMode(); + + // Set the authenticator class to use + + String authClass = "org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator"; + + if (authType.equalsIgnoreCase("passthru")) + { + // Check if the appropriate authentication component type is configured + + if ( ntlmMode == NTLMMode.MD4_PROVIDER) + throw new AlfrescoRuntimeException("Wrong authentication setup for passthru authenticator (cannot be used with Alfresco users)"); + + // Use the passthru authenticator class + + authClass = "org.alfresco.filesys.auth.ftp.PassthruFtpAuthenticator"; + } + else if (authType.equalsIgnoreCase("alfresco")) + { + // Standard authenticator requires MD4 or passthru based authentication + + if ( ntlmMode == NTLMMode.NONE) + throw new AlfrescoRuntimeException("Wrong authentication setup for alfresco authenticator"); + } + else + throw new AlfrescoRuntimeException("Invalid authenticator type, " + authType); + + // Initialize and set the authenticator class + + ftpConfig.setAuthenticator(authClass, authElem); + } + else + throw new AlfrescoRuntimeException("FTP authenticator not specified"); + + } + catch (InvalidConfigurationException ex) + { + throw new AlfrescoRuntimeException( ex.getMessage()); + } + + } + + /** + * Process the NFS server configuration + * + * @param config Config + */ + private final void processNFSServerConfig(Config config) + { + // If the configuration section is not valid then NFS is disabled + + if ( config == null) + { + removeConfigSection( NFSConfigSection.SectionName); + return; + } + + // Check if the server has been disabled + + ConfigElement elem = config.getConfigElement( "serverEnable"); + if ( elem != null) + { + // Check for the enabled attribute + + String srvEnable = elem.getAttribute( "enabled"); + if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) + { + removeConfigSection( NFSConfigSection.SectionName); + return; + } + } + + // Create the NFS configuration section + + NFSConfigSection nfsConfig = new NFSConfigSection( this); + + try + { + // Check if the port mapper is enabled + + if ( config.getConfigElement("enablePortMapper") != null) + nfsConfig.setNFSPortMapper( true); + + // Check for the thread pool size + + elem = config.getConfigElement("ThreadPool"); + + if ( elem != null) { + + try { + + // Convert the pool size value + + int poolSize = Integer.parseInt(elem.getValue()); + + // Range check the pool size value + + if ( poolSize < 4) + throw new AlfrescoRuntimeException("NFS thread pool size is below minimum of 4"); + + // Set the thread pool size + + nfsConfig.setNFSThreadPoolSize(poolSize); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NFS thread pool size setting, " + elem.getValue()); + } + } + + // NFS packet pool size + + elem = config.getConfigElement("PacketPool"); + + if ( elem != null) { + + try { + + // Convert the packet pool size value + + int pktPoolSize = Integer.parseInt(elem.getValue()); + + // Range check the pool size value + + if ( pktPoolSize < 10) + throw new AlfrescoRuntimeException("NFS packet pool size is below minimum of 10"); + + if ( pktPoolSize < nfsConfig.getNFSThreadPoolSize() + 1) + throw new AlfrescoRuntimeException("NFS packet pool must be at least thread pool size plus one"); + + // Set the packet pool size + + nfsConfig.setNFSPacketPoolSize( pktPoolSize); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NFS packet pool size setting, " + elem.getValue()); + } + } + + // Check for a port mapper server port + + elem = config.getConfigElement("PortMapperPort"); + if ( elem != null) { + try { + nfsConfig.setPortMapperPort( Integer.parseInt(elem.getValue())); + if ( nfsConfig.getPortMapperPort() <= 0 || nfsConfig.getPortMapperPort() >= 65535) + throw new AlfrescoRuntimeException("Port mapper server port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid port mapper server port"); + } + } + + // Check for a mount server port + + elem = config.getConfigElement("MountServerPort"); + if ( elem != null) { + try { + nfsConfig.setMountServerPort( Integer.parseInt(elem.getValue())); + if ( nfsConfig.getMountServerPort() <= 0 || nfsConfig.getMountServerPort() >= 65535) + throw new AlfrescoRuntimeException("Mount server port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid mount server port"); + } + } + + // Check for an NFS server port + + elem = config.getConfigElement("NFSServerPort"); + if ( elem != null) { + try { + nfsConfig.setNFSServerPort( Integer.parseInt(elem.getValue())); + if ( nfsConfig.getNFSServerPort() <= 0 || nfsConfig.getNFSServerPort() >= 65535) + throw new AlfrescoRuntimeException("NFS server port out of valid range"); + } + catch (NumberFormatException ex) { + throw new AlfrescoRuntimeException("Invalid NFS server port"); + } + } + + // Check if NFS debug is enabled + + elem = config.getConfigElement("debug"); + if (elem != null) { + + // Check for NFS debug flags + + String flags = elem.getAttribute("flags"); + int nfsDbg = 0; + + if ( flags != null) { + + // Parse the flags + + flags = flags.toUpperCase(); + StringTokenizer token = new StringTokenizer(flags,","); + + while ( token.hasMoreTokens()) { + + // Get the current debug flag token + + String dbg = token.nextToken().trim(); + + // Find the debug flag name + + int idx = 0; + + while ( idx < m_nfsDebugStr.length && m_nfsDebugStr[idx].equalsIgnoreCase(dbg) == false) + idx++; + + if ( idx >= m_nfsDebugStr.length) + throw new AlfrescoRuntimeException("Invalid NFS debug flag, " + dbg); + + // Set the debug flag + + nfsDbg += 1 << idx; + } + } + + // Set the NFS debug flags + + nfsConfig.setNFSDebug( nfsDbg); + } + + // Check if mount server debug output is enabled + + elem = config.getConfigElement("mountServerDebug"); + if ( elem != null) + nfsConfig.setMountServerDebug( true); + + // Check if portmapper debug output is enabled + + elem = config.getConfigElement("portMapperDebug"); + if ( elem != null) + nfsConfig.setPortMapperDebug(true); + + // Create the RPC authenticator + + elem = config.getConfigElement("rpcAuthenticator"); + if ( elem != null) + { + try + { + // Create the RPC authenticator + + nfsConfig.setRpcAuthenticator( "org.alfresco.filesys.auth.nfs.AlfrescoRpcAuthenticator", elem); + } + catch ( InvalidConfigurationException ex) + { + throw new AlfrescoRuntimeException( ex.getMessage()); + } + } + else + throw new AlfrescoRuntimeException("RPC authenticator configuration missing, require user mappings"); + } + catch ( InvalidConfigurationException ex) + { + throw new AlfrescoRuntimeException( ex.getMessage()); + } + } + + /** + * Process the filesystems configuration + * + * @param config Config + */ + private final void processFilesystemsConfig(Config config) + { + // Get the top level filesystems configuration element + + ConfigElement filesystems = config.getConfigElement("filesystems"); + + // Get the filesystem configuration elements + + List filesysElems = null; + if ( filesystems != null) + { + // Get the list of filesystems + + filesysElems = filesystems.getChildren(); + } + else + { + // Check for the old style configuration + + ConfigElement filesysElem = config.getConfigElement( "filesystem"); + + if (filesysElem != null) + { + // create a list with the single filesys element in + + filesysElems = new ArrayList(1); + filesysElems.add(filesysElem); + } + + // Warn that the configuration is using the old format + + logger.warn("Old style file-servers.xml configuration being used"); + } + + // Create the filesystems configuration section + + FilesystemsConfigSection fsysConfig = new FilesystemsConfigSection( this); + + // Access the security configuration section + + SecurityConfigSection secConfig = (SecurityConfigSection) getConfigSection( SecurityConfigSection.SectionName); + + // Process the filesystems list + + if (filesysElems != null) + { + + // Add the filesystems + + for (int i = 0; i < filesysElems.size(); i++) + { + + // Get the current filesystem configuration + + ConfigElement elem = filesysElems.get(i); + + String filesysType = elem.getName(); + String filesysName = elem.getAttribute("name"); + + try + { + // Check the filesystem type and use the appropriate driver + + DiskSharedDevice filesys = null; + + if ( filesysType.equalsIgnoreCase("avmfilesystem")) + { + // Create a new filesystem driver instance and create a context for + // the new filesystem + + DiskInterface filesysDriver = getAvmDiskInterface(); + AVMContext filesysContext = (AVMContext) filesysDriver.createContext( filesysName, elem); + + // Create the shared filesystem + + filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext); + + // Start the filesystem + + filesysContext.startFilesystem(filesys); + } + else + { + // Create a new filesystem driver instance and create a context for + // the new filesystem + + DiskInterface filesysDriver = getRepoDiskInterface(); + ContentContext filesysContext = (ContentContext) filesysDriver.createContext( filesysName, elem); + + // Check if an access control list has been specified + + AccessControlList acls = null; + ConfigElement aclElem = elem.getChild("accessControl"); + + if (aclElem != null) + { + + // Parse the access control list + + acls = processAccessControlList(secConfig, aclElem); + } + else if (secConfig.hasGlobalAccessControls()) + { + + // Use the global access control list for this disk share + + acls = secConfig.getGlobalAccessControls(); + } + + // Check if change notifications are disabled + + boolean changeNotify = elem.getChild("disableChangeNotification") == null ? true : false; + + // Create the shared filesystem + + filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext); + + // Attach desktop actions to the filesystem + + ConfigElement deskActionsElem = elem.getChild("desktopActions"); + if ( deskActionsElem != null) + { + // Get the desktop actions list + + DesktopActionTable desktopActions = processDesktopActions(deskActionsElem, filesys); + if ( desktopActions != null) + filesysContext.setDesktopActions( desktopActions, filesysDriver); + } + + // Add any access controls to the share + + filesys.setAccessControlList(acls); + + // Enable/disable change notification for this device + + filesysContext.enableChangeHandler(changeNotify); + + // Start the filesystem + + filesysContext.startFilesystem(filesys); + } + + // Add the new filesystem + + fsysConfig.addShare( filesys); + } + catch (DeviceContextException ex) + { + throw new AlfrescoRuntimeException("Error creating filesystem " + filesysName, ex); + } + } + } + else + { + // No filesystems defined + + logger.warn("No filesystems defined"); + } + + // Check if shares should be added for all AVM stores + + ConfigElement avmAllStoresElem = config.getConfigElement( "avmAllStores"); + + if ( avmAllStoresElem != null && getAvmDiskInterface() != null) + { + // Get the list of store names + + AVMDiskDriver avmDriver = (AVMDiskDriver) getAvmDiskInterface(); + StringList storeNames = avmDriver.getAVMStoreNames(); + + // Add shares for each of the store names, if the share name does not already exist + + if ( storeNames != null && storeNames.numberOfStrings() > 0) + { + // Add a share for each store + + for ( int i = 0; i < storeNames.numberOfStrings(); i++) + { + String storeName = storeNames.getStringAt( i); + + // Check if a share of the same name already exists + + if ( fsysConfig.getShares().findShare( storeName, ShareType.DISK, true) == null) + { + // Create the new share for the store + + AVMContext avmContext = new AVMContext( storeName, storeName + ":/", AVMContext.VERSION_HEAD); + avmContext.enableStateTable( true, avmDriver.getStateReaper()); + + // Create the shared filesystem + + fsysConfig.addShare( new DiskSharedDevice( storeName, avmDriver, avmContext)); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug( "Added AVM share " + storeName); + } + } + } + } + } + + /** + * Process the security configuration + * + * @param config Config + */ + private final void processSecurityConfig(Config config) + { + // Create the security configuration section + + SecurityConfigSection secConfig = new SecurityConfigSection( this); + + try + { + // Check if global access controls have been specified + + ConfigElement globalACLs = config.getConfigElement("globalAccessControl"); + if (globalACLs != null) + { + + // Parse the access control list + + AccessControlList acls = processAccessControlList(secConfig, globalACLs); + if (acls != null) + secConfig.setGlobalAccessControls(acls); + } + + // Check if a JCE provider class has been specified + + ConfigElement jceElem = config.getConfigElement("JCEProvider"); + if (jceElem != null) + { + + // Set the JCE provider + + secConfig.setJCEProvider(jceElem.getValue()); + } + else + { + // Use the default Bouncy Castle JCE provider + + secConfig.setJCEProvider("org.bouncycastle.jce.provider.BouncyCastleProvider"); + } + + // Check if a share mapper has been specified + + ConfigElement mapperElem = config.getConfigElement("shareMapper"); + + if ( mapperElem != null) { + + // Check if the shre mapper type has been specified + + String mapperType = mapperElem.getAttribute( "type"); + String mapperClass = null; + + if ( mapperType.equalsIgnoreCase( "multi-tenant")) + mapperClass = "org.alfresco.filesys.alfresco.MultiTenantShareMapper"; + else + { + // Get the share mapper class + + ConfigElement classElem = mapperElem.getChild( "class"); + if ( classElem == null) + throw new InvalidConfigurationException("Share mapper class not specified"); + } + + // Initialize the share mapper + + secConfig.setShareMapper(mapperClass, mapperElem); + } + + // Check if any domain mappings have been specified + + ConfigElement domainMappings = config.getConfigElement( "DomainMappings"); + if ( domainMappings != null) + { + // Get the domain mapping elements + + List mappings = domainMappings.getChildren(); + if ( mappings != null) + { + DomainMapping mapping = null; + + for ( ConfigElement domainMap : mappings) + { + if ( domainMap.getName().equals( "Domain")) + { + // Get the domain name + + String name = domainMap.getAttribute( "name"); + + // Check if the domain is specified by subnet or range + + if ( domainMap.hasAttribute( "subnet")) + { + String subnetStr = domainMap.getAttribute( "subnet"); + String maskStr = domainMap.getAttribute( "mask"); + + // Parse the subnet and mask, to validate and convert to int values + + int subnet = IPAddress.parseNumericAddress( subnetStr); + int mask = IPAddress.parseNumericAddress( maskStr); + + if ( subnet == 0 || mask == 0) + throw new AlfrescoRuntimeException( "Invalid subnet/mask for domain mapping " + name); + + // Create the subnet domain mapping + + mapping = new SubnetDomainMapping( name, subnet, mask); + } + else if ( domainMap.hasAttribute( "rangeFrom")) + { + String rangeFromStr = domainMap.getAttribute( "rangeFrom"); + String rangeToStr = domainMap.getAttribute( "rangeTo"); + + // Parse the range from/to values and convert to int values + + int rangeFrom = IPAddress.parseNumericAddress( rangeFromStr); + int rangeTo = IPAddress.parseNumericAddress( rangeToStr); + + if ( rangeFrom == 0 || rangeTo == 0) + throw new AlfrescoRuntimeException( "Invalid address range domain mapping " + name); + + // Create the subnet domain mapping + + mapping = new RangeDomainMapping( name, rangeFrom, rangeTo); + } + else + throw new AlfrescoRuntimeException( "Invalid domain mapping specified"); + + // Add the domain mapping + + secConfig.addDomainMapping(mapping); + } + } + } + } + } + catch ( InvalidConfigurationException ex) + { + throw new AlfrescoRuntimeException( ex.getMessage()); + } + } + + /** + * Process an access control sub-section and return the access control list + * + * @param secConfig SecurityConfigSection + * @param aclsElem ConfigElement + */ + private final AccessControlList processAccessControlList(SecurityConfigSection secConfig, ConfigElement aclsElem) + { + + // Check if there is an access control manager configured + + if (secConfig.getAccessControlManager() == null) + throw new AlfrescoRuntimeException("No access control manager configured"); + + // Create the access control list + + AccessControlList acls = new AccessControlList(); + + // Check if there is a default access level for the ACL group + + String attrib = aclsElem.getAttribute("default"); + + if (attrib != null && attrib.length() > 0) + { + + // Get the access level and validate + + try + { + + // Parse the access level name + + int access = AccessControlParser.parseAccessTypeString(attrib); + + // Set the default access level for the access control list + + acls.setDefaultAccessLevel(access); + } + catch (InvalidACLTypeException ex) + { + throw new AlfrescoRuntimeException("Default access level error", ex); + } + catch (ACLParseException ex) + { + throw new AlfrescoRuntimeException("Default access level error", ex); + } + } + + // Parse each access control element + + List aclElemList = aclsElem.getChildren(); + + if (aclElemList != null && aclElemList.size() > 0) + { + + // Create the access controls + + for (int i = 0; i < aclsElem.getChildCount(); i++) + { + + // Get the current ACL element + + ConfigElement curAclElem = aclElemList.get(i); + + try + { + // Create the access control and add to the list + + acls.addControl(secConfig.getAccessControlManager().createAccessControl(curAclElem.getName(), curAclElem)); + } + catch (InvalidACLTypeException ex) + { + throw new AlfrescoRuntimeException("Invalid access control type - " + curAclElem.getName()); + } + catch (ACLParseException ex) + { + throw new AlfrescoRuntimeException("Access control parse error (" + curAclElem.getName() + ")", ex); + } + } + } + + // Check if there are no access control rules but the default access level is set to 'None', + // this is not allowed as the share would not be accessible or visible. + + if (acls.getDefaultAccessLevel() == AccessControl.NoAccess && acls.numberOfControls() == 0) + throw new AlfrescoRuntimeException("Empty access control list and default access 'None' not allowed"); + + // Return the access control list + + return acls; + } + + /** + * Process a desktop actions sub-section and return the desktop action table + * + * @param deskActionElem ConfigElement + * @param fileSys DiskSharedDevice + */ + private final DesktopActionTable processDesktopActions(ConfigElement deskActionElem, DiskSharedDevice fileSys) + { + // Get the desktop action configuration elements + + DesktopActionTable desktopActions = null; + List actionElems = deskActionElem.getChildren(); + + if ( actionElems != null) + { + // Check for the global configuration section + + ConfigElement globalConfig = deskActionElem.getChild("global"); + + // Allocate the actions table + + desktopActions = new DesktopActionTable(); + + // Process the desktop actions list + + for ( ConfigElement actionElem : actionElems) + { + if ( actionElem.getName().equals("action")) + { + // Get the desktop action class name or bean id + + ConfigElement className = actionElem.getChild("class"); + if ( className != null) + { + // Load the desktop action class, create a new instance + + Object actionObj = null; + + try + { + // Create a new desktop action instance + + actionObj = Class.forName(className.getValue()).newInstance(); + + // Make sure the object is a desktop action + + if ( actionObj instanceof DesktopAction) + { + // Initialize the desktop action + + DesktopAction deskAction = (DesktopAction) actionObj; + deskAction.initializeAction(globalConfig, actionElem, fileSys); + + // Add the action to the list of desktop actions + + desktopActions.addAction(deskAction); + + // DEBUG + + if ( logger.isDebugEnabled()) + logger.debug("Added desktop action " + deskAction.getName()); + } + else + throw new AlfrescoRuntimeException("Desktop action does not extend DesktopAction class, " + className.getValue()); + } + catch ( ClassNotFoundException ex) + { + throw new AlfrescoRuntimeException("Desktop action class not found, " + className.getValue()); + } + catch (IllegalAccessException ex) + { + throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex); + } + catch ( InstantiationException ex) + { + throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex); + } + catch (DesktopActionException ex) + { + throw new AlfrescoRuntimeException("Failed to initialize desktop action", ex); + } + } + } + else if ( actionElem.getName().equals("global") == false) + throw new AlfrescoRuntimeException("Invalid configuration element in desktopActions section, " + actionElem.getName()); + } + } + + // Return the desktop actions list + + return desktopActions; + } + + /** + * Parse the platforms attribute returning the set of platform ids + * + * @param platformStr String + * @return EnumSet + */ + private final EnumSet parsePlatformString(String platformStr) + { + // Split the platform string and build up a set of platform types + + EnumSet platformTypes = EnumSet.noneOf(Platform.Type.class); + if (platformStr == null || platformStr.length() == 0) + return platformTypes; + + StringTokenizer token = new StringTokenizer(platformStr.toUpperCase(Locale.ENGLISH), ","); + String typ = null; + + try + { + while (token.hasMoreTokens()) + { + + // Get the current platform type string and validate + + typ = token.nextToken().trim(); + Platform.Type platform = Platform.Type.valueOf(typ); + + if (platform != Platform.Type.Unknown) + platformTypes.add(platform); + else + throw new AlfrescoRuntimeException("Invalid platform type, " + typ); + } + } + catch (IllegalArgumentException ex) + { + throw new AlfrescoRuntimeException("Invalid platform type, " + typ); + } + + // Return the platform types + + return platformTypes; + } + + /** + * Get the local server name and optionally trim the domain name + * + * @param trimDomain boolean + * @return String + */ + public final String getLocalServerName(boolean trimDomain) + { + // Check if the name has already been set + + if (m_localName != null) + return m_localName; + + // Find the local server name + + String srvName = null; + + if (getPlatformType() == Platform.Type.WINDOWS) + { + // Get the local name via JNI + + srvName = Win32NetBIOS.GetLocalNetBIOSName(); + } + else + { + // Get the DNS name of the local system + + try + { + srvName = InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException ex) + { + } + } + + // Strip the domain name + + if (trimDomain && srvName != null) + { + int pos = srvName.indexOf("."); + if (pos != -1) + srvName = srvName.substring(0, pos); + } + + // Save the local server name + + m_localName = srvName; + + // Return the local server name + + return srvName; + } + + /** + * Get the local domain/workgroup name + * + * @return String + */ + public final String getLocalDomainName() + { + // Check if the local domain has been set + + if (m_localDomain != null) + return m_localDomain; + + // Find the local domain name + + String domainName = null; + + if (getPlatformType() == Platform.Type.WINDOWS) + { + // Get the local domain/workgroup name via JNI + + domainName = Win32NetBIOS.GetLocalDomainName(); + + // Debug + + if (logger.isDebugEnabled()) + logger.debug("Local domain name is " + domainName + " (via JNI)"); + } + else + { + NetBIOSName nbName = null; + + try + { + // Try and find the browse master on the local network + + nbName = NetBIOSSession.FindName(NetBIOSName.BrowseMasterName, NetBIOSName.BrowseMasterGroup, 5000); + + // Log the browse master details + + if (logger.isDebugEnabled()) + logger.debug("Found browse master at " + nbName.getIPAddressString(0)); + + // Get the NetBIOS name list from the browse master + + NetBIOSNameList nbNameList = NetBIOSSession.FindNamesForAddress(nbName.getIPAddressString(0)); + if (nbNameList != null) + { + nbName = nbNameList.findName(NetBIOSName.MasterBrowser, false); + // Set the domain/workgroup name + if (nbName != null) + domainName = nbName.getName(); + } + } + catch (IOException ex) + { + } + } + + // Save the local domain name + + m_localDomain = domainName; + + // Return the local domain/workgroup name + + return domainName; + } + + /** + * Parse an adapter name string and return the matching address + * + * @param adapter String + * @return InetAddress + * @exception InvalidConfigurationException + */ + protected final InetAddress parseAdapterName(String adapter) + throws InvalidConfigurationException { + + NetworkInterface ni = null; + + try { + ni = NetworkInterface.getByName( adapter); + } + catch (SocketException ex) { + throw new InvalidConfigurationException( "Invalid adapter name, " + adapter); + } + + if ( ni == null) + throw new InvalidConfigurationException( "Invalid network adapter name, " + adapter); + + // Get the IP address for the adapter + + InetAddress adapAddr = null; + Enumeration addrEnum = ni.getInetAddresses(); + + while ( addrEnum.hasMoreElements() && adapAddr == null) { + + // Get the current address + + InetAddress addr = addrEnum.nextElement(); + if ( IPAddress.isNumericAddress( addr.getHostAddress())) + adapAddr = addr; + } + + // Check if we found the IP address to bind to + + if ( adapAddr == null) + throw new InvalidConfigurationException( "Adapter " + adapter + " does not have a valid IP address"); + + // Return the adapter address + + return adapAddr; + } + + private ApplicationContext applicationContext = null; + + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + public void onApplicationEvent(ApplicationEvent event) + { + if (event instanceof ContextRefreshedEvent) + { + ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent)event; + ApplicationContext refreshContext = refreshEvent.getApplicationContext(); + if (refreshContext != null && refreshContext.equals(applicationContext)) + { + // Initialize the bean + + init(); + } + } + } + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException + { + this.applicationContext = applicationContext; + } + + /** + * Return the authentication service + * + * @return AuthenticationService + */ + protected final AuthenticationService getAuthenticationService() + { + return m_authenticationService; + } + + /** + * Return the authentication component + * + * @return AuthenticationComponent + */ + protected final AuthenticationComponent getAuthenticationComponent() + { + return m_authenticationComponent; + } + + /** + * Return the node service + * + * @return NodeService + */ + protected final NodeService getNodeService() + { + return m_nodeService; + } + + /** + * Return the person service + * + * @return PersonService + */ + protected final PersonService getPersonService() + { + return m_personService; + } + + /** + * Return the transaction service + * + * @return TransactionService + */ + protected final TransactionService getTransactionService() + { + return m_transactionService; + } + + /** + * Return the tenant service + * + * @return TenantService + */ + protected final TenantService getTenantService() + { + return m_tenantService; + } + + /** + * Return the search service + * + * @return SearchService + */ + protected final SearchService getSearchService() + { + return m_searchService; + } + + /** + * Return the namespace service + * + * @return NamespaceService + */ + protected final NamespaceService getNamespaceService() + { + return m_namespaceService; + } +} diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfo.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfo.java new file mode 100644 index 0000000000..49ac7ef46d --- /dev/null +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfo.java @@ -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 + * + *

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; + } + +} diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfoFactory.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfoFactory.java new file mode 100644 index 0000000000..99d151c047 --- /dev/null +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoClientInfoFactory.java @@ -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); + } +} diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java index e13f454004..ce894910e6 100644 --- a/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoContext.java @@ -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 diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoDiskDriver.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoDiskDriver.java index 8c6efb2160..cf046dae31 100644 --- a/source/java/org/alfresco/filesys/alfresco/AlfrescoDiskDriver.java +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoDiskDriver.java @@ -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 + */ + public void endTransaction(SrvSession sess, ThreadLocal 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); + } } diff --git a/source/java/org/alfresco/filesys/alfresco/AlfrescoNetworkFile.java b/source/java/org/alfresco/filesys/alfresco/AlfrescoNetworkFile.java new file mode 100644 index 0000000000..e7613193b5 --- /dev/null +++ b/source/java/org/alfresco/filesys/alfresco/AlfrescoNetworkFile.java @@ -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 + * + *

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; + } +} diff --git a/source/java/org/alfresco/filesys/alfresco/DesktopAction.java b/source/java/org/alfresco/filesys/alfresco/DesktopAction.java index e7f28be3e1..8e84658d61 100644 --- a/source/java/org/alfresco/filesys/alfresco/DesktopAction.java +++ b/source/java/org/alfresco/filesys/alfresco/DesktopAction.java @@ -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 { diff --git a/source/java/org/alfresco/filesys/alfresco/DesktopParams.java b/source/java/org/alfresco/filesys/alfresco/DesktopParams.java index 024ae3be95..b7170d8173 100644 --- a/source/java/org/alfresco/filesys/alfresco/DesktopParams.java +++ b/source/java/org/alfresco/filesys/alfresco/DesktopParams.java @@ -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 diff --git a/source/java/org/alfresco/filesys/alfresco/FilesysTransaction.java b/source/java/org/alfresco/filesys/alfresco/FilesysTransaction.java new file mode 100644 index 0000000000..4c8710956e --- /dev/null +++ b/source/java/org/alfresco/filesys/alfresco/FilesysTransaction.java @@ -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 + * + *

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(); + } +} diff --git a/source/java/org/alfresco/filesys/alfresco/IOControl.java b/source/java/org/alfresco/filesys/alfresco/IOControl.java index c0820c4f2b..3764707fa1 100644 --- a/source/java/org/alfresco/filesys/alfresco/IOControl.java +++ b/source/java/org/alfresco/filesys/alfresco/IOControl.java @@ -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 diff --git a/source/java/org/alfresco/filesys/alfresco/IOControlHandler.java b/source/java/org/alfresco/filesys/alfresco/IOControlHandler.java index cf20a84042..c3b8c8d31c 100644 --- a/source/java/org/alfresco/filesys/alfresco/IOControlHandler.java +++ b/source/java/org/alfresco/filesys/alfresco/IOControlHandler.java @@ -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 diff --git a/source/java/org/alfresco/filesys/alfresco/MultiTenantShareMapper.java b/source/java/org/alfresco/filesys/alfresco/MultiTenantShareMapper.java new file mode 100644 index 0000000000..7975a0e423 --- /dev/null +++ b/source/java/org/alfresco/filesys/alfresco/MultiTenantShareMapper.java @@ -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 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(); + } + + /** + * 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 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 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(); + } + } + } +} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileImpl.java b/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java similarity index 91% rename from source/java/org/alfresco/filesys/server/pseudo/PseudoFileImpl.java rename to source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java index 7027fab2e5..fa4f42d132 100644 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileImpl.java +++ b/source/java/org/alfresco/filesys/alfresco/PseudoFileImpl.java @@ -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; diff --git a/source/java/org/alfresco/filesys/server/auth/AlfrescoAuthenticator.java b/source/java/org/alfresco/filesys/auth/cifs/AlfrescoCifsAuthenticator.java similarity index 67% rename from source/java/org/alfresco/filesys/server/auth/AlfrescoAuthenticator.java rename to source/java/org/alfresco/filesys/auth/cifs/AlfrescoCifsAuthenticator.java index 70240a8a6e..432d94a919 100644 --- a/source/java/org/alfresco/filesys/server/auth/AlfrescoAuthenticator.java +++ b/source/java/org/alfresco/filesys/auth/cifs/AlfrescoCifsAuthenticator.java @@ -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; * *

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 * *

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 diff --git a/source/java/org/alfresco/filesys/netbios/NameTemplateException.java b/source/java/org/alfresco/filesys/auth/cifs/AuthTokenAuthContext.java similarity index 65% rename from source/java/org/alfresco/filesys/netbios/NameTemplateException.java rename to source/java/org/alfresco/filesys/auth/cifs/AuthTokenAuthContext.java index 800da227bf..8b1624c94c 100644 --- a/source/java/org/alfresco/filesys/netbios/NameTemplateException.java +++ b/source/java/org/alfresco/filesys/auth/cifs/AuthTokenAuthContext.java @@ -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 - *

- * 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; + } +} diff --git a/source/java/org/alfresco/filesys/auth/cifs/CifsAuthenticatorBase.java b/source/java/org/alfresco/filesys/auth/cifs/CifsAuthenticatorBase.java new file mode 100644 index 0000000000..f96f38c528 --- /dev/null +++ b/source/java/org/alfresco/filesys/auth/cifs/CifsAuthenticatorBase.java @@ -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 + * + *

+ * 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(); + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java b/source/java/org/alfresco/filesys/auth/cifs/EnterpriseCifsAuthenticator.java similarity index 84% rename from source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java rename to source/java/org/alfresco/filesys/auth/cifs/EnterpriseCifsAuthenticator.java index 8c586936bb..fbe26428c3 100644 --- a/source/java/org/alfresco/filesys/server/auth/EnterpriseCifsAuthenticator.java +++ b/source/java/org/alfresco/filesys/auth/cifs/EnterpriseCifsAuthenticator.java @@ -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 mechTypes = new Vector(); + 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()); } diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java b/source/java/org/alfresco/filesys/auth/cifs/PassthruCifsAuthenticator.java similarity index 75% rename from source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java rename to source/java/org/alfresco/filesys/auth/cifs/PassthruCifsAuthenticator.java index 8271a5b867..e047630b84 100644 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruAuthenticator.java +++ b/source/java/org/alfresco/filesys/auth/cifs/PassthruCifsAuthenticator.java @@ -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 *

* 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 diff --git a/source/java/org/alfresco/filesys/auth/ftp/AlfrescoFtpAuthenticator.java b/source/java/org/alfresco/filesys/auth/ftp/AlfrescoFtpAuthenticator.java new file mode 100644 index 0000000000..e24d83908b --- /dev/null +++ b/source/java/org/alfresco/filesys/auth/ftp/AlfrescoFtpAuthenticator.java @@ -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(); + } +} diff --git a/source/java/org/alfresco/filesys/server/auth/AlfrescoRpcAuthenticator.java b/source/java/org/alfresco/filesys/auth/nfs/AlfrescoRpcAuthenticator.java similarity index 69% rename from source/java/org/alfresco/filesys/server/auth/AlfrescoRpcAuthenticator.java rename to source/java/org/alfresco/filesys/auth/nfs/AlfrescoRpcAuthenticator.java index 9dabd7e6e6..178bb1cabd 100644 --- a/source/java/org/alfresco/filesys/server/auth/AlfrescoRpcAuthenticator.java +++ b/source/java/org/alfresco/filesys/auth/nfs/AlfrescoRpcAuthenticator.java @@ -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 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 diff --git a/source/java/org/alfresco/filesys/avm/AVMContext.java b/source/java/org/alfresco/filesys/avm/AVMContext.java index 5f8c7405e0..fdf3804a9e 100644 --- a/source/java/org/alfresco/filesys/avm/AVMContext.java +++ b/source/java/org/alfresco/filesys/avm/AVMContext.java @@ -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; diff --git a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java index 157e5be158..5c821a7694 100644 --- a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java +++ b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java @@ -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 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 diff --git a/source/java/org/alfresco/filesys/avm/AVMNetworkFile.java b/source/java/org/alfresco/filesys/avm/AVMNetworkFile.java index 22ee39edb8..095b2a8336 100644 --- a/source/java/org/alfresco/filesys/avm/AVMNetworkFile.java +++ b/source/java/org/alfresco/filesys/avm/AVMNetworkFile.java @@ -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 diff --git a/source/java/org/alfresco/filesys/avm/AVMPath.java b/source/java/org/alfresco/filesys/avm/AVMPath.java index 01cfc625e0..49d1c560dd 100644 --- a/source/java/org/alfresco/filesys/avm/AVMPath.java +++ b/source/java/org/alfresco/filesys/avm/AVMPath.java @@ -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 diff --git a/source/java/org/alfresco/filesys/avm/AVMSearchContext.java b/source/java/org/alfresco/filesys/avm/AVMSearchContext.java index a7f5f5111a..2c5342f964 100644 --- a/source/java/org/alfresco/filesys/avm/AVMSearchContext.java +++ b/source/java/org/alfresco/filesys/avm/AVMSearchContext.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/avm/AVMShareMapper.java b/source/java/org/alfresco/filesys/avm/AVMShareMapper.java index d65266a83e..858850d90c 100644 --- a/source/java/org/alfresco/filesys/avm/AVMShareMapper.java +++ b/source/java/org/alfresco/filesys/avm/AVMShareMapper.java @@ -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 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 - '_' @@ -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 diff --git a/source/java/org/alfresco/filesys/avm/AVMSingleFileSearchContext.java b/source/java/org/alfresco/filesys/avm/AVMSingleFileSearchContext.java index af92df0e82..3c9df8007a 100644 --- a/source/java/org/alfresco/filesys/avm/AVMSingleFileSearchContext.java +++ b/source/java/org/alfresco/filesys/avm/AVMSingleFileSearchContext.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/avm/DummyFolderPseudoFile.java b/source/java/org/alfresco/filesys/avm/DummyFolderPseudoFile.java index ab40c65d8a..76d757e3f6 100644 --- a/source/java/org/alfresco/filesys/avm/DummyFolderPseudoFile.java +++ b/source/java/org/alfresco/filesys/avm/DummyFolderPseudoFile.java @@ -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 diff --git a/source/java/org/alfresco/filesys/avm/PseudoFileListSearchContext.java b/source/java/org/alfresco/filesys/avm/PseudoFileListSearchContext.java index c81facbcb1..e2ecb06656 100644 --- a/source/java/org/alfresco/filesys/avm/PseudoFileListSearchContext.java +++ b/source/java/org/alfresco/filesys/avm/PseudoFileListSearchContext.java @@ -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 diff --git a/source/java/org/alfresco/filesys/avm/StorePseudoFile.java b/source/java/org/alfresco/filesys/avm/StorePseudoFile.java index c57b119893..8773d00323 100644 --- a/source/java/org/alfresco/filesys/avm/StorePseudoFile.java +++ b/source/java/org/alfresco/filesys/avm/StorePseudoFile.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/avm/VersionPseudoFile.java b/source/java/org/alfresco/filesys/avm/VersionPseudoFile.java index ed329885ef..2f3833b1be 100644 --- a/source/java/org/alfresco/filesys/avm/VersionPseudoFile.java +++ b/source/java/org/alfresco/filesys/avm/VersionPseudoFile.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/avm/WebProjectStorePseudoFile.java b/source/java/org/alfresco/filesys/avm/WebProjectStorePseudoFile.java index 5a8e557485..6cc9459b4c 100644 --- a/source/java/org/alfresco/filesys/avm/WebProjectStorePseudoFile.java +++ b/source/java/org/alfresco/filesys/avm/WebProjectStorePseudoFile.java @@ -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; diff --git a/source/java/org/alfresco/filesys/debug/FileServerDebugInterface.java b/source/java/org/alfresco/filesys/debug/FileServerDebugInterface.java new file mode 100644 index 0000000000..612fc4d529 --- /dev/null +++ b/source/java/org/alfresco/filesys/debug/FileServerDebugInterface.java @@ -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 + } +} diff --git a/source/java/org/alfresco/filesys/ftp/FTPCommand.java b/source/java/org/alfresco/filesys/ftp/FTPCommand.java deleted file mode 100644 index e08ee98843..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPCommand.java +++ /dev/null @@ -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]; - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPDataSession.java b/source/java/org/alfresco/filesys/ftp/FTPDataSession.java deleted file mode 100644 index 932d5618bb..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPDataSession.java +++ /dev/null @@ -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 - *

- * A data connection is made when a PORT or PASV FTP command is received on the main control - * session. - *

- * 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 - *

- * 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 - *

- * 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 - *

- * 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 - *

- * 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 - *

- * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPDate.java b/source/java/org/alfresco/filesys/ftp/FTPDate.java deleted file mode 100644 index 0cd5a15fbd..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPDate.java +++ /dev/null @@ -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)); - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPNetworkServer.java b/source/java/org/alfresco/filesys/ftp/FTPNetworkServer.java deleted file mode 100644 index be402fde7f..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPNetworkServer.java +++ /dev/null @@ -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; - -/** - *

- * 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; - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPPath.java b/source/java/org/alfresco/filesys/ftp/FTPPath.java deleted file mode 100644 index c92e6ff448..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPPath.java +++ /dev/null @@ -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 - *

- * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPRequest.java b/source/java/org/alfresco/filesys/ftp/FTPRequest.java deleted file mode 100644 index e718de132e..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPRequest.java +++ /dev/null @@ -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 - *

- * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPSessionList.java b/source/java/org/alfresco/filesys/ftp/FTPSessionList.java deleted file mode 100644 index e494b20456..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPSessionList.java +++ /dev/null @@ -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 m_sessions; - - /** - * Class constructor - */ - public FTPSessionList() - { - m_sessions = new Hashtable(); - } - - /** - * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPSiteInterface.java b/source/java/org/alfresco/filesys/ftp/FTPSiteInterface.java deleted file mode 100644 index 7b23e02d67..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPSiteInterface.java +++ /dev/null @@ -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 - * - *

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); -} diff --git a/source/java/org/alfresco/filesys/ftp/FTPSrvSession.java b/source/java/org/alfresco/filesys/ftp/FTPSrvSession.java deleted file mode 100644 index f9da96bbce..0000000000 --- a/source/java/org/alfresco/filesys/ftp/FTPSrvSession.java +++ /dev/null @@ -1,4687 +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.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Calendar; -import java.util.Date; -import java.util.Enumeration; -import java.util.StringTokenizer; -import java.util.TimeZone; -import java.util.Vector; - -import javax.transaction.UserTransaction; - -import org.alfresco.filesys.avm.AVMDiskDriver; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; -import org.alfresco.filesys.server.filesys.AccessDeniedException; -import org.alfresco.filesys.server.filesys.AccessMode; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskFullException; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.DiskSharedDevice; -import org.alfresco.filesys.server.filesys.FileAction; -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.FileStatus; -import org.alfresco.filesys.server.filesys.FileType; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.NotifyChange; -import org.alfresco.filesys.server.filesys.SearchContext; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.TreeConnectionHash; -import org.alfresco.filesys.smb.server.repo.ContentContext; -import org.alfresco.model.ContentModel; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.repo.security.authentication.AuthenticationException; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -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; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.ibm.icu.text.Normalizer; - -/** - * FTP Server Session Class - * - * @author GKSpencer - */ -public class FTPSrvSession extends SrvSession implements Runnable -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.ftp.protocol"); - - // Constants - // - // Debug flag values - - public static final int DBG_STATE = 0x00000001; // Session state changes - - public static final int DBG_SEARCH = 0x00000002; // File/directory search - - public static final int DBG_INFO = 0x00000004; // Information requests - - public static final int DBG_FILE = 0x00000008; // File open/close/info - - public static final int DBG_FILEIO = 0x00000010; // File read/write - - public static final int DBG_ERROR = 0x00000020; // Errors - - public static final int DBG_PKTTYPE = 0x00000040; // Received packet type - - public static final int DBG_TIMING = 0x00000080; // Time packet - - // processing - - public static final int DBG_DATAPORT = 0x00000100; // Data port - - public static final int DBG_DIRECTORY = 0x00000200; // Directory commands - - // Enabled features - - protected static boolean FeatureUTF8 = true; - protected static boolean FeatureMDTM = true; - protected static boolean FeatureSIZE = true; - protected static boolean FeatureMLST = true; - - // Anonymous user name - - private static final String USER_ANONYMOUS = "anonymous"; - - // Root directory and FTP directory seperator - - private static final String ROOT_DIRECTORY = "/"; - - 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 = '\\'; - - // File transfer buffer size - - public static final int DEFAULT_BUFFERSIZE = 64000; - - // Carriage return/line feed combination required for response messages - - protected final static String CRLF = "\r\n"; - - // LIST command options - - protected final static String LIST_OPTION_PREFIX = "-"; - - protected final static char LIST_OPTION_HIDDEN = 'a'; - - // Machine listing fact ids - - protected static final int MLST_SIZE = 0x0001; - protected static final int MLST_MODIFY = 0x0002; - protected static final int MLST_CREATE = 0x0004; - protected static final int MLST_TYPE = 0x0008; - protected static final int MLST_UNIQUE = 0x0010; - protected static final int MLST_PERM = 0x0020; - protected static final int MLST_MEDIATYPE = 0x0040; - - // Default fact list to use for machine listing commands - - protected static final int MLST_DEFAULT = MLST_SIZE + MLST_MODIFY + MLST_CREATE + MLST_TYPE + MLST_UNIQUE + MLST_PERM + MLST_MEDIATYPE; - - // Machine listing fact names - - protected static final String _factNames[] = { "size", "modify", "create", "type", "unique", "perm", "media-type" }; - - // MLSD buffer size to allocate - - protected static final int MLSD_BUFFER_SIZE = 4096; - - // Modify date/time minimum date/time argument length - - protected static final int MDTM_DATETIME_MINLEN = 14; // YYYYMMDDHHMMSS - - // Flag to control whether data transfers use a seperate thread - - private static boolean UseThreadedDataTransfer = false; - - // Session socket - - private Socket m_sock; - - // Input/output streams to remote client - - private InputStream m_in; - private byte[] m_inbuf; - - private OutputStreamWriter m_out; - private StringBuffer m_outbuf; - - // Data connection - - private FTPDataSession m_dataSess; - - // Current working directory details - // - // First level is the share name then a path relative to the share root - - private FTPPath m_cwd; - - // Binary mode flag - - private boolean m_binary = false; - - // Restart position for binary file transfer - - private long m_restartPos = 0; - - // Flag to indicate if UTF-8 paths are enabled - - private boolean m_utf8Paths = false; - - // Machine listing fact list - - private int m_mlstFacts = MLST_DEFAULT; - - // Rename from path details - - private FTPPath m_renameFrom; - - // Filtered list of shared filesystems available to this session - - private SharedDeviceList m_shares; - - // List of shared device connections used by this session - - private TreeConnectionHash m_connections; - - /** - * Class constructor - * - * @param sock - * Socket - * @param srv - * FTPServer - */ - public FTPSrvSession(Socket sock, FTPNetworkServer srv) - { - super(-1, srv, "FTP", null); - - // Save the local socket - - m_sock = sock; - - // Set the socket linger options, so the socket closes immediately when - // closed - - try - { - m_sock.setSoLinger(false, 0); - } - catch (SocketException ex) - { - } - - // Indicate that the user is not logged in - - setLoggedOn(false); - - // Allocate the FTP path - - m_cwd = new FTPPath(); - - // Allocate the tree connection cache - - m_connections = new TreeConnectionHash(); - } - - /** - * Close the FTP session, and associated data socket if active - */ - public final void closeSession() - { - - // Call the base class - - super.closeSession(); - - // Close the data connection, if active - - if (m_dataSess != null) - { - // Abort any active transfer - - m_dataSess.abortTransfer(); - - // Remove the data session - - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - - // Close the socket first, if the client is still connected this should - // allow the input/output streams to be closed - - if (m_sock != null) - { - try - { - m_sock.close(); - } - catch (Exception ex) - { - } - m_sock = null; - } - - // Close the input/output streams - - if (m_in != null) - { - try - { - m_in.close(); - } - catch (Exception ex) - { - } - m_in = null; - } - - if (m_out != null) - { - try - { - m_out.close(); - } - catch (Exception ex) - { - } - m_out = null; - } - - // Remove session from server session list - - getFTPServer().removeSession(this); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Session closed, " + getSessionId()); - } - - /** - * Return the current working directory - * - * @return String - */ - public final String getCurrentWorkingDirectory() - { - return m_cwd.getFTPPath(); - } - - /** - * Return the server that this session is associated with. - * - * @return FTPServer - */ - public final FTPNetworkServer getFTPServer() - { - return (FTPNetworkServer) getServer(); - } - - /** - * Return the client network address - * - * @return InetAddress - */ - public final InetAddress getRemoteAddress() - { - return m_sock.getInetAddress(); - } - - /** - * Check if there is a current working directory - * - * @return boolean - */ - public final boolean hasCurrentWorkingDirectory() - { - return m_cwd != null ? true : false; - } - - /** - * Check if UTF-8 filenames are enabled - * - * @return boolean - */ - public final boolean isUTF8Enabled() - { - return m_utf8Paths; - } - - /** - * Set the default path for the session - * - * @param rootPath FTPPath - */ - public final void setRootPath(FTPPath rootPath) - { - - // Initialize the current working directory using the root path - - m_cwd = new FTPPath(rootPath); - if ( rootPath.hasSharedDevice()) - m_cwd.setSharedDevice( rootPath.getSharedDevice()); - else - m_cwd.setSharedDevice(getShareList(), this); - } - - /** - * Get the path details for the current request - * - * @param req FTPRequest - * @param filePath boolean - * @return FTPPath - */ - protected final FTPPath generatePathForRequest(FTPRequest req, boolean filePath) - { - return generatePathForRequest(req, filePath, true); - } - - /** - * Get the path details for the current request - * - * @param req FTPRequest - * @param filePath boolean - * @param checkExists boolean - * @return FTPPath - */ - protected final FTPPath generatePathForRequest(FTPRequest req, boolean filePath, boolean checkExists) - { - // Use the global share list for normal connections and the per session list for guest access - - SharedDeviceList shareList = null; - - if ( getClientInformation().isGuest()) - shareList = getDynamicShareList(); - else - shareList = getShareList(); - - // Convert the path to an FTP format path - - String path = convertToFTPSeperators( req.getArgument()); - - // Check if the path is the root directory and there is a default root - // path configured - - FTPPath ftpPath = null; - - if (path.compareTo(ROOT_DIRECTORY) == 0) - { - - // Check if the FTP server has a default root directory configured - - FTPNetworkServer ftpSrv = (FTPNetworkServer) getServer(); - if (ftpSrv.hasRootPath()) - ftpPath = ftpSrv.getRootPath(); - else - { - try - { - ftpPath = new FTPPath("/"); - } - catch (Exception ex) - { - } - return ftpPath; - } - } - - // Check if the path is relative - - else if (FTPPath.isRelativePath(path) == false) - { - - // Create a new path for the directory - - try - { - ftpPath = new FTPPath(path); - } - catch (InvalidPathException ex) - { - return null; - } - - // Find the associated shared device - - if (ftpPath.setSharedDevice( shareList, this) == false) - return null; - } - else - { - - // Check for the special '.' directory, just return the current - // working directory - - if (path.equals(".")) - return m_cwd; - - // Check for the special '..' directory, if already at the root - // directory return an - // error - - if (path.equals("..")) - { - - // Check if we are already at the root path - - if (m_cwd.isRootPath() == false) - { - - // Remove the last directory from the path - - m_cwd.removeDirectory(); - m_cwd.setSharedDevice( shareList, this); - return m_cwd; - } - else - return null; - } - - // Create a copy of the current working directory and append the new - // file/directory name - - ftpPath = new FTPPath(m_cwd); - - // Check if the root directory/share has been set - - if (ftpPath.isRootPath()) - { - - // Path specifies the share name - - try - { - ftpPath.setSharePath(path, null); - } - catch (InvalidPathException ex) - { - return null; - } - } - else - { - if (filePath) - ftpPath.addFile(path); - else - ftpPath.addDirectory(path); - } - - // Find the associated shared device, if not already set - - if (ftpPath.hasSharedDevice() == false && ftpPath.setSharedDevice( shareList, this) == false) - return null; - } - - // Check if the generated path exists - - if (checkExists) - { - - // Check if the new path exists and is a directory - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(ftpPath.getSharedDevice()); - - // Access the virtual filesystem driver - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - - // Check if the path exists - - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.NotExist) - { - - // Get the path string, check if there is a leading - // seperator - - String pathStr = req.getArgument(); - if (pathStr.startsWith(FTP_SEPERATOR) == false) - pathStr = FTP_SEPERATOR + pathStr; - - // Create the root path - - ftpPath = new FTPPath(pathStr); - - // Find the associated shared device - - if (ftpPath.setSharedDevice(getShareList(), this) == false) - ftpPath = null; - else - { - // Recheck if the path exists - - sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - if ( sts == FileStatus.NotExist) - ftpPath = null; - } - } - else if ((sts == FileStatus.FileExists && filePath == false) - || (sts == FileStatus.DirectoryExists && filePath == true)) - { - - // Path exists but is the wrong type (directory or file) - - ftpPath = null; - } - } - catch (Exception ex) - { - // DEBUG - - if ( logger.isErrorEnabled()) - logger.error("Error generating FTP path", ex); - - ftpPath = null; - } - } - - // Return the new path - - return ftpPath; - } - - /** - * Convert a path string from share path seperators to FTP path seperators - * - * @param path String - * @return String - */ - protected final String convertToFTPSeperators(String path) - { - - // Check if the path is valid - - if (path == null || path.indexOf(DIR_SEPERATOR) == -1) - return path; - - // Replace the path seperators - - return path.replace(DIR_SEPERATOR_CHAR, FTP_SEPERATOR_CHAR); - } - - /** - * Find the required disk shared device - * - * @param name String - * @return DiskSharedDevice - */ - protected final DiskSharedDevice findShare(String name) - { - - // Check if the name is valid - - if (name == null) - return null; - - // Find the required disk share - - SharedDevice shr = getFTPServer().getShareList().findShare(m_cwd.getShareName()); - - if (shr != null && shr instanceof DiskSharedDevice) - return (DiskSharedDevice) shr; - - // Disk share not found - - return null; - } - - /** - * Set the binary mode flag - * - * @param bin boolean - */ - protected final void setBinary(boolean bin) - { - m_binary = bin; - } - - /** - * Send an FTP command response - * - * @param stsCode int - * @param msg String - * @exception IOException - */ - protected final void sendFTPResponse(int stsCode, String msg) throws IOException - { - - // Build the output record - - m_outbuf.setLength(0); - m_outbuf.append(stsCode); - m_outbuf.append(" "); - - if (msg != null) - m_outbuf.append(msg); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR) && stsCode >= 500) - logger.debug("Error status=" + stsCode + ", msg=" + msg); - - // Add the CR/LF - - m_outbuf.append(CRLF); - - // Output the FTP response - - if (m_out != null) - { - m_out.write(m_outbuf.toString()); - m_out.flush(); - } - } - - /** - * Send an FTP command response - * - * @param msg StringBuffer - * @exception IOException - */ - protected final void sendFTPResponse(StringBuffer msg) throws IOException - { - - // Output the FTP response - - if (m_out != null) - { - m_out.write(msg.toString()); - m_out.write(CRLF); - m_out.flush(); - } - } - - /** - * Send an FTP command response - * - * @param msg String - * @exception IOException - */ - protected final void sendFTPResponse(String msg) throws IOException - { - - // Output the FTP response - - if (m_out != null) - { - m_out.write(msg); - m_out.write(CRLF); - m_out.flush(); - } - } - - /** - * Process a user command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procUser(FTPRequest req) throws IOException - { - - // Clear the current client information - - setClientInformation(null); - setLoggedOn(false); - - // Check if a user name has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error in parameters or arguments"); - return; - } - - // Check for an anonymous login - - if (getFTPServer().allowAnonymous() == true - && req.getArgument().equalsIgnoreCase(getFTPServer().getAnonymousAccount())) - { - - // Anonymous login, create guest client information - - ClientInfo cinfo = new ClientInfo(getFTPServer().getAnonymousAccount(), null); - cinfo.setGuest(true); - setClientInformation(cinfo); - - // Return the anonymous login response - - sendFTPResponse(331, "Guest login ok, send your complete e-mail address as password"); - return; - } - - // Create client information for the user - - setClientInformation(new ClientInfo(req.getArgument(), null)); - - // Valid user, wait for the password - - sendFTPResponse(331, "User name okay, need password for " + req.getArgument()); - } - - /** - * Process a password command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procPassword(FTPRequest req) throws IOException - { - - // Check if the client information has been set, this indicates a user - // command has been received - - if (hasClientInformation() == false) - { - sendFTPResponse(500, "Syntax error, command " - + FTPCommand.getCommandName(req.isCommand()) + " unrecognized"); - return; - } - - // Check for an anonymous login, accept any password string - - ClientInfo cInfo = getClientInformation(); - - if (cInfo.isGuest()) - { - if ( getFTPServer().allowAnonymous() == true) - { - // Authenticate as the guest user - - AuthenticationComponent authComponent = getServer().getConfiguration().getAuthenticationComponent(); - cInfo.setUserName( authComponent.getGuestUserName()); - } - else - { - // Return an access denied error - - sendFTPResponse(530, "Access denied"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Anonymous logon not allowed"); - - // Close the connection - - closeSession(); - } - } - - // Get the client information and store the received plain text password - - cInfo.setPassword(req.getArgument()); - - // Start a transaction - - beginReadTransaction( getServer().getConfiguration().getTransactionService()); - - // Use the normal authentication service as we have the plaintext password - - AuthenticationService authService = getServer().getConfiguration().getAuthenticationService(); - - try - { - // Authenticate the user - - if ( cInfo.isGuest()) - { - // Authenticate as the guest user - - authService.authenticateAsGuest(); - } - else - { - // Authenticate as a normal user - - authService.authenticate( cInfo.getUserName(), cInfo.getPasswordAsCharArray()); - } - - // User successfully logged on - - sendFTPResponse(230, "User logged in, proceed"); - setLoggedOn(true); - - // Save the client info - - setClientInformation( cInfo); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("User " + getClientInformation().getUserName() + ", logon successful"); - } - catch (org.alfresco.repo.security.authentication.AuthenticationException ex) - { - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Logon failed for user " + cInfo.getUserName()); - } - - // Check if the logon was successful - - if ( isLoggedOn() == true) - { - // If the user has successfully logged on to the FTP server then inform listeners - - getFTPServer().sessionLoggedOn(this); - - // If this is a guest logon then we need to set the root folder to the guest user home folder - // as guest is not allowed access to other areas - - if ( cInfo.isGuest()) - { - // Generate a dynamic share with the guest users home folder as the root - - DiskSharedDevice guestShare = createHomeDiskShare( cInfo); - addDynamicShare( guestShare); - - // Set the root path for the guest logon to the guest share - - StringBuilder rootPath = new StringBuilder(); - - rootPath.append(FTP_SEPERATOR); - rootPath.append( guestShare.getName()); - rootPath.append(FTP_SEPERATOR); - - FTPPath guestRoot = null; - - try - { - // Set the root path for this FTP session - - guestRoot = new FTPPath( rootPath.toString()); - guestRoot.setSharedDevice( guestShare); - setRootPath( guestRoot); - } - catch ( InvalidPathException ex) - { - if ( logger.isErrorEnabled()) - logger.error("Error setting guest FTP root path", ex); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug(" Using root path " + guestRoot); - } - } - else - { - - // Return an access denied error - - sendFTPResponse(530, "Access denied"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("User " + getClientInformation().getUserName() + ", logon failed"); - - // Close the connection - - closeSession(); - } - } - - /** - * Process a port command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procPort(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if the parameter has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Required argument missing"); - return; - } - - // Parse the address/port string into a IP address and port - - StringTokenizer token = new StringTokenizer(req.getArgument(), ","); - if (token.countTokens() != 6) - { - sendFTPResponse(501, "Invalid argument"); - return; - } - - // Parse the client address - - String addrStr = token.nextToken() - + "." + token.nextToken() + "." + token.nextToken() + "." + token.nextToken(); - InetAddress addr = null; - - try - { - addr = InetAddress.getByName(addrStr); - } - catch (UnknownHostException ex) - { - sendFTPResponse(501, "Invalid argument (address)"); - return; - } - - // Parse the client port - - int port = -1; - - try - { - port = Integer.parseInt(token.nextToken()) * 256; - port += Integer.parseInt(token.nextToken()); - } - catch (NumberFormatException ex) - { - sendFTPResponse(501, "Invalid argument (port)"); - return; - } - - // Create an active data session, the actual socket connection will be - // made later - - m_dataSess = getFTPServer().allocateDataSession(this, addr, port); - - // Return a success response to the client - - sendFTPResponse(200, "Port OK"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DATAPORT)) - logger.debug("Port open addr=" + addr + ", port=" + port); - } - - /** - * Process a passive command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procPassive(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Create a passive data session - - try - { - m_dataSess = getFTPServer().allocateDataSession(this, null, 0); - } - catch (IOException ex) - { - m_dataSess = null; - } - - // Check if the data session is valid - - if (m_dataSess == null) - { - sendFTPResponse(550, "Requested action not taken"); - return; - } - - // Get the passive connection address/port and return to the client - - int pasvPort = m_dataSess.getPassivePort(); - - StringBuffer msg = new StringBuffer(); - - msg.append("227 Entering Passive Mode ("); - msg.append(getFTPServer().getLocalFTPAddressString()); - msg.append(","); - msg.append(pasvPort >> 8); - msg.append(","); - msg.append(pasvPort & 0xFF); - msg.append(")"); - - sendFTPResponse(msg); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DATAPORT)) - logger.debug("Passive open addr=" + getFTPServer().getLocalFTPAddressString() + ", port=" + pasvPort); - } - - /** - * Process a print working directory command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procPrintWorkDir(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Return the current working directory virtual path - - sendFTPResponse(257, "\"" + m_cwd.getFTPPath() + "\""); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DIRECTORY)) - logger.debug("Pwd ftp=" - + m_cwd.getFTPPath() + ", share=" + m_cwd.getShareName() + ", path=" + m_cwd.getSharePath()); - } - - /** - * Process a change working directory command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procChangeWorkDir(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if the request has a valid argument - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Path not specified"); - return; - } - - // Create the new working directory path - - FTPPath newPath = generatePathForRequest(req, false); - if (newPath == null) - { - sendFTPResponse(550, "Invalid path " + req.getArgument()); - return; - } - - // Set the new current working directory - - m_cwd = newPath; - - // Return a success status - - sendFTPResponse(250, "Requested file action OK"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DIRECTORY)) - logger.debug("Cwd ftp=" - + m_cwd.getFTPPath() + ", share=" + m_cwd.getShareName() + ", path=" + m_cwd.getSharePath()); - } - - /** - * Process a change directory up command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procCdup(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if there is a current working directory path - - if (m_cwd.isRootPath()) - { - - // Already at the root directory, return an error status - - sendFTPResponse(550, "Already at root directory"); - return; - } - else - { - - // Remove the last directory from the path - - m_cwd.removeDirectory(); - if (m_cwd.isRootPath() == false && m_cwd.getSharedDevice() == null) - m_cwd.setSharedDevice(getShareList(), this); - } - - // Return a success status - - sendFTPResponse(250, "Requested file action OK"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DIRECTORY)) - logger.debug("Cdup ftp=" - + m_cwd.getFTPPath() + ", share=" + m_cwd.getShareName() + ", path=" + m_cwd.getSharePath()); - } - - /** - * Process a long directory listing command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procList(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if the client has requested hidden files, via the '-a' option - - boolean hidden = false; - - if (req.hasArgument() && req.getArgument().startsWith(LIST_OPTION_PREFIX)) - { - // We only support the hidden files option - - String arg = req.getArgument(); - if ( arg.indexOf( LIST_OPTION_HIDDEN) != -1) - { - // Indicate that we want hidden files in the listing - - hidden = true; - } - - // Remove the option from the command argument, and update the - // request - - int pos = arg.indexOf(" "); - if (pos > 0) - arg = arg.substring(pos + 1); - else - arg = null; - - req.updateArgument(arg); - } - - // Create the path for the file listing - - FTPPath ftpPath = m_cwd; - if ( req.hasArgument()) - ftpPath = generatePathForRequest(req, true); - - if (ftpPath == null) - { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Check if the session has the required access - - if (ftpPath.isRootPath() == false) - { - - // Check if the session has access to the filesystem - - TreeConnection tree = getTreeConnection(ftpPath.getSharedDevice()); - if (tree == null || tree.hasReadAccess() == false) - { - - // Session does not have access to the filesystem - - sendFTPResponse(550, "Access denied"); - return; - } - } - - // Send the intermediate response - - sendFTPResponse(150, "File status okay, about to open data connection"); - - // Check if there is an active data session - - if (m_dataSess == null) - { - sendFTPResponse(425, "Can't open data connection"); - return; - } - - // Get the data connection socket - - Socket dataSock = null; - - try - { - dataSock = m_dataSess.getSocket(); - } - catch (Exception ex) - { - logger.debug(ex); - } - - if (dataSock == null) - { - sendFTPResponse(426, "Connection closed; transfer aborted"); - return; - } - - // Output the directory listing to the client - - Writer dataWrt = null; - - try - { - - // Open an output stream to the client - - if ( isUTF8Enabled()) - dataWrt = new OutputStreamWriter(dataSock.getOutputStream(), "UTF-8"); - else - dataWrt = new OutputStreamWriter(dataSock.getOutputStream()); - - // Check if a path has been specified to list - - Vector files = null; - - if (req.hasArgument()) - { - } - - // Get a list of file information objects for the current directory - - files = listFilesForPath(ftpPath, false, hidden); - - // Output the file list to the client - - if (files != null) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_SEARCH)) - logger.debug("List found " + files.size() + " files in " + ftpPath.getFTPPath()); - - // Output the file information to the client - - StringBuilder str = new StringBuilder(256); - - for (FileInfo finfo : files) - { - // Build the output record - - str.setLength(0); - - str.append(finfo.isDirectory() ? "d" : "-"); - str.append("rw-rw-rw- 1 user group "); - str.append(finfo.getSize()); - str.append(" "); - - FTPDate.packUnixDate(str, new Date(finfo.getModifyDateTime())); - - str.append(" "); - str.append(finfo.getFileName()); - str.append(CRLF); - - // Output the file information record - - dataWrt.write(str.toString()); - } - - // Flush the data stream - - dataWrt.flush(); - } - - // Close the data stream and socket - - dataWrt.close(); - dataWrt = null; - - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - - // End of file list transmission - - sendFTPResponse(226, "Closing data connection"); - } - catch (Exception ex) - { - - // Failed to send file listing - - sendFTPResponse(451, "Error reading file list"); - } finally - { - - // Close the data stream to the client - - if (dataWrt != null) - dataWrt.close(); - - // Close the data connection to the client - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - } - } - - /** - * Process a short directory listing command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procNList(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Create the path for the file listing - - FTPPath ftpPath = m_cwd; - if (req.hasArgument()) - ftpPath = generatePathForRequest(req, true); - - if (ftpPath == null) - { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Check if the session has the required access - - if (ftpPath.isRootPath() == false) - { - - // Check if the session has access to the filesystem - - TreeConnection tree = getTreeConnection(ftpPath.getSharedDevice()); - if (tree == null || tree.hasReadAccess() == false) - { - - // Session does not have access to the filesystem - - sendFTPResponse(550, "Access denied"); - return; - } - } - - // Send the intermediate response - - sendFTPResponse(150, "File status okay, about to open data connection"); - - // Check if there is an active data session - - if (m_dataSess == null) - { - sendFTPResponse(425, "Can't open data connection"); - return; - } - - // Get the data connection socket - - Socket dataSock = null; - - try - { - dataSock = m_dataSess.getSocket(); - } - catch (Exception ex) - { - logger.error("Data socket error", ex); - } - - if (dataSock == null) - { - sendFTPResponse(426, "Connection closed; transfer aborted"); - return; - } - - // Output the directory listing to the client - - Writer dataWrt = null; - - try - { - - // Open an output stream to the client - - if ( isUTF8Enabled()) - dataWrt = new OutputStreamWriter(dataSock.getOutputStream(), "UTF-8"); - else - dataWrt = new OutputStreamWriter(dataSock.getOutputStream()); - - // Check if a path has been specified to list - - Vector files = null; - - if (req.hasArgument()) - { - } - - // Get a list of file information objects for the current directory - - files = listFilesForPath(ftpPath, false, false); - - // Output the file list to the client - - if (files != null) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_SEARCH)) - logger.debug("List found " + files.size() + " files in " + ftpPath.getFTPPath()); - - // Output the file information to the client - - for (FileInfo finfo : files) - { - - // Output the file information record - - dataWrt.write(finfo.getFileName()); - dataWrt.write(CRLF); - } - } - - // End of file list transmission - - sendFTPResponse(226, "Closing data connection"); - } - catch (Exception ex) - { - - // Failed to send file listing - - sendFTPResponse(451, "Error reading file list"); - } finally - { - - // Close the data stream to the client - - if (dataWrt != null) - dataWrt.close(); - - // Close the data connection to the client - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - } - } - - /** - * Process a system status command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procSystemStatus(FTPRequest req) throws IOException - { - - // Return the system type - - sendFTPResponse(215, "UNIX Type: Java FTP Server"); - } - - /** - * Process a server status command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procServerStatus(FTPRequest req) throws IOException - { - - // Return server status information - - sendFTPResponse(211, "JLAN Server - Java FTP Server"); - } - - /** - * Process a help command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procHelp(FTPRequest req) throws IOException - { - - // Return help information - - sendFTPResponse(211, "HELP text"); - } - - /** - * Process a no-op command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procNoop(FTPRequest req) throws IOException - { - - // Return a response - - sendFTPResponse(200, ""); - } - - /** - * Process an options request - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procOptions(FTPRequest req) throws IOException { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if the parameter has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Required argument missing"); - return; - } - - // Parse the argument to get the sub-command and arguments - - StringTokenizer token = new StringTokenizer(req.getArgument(), " "); - if (token.hasMoreTokens() == false) - { - sendFTPResponse(501, "Invalid argument"); - return; - } - - // Get the sub-command - - String optsCmd = token.nextToken(); - - // UTF8 enable/disable command - - if (FeatureUTF8 && optsCmd.equalsIgnoreCase("UTF8")) - { - - // Get the next argument - - if (token.hasMoreTokens()) - { - String optsArg = token.nextToken(); - if (optsArg.equalsIgnoreCase("ON")) - { - - // Enable UTF-8 file names - - m_utf8Paths = true; - } - else if (optsArg.equalsIgnoreCase("OFF")) - { - - // Disable UTF-8 file names - - m_utf8Paths = false; - } - else - { - - // Invalid argument - - sendFTPResponse(501, "OPTS UTF8 Invalid argument"); - return; - } - - // Report the new setting back to the client - - sendFTPResponse(200, "OPTS UTF8 " + (isUTF8Enabled() ? "ON" : "OFF")); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("UTF8 options utf8=" + (isUTF8Enabled() ? "ON" : "OFF")); - } - } - - // MLST/MLSD fact list command - - else if (FeatureMLST && optsCmd.equalsIgnoreCase("MLST")) - { - - // Check if the fact list argument is valid - - if (token.hasMoreTokens() == false) - { - - // Invalid fact list argument - - sendFTPResponse(501, "OPTS MLST Invalid argument"); - return; - } - - // Parse the supplied fact names - - int mlstFacts = 0; - StringTokenizer factTokens = new StringTokenizer(token.nextToken(), - ";"); - StringBuffer factStr = new StringBuffer(); - - while (factTokens.hasMoreTokens()) - { - // Get the current fact name and validate - - String factName = factTokens.nextToken(); - int factIdx = -1; - int idx = 0; - - while (idx < _factNames.length && factIdx == -1) - { - if (_factNames[idx].equalsIgnoreCase(factName)) - factIdx = idx; - else - idx++; - } - - // Check if the fact name is valid, ignore invalid names - - if (factIdx != -1) - { - // Add the fact name to the reply tring - - factStr.append(_factNames[factIdx]); - factStr.append(";"); - - // Add the fact to the fact bit mask - - mlstFacts += (1 << factIdx); - } - } - - // check if any valid fact names were found - - if (mlstFacts == 0) - { - sendFTPResponse(501, "OPTS MLST Invalid Argument"); - return; - } - - // Update the MLST enabled fact list for this session - - m_mlstFacts = mlstFacts; - - // Send the response - - sendFTPResponse(200, "MLST OPTS " + factStr.toString()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_SEARCH)) - logger.debug("MLst options facts=" + factStr.toString()); - } - else - { - // Invalid options command, or feature not enabled - - sendFTPResponse(501, "Invalid options commands"); - } - } - - /** - * Process a quit command - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procQuit(FTPRequest req) throws IOException - { - - // Return a response - - sendFTPResponse(221, "Bye"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Quit closing connection(s) to client"); - - // Close the session(s) to the client - - closeSession(); - } - - /** - * Process a type command - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procType(FTPRequest req) throws IOException - { - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Check if ASCII or binary mode is enabled - - String arg = req.getArgument().toUpperCase(); - if (arg.startsWith("A")) - setBinary(false); - else if (arg.startsWith("I") || arg.startsWith("L")) - setBinary(true); - else - { - - // Invalid argument - - sendFTPResponse(501, "Syntax error, invalid parameter"); - return; - } - - // Return a success status - - sendFTPResponse(200, "Command OK"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Type arg=" + req.getArgument() + ", binary=" + m_binary); - } - - /** - * Process a restart command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procRestart(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Validate the restart position - - try - { - m_restartPos = Integer.parseInt(req.getArgument()); - } - catch (NumberFormatException ex) - { - sendFTPResponse(501, "Invalid restart position"); - return; - } - - // Return a success status - - sendFTPResponse(350, "Restart OK"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILEIO)) - logger.debug("Restart pos=" + m_restartPos); - } - - /** - * Process a return file command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procReturnFile(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Create the path for the file listing - - FTPPath ftpPath = generatePathForRequest(req, true); - if (ftpPath == null) - { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Check if the path is the root directory - - if (ftpPath.isRootPath() || ftpPath.isRootSharePath()) - { - sendFTPResponse(550, "That is a directory"); - return; - } - - // Send the intermediate response - - sendFTPResponse(150, "Connection accepted"); - - // Check if there is an active data session - - if (m_dataSess == null) - { - sendFTPResponse(425, "Can't open data connection"); - return; - } - - // Check if a seperate thread should be used for the data transfer - - if ( UseThreadedDataTransfer == true) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Returning (threaded) ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" + ftpPath.getSharePath()); - - // Start the transfer in a seperate thread - - m_dataSess.doReturnFile( ftpPath, m_restartPos, req.getArgument()); - } - else - { - // Get the data connection socket - - Socket dataSock = null; - - try - { - dataSock = m_dataSess.getSocket(); - } - catch (Exception ex) - { - } - - if (dataSock == null) - { - sendFTPResponse(426, "Connection closed; transfer aborted"); - return; - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Returning ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" + ftpPath.getSharePath()); - - // Send the file to the client - - OutputStream os = null; - DiskInterface disk = null; - TreeConnection tree = null; - NetworkFile netFile = null; - - try - { - - // Open an output stream to the client - - os = dataSock.getOutputStream(); - - // Create a temporary tree connection - - tree = getTreeConnection(ftpPath.getSharedDevice()); - - // Check if the file exists and it is a file, if so then open the - // file - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - - // Create the file open parameters - - FileOpenParams params = new FileOpenParams(ftpPath.getSharePath(), FileAction.OpenIfExists, - AccessMode.ReadOnly, 0); - - // Check if the file exists and it is a file - - int sts = disk.fileExists(this, tree, 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) - { - sendFTPResponse(550, "File " + req.getArgument() + " not available"); - return; - } - - // Allocate the buffer for the file data - - byte[] buf = new byte[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() && hasDebug(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; - } - } - - // 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 - - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - - // Close the network file - - disk.closeFile(this, tree, netFile); - netFile = null; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILEIO)) - logger.debug(" Transfer complete, file closed"); - } - catch (SocketException ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug(" Error during transfer", ex); - - // Close the data socket to the client - - if (m_dataSess != null) - { - m_dataSess.closeSession(); - m_dataSess = null; - } - - // 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() && hasDebug(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 - { - - // Close the network file - - if (netFile != null && disk != null && tree != null) - disk.closeFile(this, tree, netFile); - - // Close the output stream to the client - - if (os != null) - os.close(); - - // Close the data connection to the client - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - } - } - } - - /** - * Process a store file command - * - * @param req FTPRequest - * @param append boolean - * @exception IOException - */ - protected final void procStoreFile(FTPRequest req, boolean append) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Create the path for the file listing - - FTPPath ftpPath = generatePathForRequest(req, true, false); - if (ftpPath == null) - { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Check if a seperate thread should be used for the data transfer - - if ( UseThreadedDataTransfer == true) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Storing (threaded) ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - - // Start the transfer in a seperate thread - - m_dataSess.doStoreFile( ftpPath, m_restartPos, req.getArgument()); - } - else - { - // Send the file to the client - - InputStream is = null; - DiskInterface disk = null; - TreeConnection tree = null; - NetworkFile netFile = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.DirectoryExists) - { - - // Return an error status - - sendFTPResponse(500, "Invalid path (existing directory)"); - return; - } - - // Create the file open parameters - - int openAction = FileAction.CreateNotExist; - if ( sts == FileStatus.FileExists) - openAction = append == false ? FileAction.TruncateExisting : FileAction.OpenIfExists; - - FileOpenParams params = new FileOpenParams(ftpPath.getSharePath(), openAction, 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); - - // Truncate the existing file - - netFile.truncateFile( 0L); - } - 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, ftpPath.getSharePath()); - - // Send the intermediate response - - sendFTPResponse(150, "File status okay, about to open data connection"); - - // Check if there is an active data session - - if (m_dataSess == null) - { - sendFTPResponse(425, "Can't open data connection"); - return; - } - - // Get the data connection socket - - Socket dataSock = null; - - try - { - dataSock = m_dataSess.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() && hasDebug(DBG_FILE)) - logger.debug("Storing ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - - // Allocate the buffer for the file data - - byte[] buf = new byte[DEFAULT_BUFFERSIZE]; - long filePos = 0; - int len = is.read(buf, 0, buf.length); - - // If the data is to be appended then set the starting file position to the end of the file - - if ( append == true) - filePos = netFile.getFileSize(); - - while (len > 0) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(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; - - // Indicate that the file has been received - - sendFTPResponse(226, "Closing data connection"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILEIO)) - logger.debug(" Transfer complete, file closed"); - } - catch( AccessDeniedException ex) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug(" Access denied", ex); - - // Session does not have write access to the filesystem - - sendFTPResponse(550, "Access denied"); - } - catch (SocketException ex) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug(" Error during transfer", ex); - - // Close the data socket to the client - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - - // Indicate that there was an error during transmission of the file - // data - - sendFTPResponse(426, "Data connection closed by client"); - } - catch (DiskFullException ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug(" Error during transfer", ex); - - // Close the data socket to the client - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - - // Indicate that there was an error during writing of the file - - sendFTPResponse(451, "Disk full"); - } - catch (Exception ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(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 - { - - // 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 - - if (m_dataSess != null) - { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - } - } - } - - /** - * Process a delete file command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procDeleteFile(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Create the path for the file - - FTPPath ftpPath = generatePathForRequest(req, true); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path specified"); - return; - } - - // Delete the specified file - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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 and it is a file - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.FileExists) - { - - // Delete the file - - disk.deleteFile(this, tree, ftpPath.getSharePath()); - - // Check if there are any file/directory change notify requests - // active - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, ftpPath.getSharePath()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Deleted ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - } - else - { - - // File does not exist or is a directory - - sendFTPResponse(550, "File " - + req.getArgument() + (sts == FileStatus.NotExist ? " not available" : " is a directory")); - return; - } - } - catch (AccessDeniedException ex) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug(" Access denied", ex); - - // Session does not have write access to the filesystem - - sendFTPResponse(550, "Access denied"); - return; - } - catch (Exception ex) - { - sendFTPResponse(450, "File action not taken"); - return; - } - - // Return a success status - - sendFTPResponse(250, "File " + req.getArgument() + " deleted"); - } - - /** - * Process a rename from command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procRenameFrom(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Clear the current rename from path details, if any - - m_renameFrom = null; - - // Create the path for the file/directory - - FTPPath ftpPath = generatePathForRequest(req, false, false); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path specified"); - return; - } - - // Check that the file exists, and it is a file - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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 and it is a file - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts != FileStatus.NotExist) - { - - // Save the rename from file details, rename to command should - // follow - - m_renameFrom = ftpPath; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("RenameFrom ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - } - else - { - - // File/directory does not exist - - sendFTPResponse(550, "File " - + req.getArgument() + (sts == FileStatus.NotExist ? " not available" : " is a directory")); - return; - } - } - catch (Exception ex) - { - sendFTPResponse(450, "File action not taken"); - return; - } - - // Return a success status - - sendFTPResponse(350, "File " + req.getArgument() + " OK"); - } - - /** - * Process a rename to command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procRenameTo(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Check if the rename from has already been set - - if (m_renameFrom == null) - { - sendFTPResponse(550, "Rename from not set"); - return; - } - - // Create the path for the new file name - - FTPPath ftpPath = generatePathForRequest(req, true, false); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path specified"); - return; - } - - // Check that the rename is on the same share - - if (m_renameFrom.getShareName().compareTo(ftpPath.getShareName()) != 0) - { - sendFTPResponse(550, "Cannot rename across shares"); - return; - } - - // Rename the file - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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 and it is a file - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.NotExist) - { - - // Rename the file/directory - - disk.renameFile(this, tree, m_renameFrom.getSharePath(), ftpPath.getSharePath()); - - // Check if there are any file/directory change notify requests - // active - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyRename(m_renameFrom.getSharePath(), ftpPath.getSharePath()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("RenameTo ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - } - else - { - - // File does not exist or is a directory - - sendFTPResponse(550, "File " - + req.getArgument() + (sts == FileStatus.NotExist ? " not available" : " is a directory")); - return; - } - } - catch (Exception ex) - { - sendFTPResponse(450, "File action not taken"); - return; - } - finally - { - - // Clear the rename details - - m_renameFrom = null; - } - - // Return a success status - - sendFTPResponse(250, "File renamed OK"); - } - - /** - * Process a create directory command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procCreateDirectory(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Check if the new directory contains multiple directories - - FTPPath ftpPath = generatePathForRequest(req, false, false); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path " + req.getArgument()); - return; - } - - // Create the new directory - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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 directory exists - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.NotExist) - { - - // Create the new directory - - FileOpenParams params = new FileOpenParams(ftpPath.getSharePath(), FileAction.CreateNotExist, - AccessMode.ReadWrite, FileAttribute.NTDirectory); - - disk.createDirectory(this, tree, params); - - // Notify change listeners that a new directory has been created - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, ftpPath.getSharePath()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DIRECTORY)) - logger.debug("CreateDir ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - } - else - { - - // File/directory already exists with that name, return an error - - sendFTPResponse(450, sts == FileStatus.FileExists ? "File exists with that name" - : "Directory already exists"); - return; - } - } - catch (Exception ex) - { - sendFTPResponse(450, "Failed to create directory"); - return; - } - - // Return the FTP path to the client - - sendFTPResponse(250, ftpPath.getFTPPath()); - } - - /** - * Process a delete directory command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procRemoveDirectory(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Check if the directory path contains multiple directories - - FTPPath ftpPath = generatePathForRequest(req, false); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path " + req.getArgument()); - return; - } - - // Check if the path is the root directory, cannot delete directories - // from the root directory as it maps to the list of available disk shares. - - if (ftpPath.isRootPath() || ftpPath.isRootSharePath()) - { - sendFTPResponse(550, "Access denied, cannot delete directory in root"); - return; - } - - // Delete the directory - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(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 directory exists - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - int sts = disk.fileExists(this, tree, ftpPath.getSharePath()); - - if (sts == FileStatus.DirectoryExists) - { - - // Delete the new directory - - disk.deleteDirectory(this, tree, ftpPath.getSharePath()); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, ftpPath.getSharePath()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_DIRECTORY)) - logger.debug("DeleteDir ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", path=" - + ftpPath.getSharePath()); - } - else - { - - // File already exists with that name or directory does not - // exist return an error - - sendFTPResponse(550, sts == FileStatus.FileExists ? "File exists with that name" - : "Directory does not exist"); - return; - } - } - catch (Exception ex) - { - sendFTPResponse(550, "Failed to delete directory"); - return; - } - - // Return a success status - - sendFTPResponse(250, "Directory deleted OK"); - } - - /** - * Process a machine listing request, single folder - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procMachineListing(FTPRequest req) throws IOException { - - // Check if the user is logged in - - if (isLoggedOn() == false) { - sendFTPResponse(500, "Not logged in"); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Create the path to be listed - - FTPPath ftpPath = generatePathForRequest(req, false, true); - if (ftpPath == null) { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Get the file information - - DiskInterface disk = null; - TreeConnection tree = null; - - try { - - // Create a temporary tree connection - - tree = getTreeConnection(ftpPath.getSharedDevice()); - - // Access the virtual filesystem driver - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - - // Get the file information - - FileInfo finfo = disk.getFileInformation(this, tree, ftpPath - .getSharePath()); - - if (finfo == null) { - sendFTPResponse(550, "Path " + req.getArgument() + " not available"); - return; - } else if (finfo.isDirectory() == false) { - sendFTPResponse(501, "Path " + req.getArgument() + " is not a directory"); - return; - } - - // Return the folder details - - sendFTPResponse("250- Listing " + req.getArgument()); - - StringBuffer mlstStr = new StringBuffer(80); - mlstStr.append(" "); - - generateMlstString(finfo, m_mlstFacts, mlstStr, true); - mlstStr.append(CRLF); - - sendFTPResponse(mlstStr.toString()); - sendFTPResponse("250 End"); - - // DEBUG - - if ( logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Mlst ftp=" + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", info=" + finfo); - } catch (Exception ex) { - sendFTPResponse(550, "Error retrieving file information"); - } - } - - /** - * Process a machine listing request, folder contents - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procMachineListingContents(FTPRequest req) - throws IOException { - - // Check if the user is logged in - - if (isLoggedOn() == false) { - sendFTPResponse(500, ""); - return; - } - - // Check if the request has an argument, if not then use the current - // working directory - - if (req.hasArgument() == false) - req.updateArgument("."); - - // Create the path for the file listing - - FTPPath ftpPath = m_cwd; - if (req.hasArgument()) - ftpPath = generatePathForRequest(req, true); - - if (ftpPath == null) { - sendFTPResponse(500, "Invalid path"); - return; - } - - // Check if the session has the required access - - if (ftpPath.isRootPath() == false) { - - // Check if the session has access to the filesystem - - TreeConnection tree = getTreeConnection(ftpPath.getSharedDevice()); - if (tree == null || tree.hasReadAccess() == false) { - - // Session does not have access to the filesystem - - sendFTPResponse(550, "Access denied"); - return; - } - } - - // Send the intermediate response - - sendFTPResponse(150, "File status okay, about to open data connection"); - - // Check if there is an active data session - - if (m_dataSess == null) { - sendFTPResponse(425, "Can't open data connection"); - return; - } - - // Get the data connection socket - - Socket dataSock = null; - - try { - dataSock = m_dataSess.getSocket(); - } catch (Exception ex) { - logger.error(ex); - } - - if (dataSock == null) { - sendFTPResponse(426, "Connection closed; transfer aborted"); - return; - } - - // Output the directory listing to the client - - Writer dataWrt = null; - - try { - - // Open an output stream to the client - - if ( isUTF8Enabled()) - dataWrt = new OutputStreamWriter(dataSock.getOutputStream(), "UTF-8"); - else - dataWrt = new OutputStreamWriter(dataSock.getOutputStream()); - - // Get a list of file information objects for the current directory - - Vector files = null; - - files = listFilesForPath(ftpPath, false, false); - - // Output the file list to the client - - if (files != null) { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_SEARCH)) - logger.debug("MLsd found " + files.size() + " files in " + ftpPath.getFTPPath()); - - // Output the file information to the client - - StringBuffer str = new StringBuffer(MLSD_BUFFER_SIZE); - - for (int i = 0; i < files.size(); i++) { - - // Get the current file information - - FileInfo finfo = (FileInfo) files.elementAt(i); - - generateMlstString(finfo, m_mlstFacts, str, false); - str.append(CRLF); - - // Output the file information record when the buffer is - // full - - if (str.length() >= MLSD_BUFFER_SIZE) { - - // Output the file data records - - dataWrt.write(str.toString()); - - // Reset the buffer - - str.setLength(0); - } - } - - // Flush any remaining file record data - - if (str.length() > 0) - dataWrt.write(str.toString()); - } - - // End of file list transmission - - sendFTPResponse(226, "Closing data connection"); - } catch (Exception ex) { - - // Failed to send file listing - - sendFTPResponse(451, "Error reading file list"); - } finally { - - // Close the data stream to the client - - if (dataWrt != null) - dataWrt.close(); - - // Close the data connection to the client - - if (m_dataSess != null) { - getFTPServer().releaseDataSession(m_dataSess); - m_dataSess = null; - } - } - } - - /** - * Process a modify date/time command - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procModifyDateTime(FTPRequest req) throws IOException { - - // Check if the user is logged in - - if (isLoggedOn() == false) { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Check the format of the argument to detemine if this is a get or set - // modify date/time request - // - // Get format is just the filename/path - // Set format is YYYYMMDDHHMMSS - - String path = req.getArgument(); - long modifyDateTime = 0L; - - if (path.length() > MDTM_DATETIME_MINLEN && path.indexOf(' ') != -1) { - - // Check if the first argument looks like a date/time value - - boolean settime = true; - for (int i = 0; i < MDTM_DATETIME_MINLEN; i++) { - if (Character.isDigit(path.charAt(i)) == false) - settime = false; - } - - // Looks like a date/time value - - if (settime == true) { - - try { - - // Parse the various fields - - int year = Integer.valueOf(path.substring(0, 4)).intValue(); - int month = Integer.valueOf(path.substring(4, 6)).intValue(); - int day = Integer.valueOf(path.substring(6, 8)).intValue(); - - int hours = Integer.valueOf(path.substring(8, 10)).intValue(); - int mins = Integer.valueOf(path.substring(10, 12)).intValue(); - int secs = Integer.valueOf(path.substring(12, 14)).intValue(); - - // Check if the date/time includes milliseconds - - int millis = 0; - int sep = path.indexOf(' ', MDTM_DATETIME_MINLEN); - - if (path.charAt(MDTM_DATETIME_MINLEN) == '.') { - - // Find the seperator between the date/time and path - - millis = Integer.valueOf(path.substring(MDTM_DATETIME_MINLEN + 1, sep)) - .intValue(); - } - - // Create the modify date/time - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - - cal.set(year, month, day, hours, mins, secs); - if (millis != 0) - cal.set(Calendar.MILLISECOND, millis); - - // Get the modify date/time - - modifyDateTime = cal.getTimeInMillis(); - - // Remove the date/time from the request argument - - path = path.substring(sep + 1); - req.updateArgument(path); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("Modify date/time arg=" + path + ", utcTime=" + modifyDateTime); - } catch (NumberFormatException ex) { - } - } - } - - // Create the path for the file listing - - FTPPath ftpPath = generatePathForRequest(req, true); - if (ftpPath == null) { - sendFTPResponse(550, "Invalid path"); - return; - } - - // Get the file information - - DiskInterface disk = null; - TreeConnection tree = null; - - try { - - // Create a temporary tree connection - - tree = getTreeConnection(ftpPath.getSharedDevice()); - - // Access the virtual filesystem driver - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - - // Check if the modify date/time should be set - - if (modifyDateTime != 0L) { - - // Set the file/folder modification date/time - - FileInfo finfo = new FileInfo(); - finfo.setModifyDateTime(modifyDateTime); - finfo.setFileInformationFlags(FileInfo.SetModifyDate); - - disk.setFileInformation(this, tree, ftpPath.getSharePath(), - finfo); - } - - // Get the file information - - FileInfo finfo = disk.getFileInformation(this, tree, ftpPath - .getSharePath()); - - if (finfo == null) { - sendFTPResponse(550, "File " + req.getArgument() - + " not available"); - return; - } - - // Return the file modification date/time - - if (finfo.hasModifyDateTime()) - sendFTPResponse(213, FTPDate.packMlstDateTime(finfo - .getModifyDateTime())); - else - sendFTPResponse(550, - "Modification date/time not available for " - + finfo.getFileName()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("File modify date/time ftp=" - + ftpPath.getFTPPath() + ", share=" - + ftpPath.getShareName() + ", modified=" - + finfo.getModifyDateTime()); - } catch (Exception ex) { - sendFTPResponse(550, "Error retrieving file modification date/time"); - } - } - - /** - * Process a server features request - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procFeatures(FTPRequest req) throws IOException { - - // Return the list of supported server features - - sendFTPResponse("211-Features supported"); - - // MOdify date/time and size commands supported - - if ( FeatureMDTM) - sendFTPResponse(" MDTM"); - - if ( FeatureSIZE) - sendFTPResponse(" SIZE"); - - if ( FeatureUTF8) - sendFTPResponse(" UTF8"); - - // Machine listing supported, build the fact list - - if ( FeatureMLST) - { - StringBuffer mlstStr = new StringBuffer(); - - mlstStr.append(" MLST "); - - for (int i = 0; i < _factNames.length; i++) { - - // Output the fact name - - mlstStr.append(_factNames[i]); - - // Check if the fact is enabled by default - - if ((MLST_DEFAULT & (1 << i)) != 0) - mlstStr.append("*"); - mlstStr.append(";"); - } - - sendFTPResponse(mlstStr.toString()); - sendFTPResponse(" MLSD"); - } - - sendFTPResponse(211, "END"); - } - - /** - * Process a file size command - * - * @param req - * FTPRequest - * @exception IOException - */ - protected final void procFileSize(FTPRequest req) throws IOException - { - - // Check if the user is logged in - - if (isLoggedOn() == false) - { - sendFTPResponse(500, ""); - return; - } - - // Check if an argument has been specified - - if (req.hasArgument() == false) - { - sendFTPResponse(501, "Syntax error, parameter required"); - return; - } - - // Create the path for the file listing - - FTPPath ftpPath = generatePathForRequest(req, true); - if (ftpPath == null) - { - sendFTPResponse(550, "Invalid path"); - return; - } - - // Get the file information - - DiskInterface disk = null; - TreeConnection tree = null; - - try - { - - // Create a temporary tree connection - - tree = getTreeConnection(ftpPath.getSharedDevice()); - - // Access the virtual filesystem driver - - disk = (DiskInterface) ftpPath.getSharedDevice().getInterface(); - - // Get the file information - - FileInfo finfo = disk.getFileInformation(this, tree, ftpPath.getSharePath()); - - if (finfo == null) - { - sendFTPResponse(550, "File " + req.getArgument() + " not available"); - return; - } - - // Return the file size - - sendFTPResponse(213, "" + finfo.getSize()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_FILE)) - logger.debug("File size ftp=" - + ftpPath.getFTPPath() + ", share=" + ftpPath.getShareName() + ", size=" + finfo.getSize()); - } - catch (Exception ex) - { - sendFTPResponse(550, "Error retrieving file size"); - } - } - - /** - * Process a site specific command - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procSite(FTPRequest req) - throws IOException - { - // Check if the user is logged in - - if (isLoggedOn() == false) { - sendFTPResponse(500, ""); - return; - } - - // Check if the FTP server has a site interface - - if ( getFTPServer().hasSiteInterface()) { - - // Pass the request to the site interface - - FTPSiteInterface siteInterface = getFTPServer().getSiteInterface(); - - siteInterface.processFTPSiteCommand( this, req); - } - else { - - // SITE command not implemented - - sendFTPResponse( 501, "SITE commands not implemented"); - } - } - - /** - * Process a structure command. This command is obsolete. - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procStructure(FTPRequest req) throws IOException - { - - // Check for the file structure argument - - if (req.hasArgument() && req.getArgument().equalsIgnoreCase("F")) - sendFTPResponse(200, "OK"); - - // Return an error response - - sendFTPResponse(504, "Obsolete"); - } - - /** - * Process a mode command. This command is obsolete. - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procMode(FTPRequest req) throws IOException - { - - // Check for the stream transfer mode argument - - if (req.hasArgument() && req.getArgument().equalsIgnoreCase("S")) - sendFTPResponse(200, "OK"); - - // Return an error response - - sendFTPResponse(504, "Obsolete"); - } - - /** - * Abort an active file transfer - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procAbort(FTPRequest req) throws IOException - { - // Check if threaded transfers are enabled - - if ( UseThreadedDataTransfer == true) - { - // Check if there is an active data connection - - if ( m_dataSess != null) - { - // Abort the data transfer - - m_dataSess.abortTransfer(); - } - else - { - // Send an error status, no transfer in progress - - sendFTPResponse( 226, "Data connection not active"); - } - } - else - { - // Abort not implemented for inline transfers - - sendFTPResponse( 502, "Abort not implemented"); - } - } - - /** - * Process an allocate command. This command is obsolete. - * - * @param req FTPRequest - * @exception IOException - */ - protected final void procAllocate(FTPRequest req) throws IOException - { - - // Return a response - - sendFTPResponse(202, "Obsolete"); - } - - /** - * Build a list of file name or file information objects for the specified - * server path - * - * @param path FTPPath - * @param nameOnly boolean - * @param hidden boolean - * @return Vector - */ - protected final Vector listFilesForPath(FTPPath path, boolean nameOnly, boolean hidden) - { - - // Check if the path is valid - - if (path == null) - return null; - - // Check if the path is the root path - - Vector files = new Vector(); - - if (path.hasSharedDevice() == false) - { - - // The first level of directories are mapped to the available shares - // Guest users only see their own list of shares - - SharedDeviceList shares = null; - if ( getClientInformation().isGuest()) - shares = getDynamicShareList(); - else - shares = getShareList(); - - if (shares != null) - { - - // Search for disk shares - - Enumeration enm = shares.enumerateShares(); - - while (enm.hasMoreElements()) - { - - // Get the current shared device - - SharedDevice shr = enm.nextElement(); - - // Add the share name or full information to the list - - if (nameOnly == false) - { - - // Create a file information object for the top level - // directory details - - FileInfo finfo = new FileInfo(shr.getName(), 0L, FileAttribute.Directory); - files.add(finfo); - } - else - files.add(new FileInfo(shr.getName(), 0L, FileAttribute.Directory)); - } - } - } - else - { - - // Append a wildcard to the search path - - String searchPath = path.getSharePath(); - - if (path.isDirectory()) - searchPath = path.makeSharePathToFile("*"); - - // Create a temporary tree connection - - TreeConnection tree = new TreeConnection(path.getSharedDevice()); - - // Start a search on the specified disk share - - DiskInterface disk = null; - SearchContext ctx = null; - - int searchAttr = FileAttribute.Directory + FileAttribute.Normal; - if (hidden) - searchAttr += FileAttribute.Hidden; - - try - { - disk = (DiskInterface) path.getSharedDevice().getInterface(); - ctx = disk.startSearch(this, tree, searchPath, searchAttr); - } - catch (Exception ex) - { - } - - // Add the files to the list - - if (ctx != null) - { - - // Get the file names/information - - FileInfo finfo = new FileInfo(); - - while (ctx.hasMoreFiles()) - { - // Get the next file details - - if ( ctx.nextFileInfo( finfo) == false) - break; - - // Filter out link nodes - - if ( finfo.isFileType() != FileType.SymbolicLink) - { - // Check if a file name or file information is required - - if (nameOnly) - { - // Add a file name to the list - - files.add(new FileInfo(ctx.nextFileName(), 0L, 0)); - } - else - { - // add the file information - - if (finfo.getFileName() != null) - files.add(finfo); - } - - // Allocate a new file information object - - finfo = new FileInfo(); - } - } - } - } - - // Return the list of file names/information - - return files; - } - - /** - * Get the list of filtered shares that are available to this session - * - * @return SharedDeviceList - */ - protected final SharedDeviceList getShareList() - { - - // Check if the filtered share list has been initialized - - if (m_shares == null) - { - - // Get a list of shared filesystems - - SharedDeviceList shares = getFTPServer().getShareMapper().getShareList(getFTPServer().getServerName(), - this, false); - - // Search for disk shares - - TenantService tenantService = getServer().getConfiguration().getTenantService(); - - m_shares = new SharedDeviceList(); - Enumeration enm = shares.enumerateShares(); - - while (enm.hasMoreElements()) - { - - // Get the current shared device - - SharedDevice shr = (SharedDevice) enm.nextElement(); - - // Check if the share is a disk share - - if (shr instanceof DiskSharedDevice) - { - if ((tenantService.isEnabled()) && (tenantService.isTenantUser())) - { - DiskSharedDevice dsd = (DiskSharedDevice)shr; - DiskDeviceContext ddc = dsd.getDiskContext(); - if (ddc instanceof ContentContext) - { - // TODO - consider fixed tenant-specific shares ? - ContentContext cc = (ContentContext)ddc; - - DiskSharedDevice tenantCompanyHomeShare = createCompanyHomeDiskShare(cc.getFilesystemName(), cc.getStoreName(), cc.getRootPath()); - m_shares.addShare(tenantCompanyHomeShare); - continue; - } - - try - { - if (shr.getInterface() instanceof AVMDiskDriver) - { - // skip - continue; - } - } - catch (InvalidDeviceInterfaceException ex) - { - } - } - - m_shares.addShare(shr); - } - } - - // Check if there is an access control manager available, if so then - // filter the list of - // shared filesystems - - if (getServer().hasAccessControlManager()) - { - - // Get the access control manager - - AccessControlManager aclMgr = getServer().getAccessControlManager(); - - // Filter the list of shared filesystems - - m_shares = aclMgr.filterShareList(this, m_shares); - } - } - - // Return the filtered shared filesystem list - - return m_shares; - } - - /** - * Get a tree connection for the specified shared device. Creates and caches - * a new tree connection if required. - * - * @param share SharedDevice - * @return TreeConnection - */ - protected final TreeConnection getTreeConnection(SharedDevice share) - { - - // Check if the share is valid - - if (share == null) - return null; - - // Check if there is a tree connection in the cache - - TreeConnection tree = m_connections.findConnection(share.getName()); - if (tree == null) - { - - // Create a new tree connection, do not add dynamic shares to the connection cache - - tree = new TreeConnection(share); - if ( share.isTemporary() == false) - m_connections.addConnection(tree); - - // Set the access permission for the shared filesystem - - if (getServer().hasAccessControlManager()) - { - - // Set the access permission to the shared filesystem - - AccessControlManager aclMgr = getServer().getAccessControlManager(); - - int access = aclMgr.checkAccessControl(this, share); - if (access != AccessControl.Default) - tree.setPermission(access); - } - } - - // Return the connection - - return tree; - } - - /** - * Create a disk share for the home folder - * - * @param client ClientInfo - * @return DiskSharedDevice - */ - private final DiskSharedDevice createHomeDiskShare(ClientInfo client) - { - // Check if the home folder has been set for the user - - if ( client.hasHomeFolder() == false) - { - // Get the required services - - NodeService nodeService = getServer().getConfiguration().getNodeService(); - PersonService personService = getServer().getConfiguration().getPersonService(); - TransactionService transService = getServer().getConfiguration().getTransactionService(); - - // Get the home folder for the user - - UserTransaction tx = transService.getUserTransaction(); - NodeRef homeSpaceRef = null; - - try - { - tx.begin(); - homeSpaceRef = (NodeRef) nodeService.getProperty( personService.getPerson(client.getUserName()), - ContentModel.PROP_HOMEFOLDER); - client.setHomeFolder( homeSpaceRef); - tx.commit(); - } - catch (Throwable ex) - { - try - { - tx.rollback(); - } - catch (Exception ex2) - { - logger.error("Failed to rollback transaction", ex2); - } - - if(ex instanceof RuntimeException) - { - throw (RuntimeException)ex; - } - else - { - throw new RuntimeException("Failed to get home folder", ex); - } - } - } - - // Create the disk driver and context - - DiskInterface diskDrv = getServer().getConfiguration().getDiskInterface(); - DiskDeviceContext diskCtx = new ContentContext( client.getUserName(), "", "", client.getHomeFolder()); - - // Default the filesystem to look like an 80Gb sized disk with 90% free space - - diskCtx.setDiskInformation(new SrvDiskInfo(2560, 64, 512, 2304)); - - // Create a temporary shared device for the users home directory - - return new DiskSharedDevice( client.getUserName(), diskDrv, diskCtx, SharedDevice.Temporary); - } - - private final DiskSharedDevice createCompanyHomeDiskShare(String filesysName, String storeName, String rootPath) - { - TenantService tenantService = getServer().getConfiguration().getTenantService(); - NodeService nodeService = getServer().getConfiguration().getNodeService(); - SearchService searchService = getServer().getConfiguration().getSearchService(); - NamespaceService namespaceService = getServer().getConfiguration().getNamespaceService(); - - StoreRef storeRef = new StoreRef(storeName); - NodeRef rootNodeRef = new NodeRef(storeRef.getProtocol(), storeRef.getIdentifier(), "dummy"); - - // root nodeRef is required for storeRef part - rootNodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, rootNodeRef); - - // Create the disk driver and context - - DiskInterface diskDrv = getServer().getConfiguration().getDiskInterface(); - DiskDeviceContext diskCtx = new ContentContext(filesysName, "", rootPath, rootNodeRef); - - // 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(filesysName, diskDrv, diskCtx, SharedDevice.Temporary); - } - - - /** - * Start the FTP session in a seperate thread - */ - public void run() - { - - try - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("FTP session started"); - - // Create the input/output streams - - m_in = m_sock.getInputStream(); - m_out = new OutputStreamWriter(m_sock.getOutputStream()); - - m_inbuf = new byte[512]; - m_outbuf = new StringBuffer(256); - - // Return the initial response - - sendFTPResponse(220, "FTP server ready"); - - // Start/end times if timing debug is enabled - - long startTime = 0L; - long endTime = 0L; - - // Create an FTP request to hold command details - - FTPRequest ftpReq = new FTPRequest(); - - // The server session loops until the NetBIOS hangup state is set. - - int rdlen = -1; - String cmd = null; - - while (m_sock != null) - { - - // Wait for a data packet - - rdlen = m_in.read(m_inbuf); - - // Check if there is no more data, the other side has dropped - // the connection - - if (rdlen == -1) - { - closeSession(); - continue; - } - - // Trim the trailing - - if (rdlen > 0) - { - while (rdlen > 0 && m_inbuf[rdlen - 1] == '\r' || m_inbuf[rdlen - 1] == '\n') - rdlen--; - } - - // Get the command string, decode as UTF-8 if enabled - - if ( isUTF8Enabled()) - { - // Convert the string from UTF-8 - - cmd = Normalizer.compose( new String(m_inbuf, 0, rdlen, "UTF-8"), false); - } - else - { - // Convert the request using the configured character set - - cmd = new String(m_inbuf, 0, rdlen, getFTPServer().getCharacterSet()); - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_TIMING)) - startTime = System.currentTimeMillis(); - - if (logger.isDebugEnabled() && hasDebug(DBG_PKTTYPE)) - logger.debug("Cmd " + ftpReq); - - // Parse the received command, and validate - - ftpReq.setCommandLine(cmd); - m_reqCount++; - - switch (ftpReq.isCommand()) - { - // User command - - case FTPCommand.User: - procUser(ftpReq); - break; - - // Password command - - case FTPCommand.Pass: - procPassword(ftpReq); - break; - - // Quit command - - case FTPCommand.Quit: - procQuit(ftpReq); - break; - - // Type command - - case FTPCommand.Type: - procType(ftpReq); - break; - - // Port command - - case FTPCommand.Port: - procPort(ftpReq); - break; - - // Passive command - - case FTPCommand.Pasv: - procPassive(ftpReq); - break; - - // Restart position command - - case FTPCommand.Rest: - procRestart(ftpReq); - break; - - // Return file command - - case FTPCommand.Retr: - procReturnFile(ftpReq); - - // Reset the restart position - - m_restartPos = 0; - break; - - // Store file command - - case FTPCommand.Stor: - procStoreFile(ftpReq, false); - break; - - // Append file command - - case FTPCommand.Appe: - procStoreFile(ftpReq, true); - break; - - // Print working directory command - - case FTPCommand.Pwd: - case FTPCommand.XPwd: - procPrintWorkDir(ftpReq); - break; - - // Change working directory command - - case FTPCommand.Cwd: - case FTPCommand.XCwd: - procChangeWorkDir(ftpReq); - break; - - // Change to previous directory command - - case FTPCommand.Cdup: - case FTPCommand.XCup: - procCdup(ftpReq); - break; - - // Full directory listing command - - case FTPCommand.List: - procList(ftpReq); - break; - - // Short directory listing command - - case FTPCommand.Nlst: - procNList(ftpReq); - break; - - // Delete file command - - case FTPCommand.Dele: - procDeleteFile(ftpReq); - break; - - // Rename file from command - - case FTPCommand.Rnfr: - procRenameFrom(ftpReq); - break; - - // Rename file to comand - - case FTPCommand.Rnto: - procRenameTo(ftpReq); - break; - - // Create new directory command - - case FTPCommand.Mkd: - case FTPCommand.XMkd: - procCreateDirectory(ftpReq); - break; - - // Delete directory command - - case FTPCommand.Rmd: - case FTPCommand.XRmd: - procRemoveDirectory(ftpReq); - break; - - // Return file size command - - case FTPCommand.Size: - procFileSize(ftpReq); - break; - - // Set modify date/time command - - case FTPCommand.Mdtm: - procModifyDateTime(ftpReq); - break; - - // System status command - - case FTPCommand.Syst: - procSystemStatus(ftpReq); - break; - - // Server status command - - case FTPCommand.Stat: - procServerStatus(ftpReq); - break; - - // Help command - - case FTPCommand.Help: - procHelp(ftpReq); - break; - - // No-op command - - case FTPCommand.Noop: - procNoop(ftpReq); - break; - - // Structure command (obsolete) - - case FTPCommand.Stru: - procStructure(ftpReq); - break; - - // Mode command (obsolete) - - case FTPCommand.Mode: - procMode(ftpReq); - break; - - // Allocate command (obsolete) - - case FTPCommand.Allo: - procAllocate(ftpReq); - break; - - // Abort an active file data transfer - - case FTPCommand.Abor: - procAbort(ftpReq); - break; - - // Return the list of features that this server supports - - case FTPCommand.Feat: - procFeatures(ftpReq); - break; - - // Options command - - case FTPCommand.Opts: - procOptions(ftpReq); - break; - - // Machine listing, single folder - - case FTPCommand.MLst: - procMachineListing(ftpReq); - break; - - // Machine listing, folder contents - - case FTPCommand.MLsd: - procMachineListingContents(ftpReq); - break; - - // Site specific commands - - case FTPCommand.Site: - procSite( ftpReq); - break; - - // Unknown/unimplemented command - - default: - if (ftpReq.isCommand() != FTPCommand.InvalidCmd) - sendFTPResponse(502, "Command " - + FTPCommand.getCommandName(ftpReq.isCommand()) + " not implemented"); - else - sendFTPResponse(502, "Command not implemented"); - break; - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_TIMING)) - { - endTime = System.currentTimeMillis(); - long duration = endTime - startTime; - if (duration > 20) - logger.debug("Processed cmd " - + FTPCommand.getCommandName(ftpReq.isCommand()) + " in " + duration + "ms"); - } - - // 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); - } - - } // end while state - } - catch (SocketException ex) - { - - // DEBUG - - if (logger.isErrorEnabled() && hasDebug(DBG_STATE)) - logger.error("Socket closed by remote client"); - } - catch (Exception ex) - { - - // Output the exception details - - if (isShutdown() == false) - { - logger.debug(ex); - } - } - finally - { - // If there is an active transaction then roll it back - - if ( hasUserTransaction()) - { - try - { - getUserTransaction().rollback(); - } - catch (Exception ex) - { - logger.warn("Failed to rollback transaction", ex); - } - } - } - - // Cleanup the session, make sure all resources are released - - closeSession(); - - // Debug - - if (hasDebug(DBG_STATE)) - logger.debug("Server session closed"); - } - - /** - * Authenticate an associated FTP data session using the same credentials as the main FTP session - * - * @exception AuthenticationException - */ - protected void authenticateDataSession() throws org.alfresco.repo.security.authentication.AuthenticationException - { - // Use the normal authentication service as we have the plaintext password - - AuthenticationService authService = getServer().getConfiguration().getAuthenticationService(); - - // Authenticate the user - - ClientInfo cInfo = getClientInformation(); - - if ( cInfo.isGuest()) - { - // Authenticate as the guest user - - authService.authenticateAsGuest(); - } - else - { - // Authenticate as a normal user - - authService.authenticate( cInfo.getUserName(), cInfo.getPasswordAsCharArray()); - } - } - - /** - * Generate a machine listing string for the specified file/folder information - * - * @param finfo FileInfo - * @param mlstFlags int - * @param buf StringBuffer - * @param isMlsd boolean - */ - protected final void generateMlstString(FileInfo finfo, int mlstFlags, StringBuffer buf, boolean isMlsd) - { - // Create the machine listing record - - for (int i = 0; i < _factNames.length; i++) { - - // Check if the current fact is enabled - - int curFact = 1 << i; - - if ((mlstFlags & curFact) != 0) { - - // Output the fact value - - switch (curFact) { - - // File size - - case MLST_SIZE: - buf.append(_factNames[i]); - buf.append("="); - buf.append(finfo.getSize()); - buf.append(";"); - break; - - // Modify date/time - - case MLST_MODIFY: - if (finfo.hasModifyDateTime()) { - buf.append(_factNames[i]); - buf.append("="); - buf.append(FTPDate.packMlstDateTime(finfo.getModifyDateTime())); - buf.append(";"); - } - break; - - // Creation date/time - - case MLST_CREATE: - if (finfo.hasCreationDateTime()) { - buf.append(_factNames[i]); - buf.append("="); - buf.append(FTPDate.packMlstDateTime(finfo.getCreationDateTime())); - buf.append(";"); - } - break; - - // Type - - case MLST_TYPE: - buf.append(_factNames[i]); - - if (finfo.isDirectory() == false) { - buf.append("=file;"); - } else { - buf.append("=dir;"); - } - break; - - // Unique identifier - - case MLST_UNIQUE: - if (finfo.getFileId() != -1) { - buf.append(_factNames[i]); - buf.append("="); - buf.append(finfo.getFileId()); - buf.append(";"); - } - break; - - // Permissions - - case MLST_PERM: - buf.append(_factNames[i]); - buf.append("="); - if (finfo.isDirectory()) { - buf.append(finfo.isReadOnly() ? "el" : "ceflmp"); - } else { - buf.append(finfo.isReadOnly() ? "r" : "rwadf"); - } - buf.append(";"); - break; - - // Media-type - - case MLST_MEDIATYPE: - break; - } - } - } - - // Add the file name - - buf.append(" "); - buf.append(finfo.getFileName()); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/ftp/InvalidPathException.java b/source/java/org/alfresco/filesys/ftp/InvalidPathException.java deleted file mode 100644 index 9723f5dd40..0000000000 --- a/source/java/org/alfresco/filesys/ftp/InvalidPathException.java +++ /dev/null @@ -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); - } -} diff --git a/source/java/org/alfresco/filesys/locking/FileLock.java b/source/java/org/alfresco/filesys/locking/FileLock.java deleted file mode 100644 index d466acf42f..0000000000 --- a/source/java/org/alfresco/filesys/locking/FileLock.java +++ /dev/null @@ -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 - *

- * 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(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/locking/FileLockException.java b/source/java/org/alfresco/filesys/locking/FileLockException.java deleted file mode 100644 index b4bcec0729..0000000000 --- a/source/java/org/alfresco/filesys/locking/FileLockException.java +++ /dev/null @@ -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); - } -} diff --git a/source/java/org/alfresco/filesys/locking/FileLockList.java b/source/java/org/alfresco/filesys/locking/FileLockList.java deleted file mode 100644 index 966ddd00bd..0000000000 --- a/source/java/org/alfresco/filesys/locking/FileLockList.java +++ /dev/null @@ -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 - *

- * Contains a list of the current locks on a file. - */ -public class FileLockList -{ - - // List of file locks - - private Vector m_lockList; - - /** - * Construct an empty file lock list. - */ - public FileLockList() - { - m_lockList = new Vector(); - } - - /** - * 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(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/locking/FileUnlockException.java b/source/java/org/alfresco/filesys/locking/FileUnlockException.java deleted file mode 100644 index af58e1ceff..0000000000 --- a/source/java/org/alfresco/filesys/locking/FileUnlockException.java +++ /dev/null @@ -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); - } -} diff --git a/source/java/org/alfresco/filesys/locking/LockConflictException.java b/source/java/org/alfresco/filesys/locking/LockConflictException.java deleted file mode 100644 index 83b9cc3929..0000000000 --- a/source/java/org/alfresco/filesys/locking/LockConflictException.java +++ /dev/null @@ -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 - *

- * 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); - } -} diff --git a/source/java/org/alfresco/filesys/locking/NotLockedException.java b/source/java/org/alfresco/filesys/locking/NotLockedException.java deleted file mode 100644 index ea785682c9..0000000000 --- a/source/java/org/alfresco/filesys/locking/NotLockedException.java +++ /dev/null @@ -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 - *

- * 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); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSDatagram.java b/source/java/org/alfresco/filesys/netbios/NetBIOSDatagram.java deleted file mode 100644 index 13acaf3af6..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSDatagram.java +++ /dev/null @@ -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() - { - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSDatagramSocket.java b/source/java/org/alfresco/filesys/netbios/NetBIOSDatagramSocket.java deleted file mode 100644 index d0f971e8cb..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSDatagramSocket.java +++ /dev/null @@ -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 - *

- * 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); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSException.java b/source/java/org/alfresco/filesys/netbios/NetBIOSException.java deleted file mode 100644 index 9ee454a988..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSException.java +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSName.java b/source/java/org/alfresco/filesys/netbios/NetBIOSName.java deleted file mode 100644 index 3a8cadb630..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSName.java +++ /dev/null @@ -1,1061 +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; -import java.util.StringTokenizer; -import java.util.Vector; - -import org.alfresco.filesys.util.IPAddress; - -/** - * NetBIOS Name Class. - */ -public class NetBIOSName -{ - // NetBIOS name length - - public static final int NameLength = 16; - - // NetBIOS name types - + type - - public static final char WorkStation = 0x00; - public static final char Messenger = 0x01; - public static final char RemoteMessenger = 0x03; - public static final char RASServer = 0x06; - public static final char FileServer = 0x20; - public static final char RASClientService = 0x21; - public static final char MSExchangeInterchange = 0x22; - public static final char MSExchangeStore = 0x23; - public static final char MSExchangeDirectory = 0x24; - public static final char LotusNotesServerService= 0x2B; - public static final char ModemSharingService = 0x30; - public static final char ModemSharingClient = 0x31; - public static final char McCaffeeAntiVirus = 0x42; - public static final char SMSClientRemoteControl = 0x43; - public static final char SMSAdminRemoteControl = 0x44; - public static final char SMSClientRemoteChat = 0x45; - public static final char SMSClientRemoteTransfer= 0x46; - public static final char DECPathworksService = 0x4C; - public static final char MSExchangeIMC = 0x6A; - public static final char MSExchangeMTA = 0x87; - public static final char NetworkMonitorAgent = 0xBE; - public static final char NetworkMonitorApp = 0xBF; - - // + type - - public static final char Domain = 0x00; // Group - public static final char DomainMasterBrowser = 0x1B; - public static final char DomainControllers = 0x1C; // Group - public static final char MasterBrowser = 0x1D; - public static final char DomainAnnounce = 0x1E; - - // Browse master - __MSBROWSE__ + type - - public static final char BrowseMasterGroup = 0x01; - - // Browse master NetBIOS name - - public static final String BrowseMasterName = "\u0001\u0002__MSBROWSE__\u0002"; - - // NetBIOS names - - public static final String SMBServer = "*SMBSERVER"; - public static final String SMBServer2 = "*SMBSERV"; - - // Adapter status request name - - public static final String AdapterStatusName = "*"; - - // Default time to live for name registrations - - public static final int DefaultTTL = 28800; // 8 hours - - // Name conversion string - - private static final String EncodeConversion = "ABCDEFGHIJKLMNOP"; - - // Character set to use when converting the NetBIOS name string to a byte array - - private static String _nameConversionCharset = null; - - // Name string and type - - private String m_name; - private char m_type; - - // Name scope - - private String m_scope; - - // Group name flag - - private boolean m_group = false; - - // Local name flag - - private boolean m_local = true; - - // IP address(es) of the owner of this name - - private Vector m_addrList; - - // Time that the name expires and time to live - - private long m_expiry; - private int m_ttl; // seconds - - /** - * Create a unique NetBIOS name. - * - * @param name java.lang.String - * @param typ char - * @param group - */ - public NetBIOSName(String name, char typ, boolean group) - { - setName(name); - setType(typ); - setGroup(group); - } - - /** - * Create a unique NetBIOS name. - * - * @param name java.lang.String - * @param typ char - * @param group boolean - * @param ipaddr byte[] - */ - public NetBIOSName(String name, char typ, boolean group, byte[] ipaddr) - { - setName(name); - setType(typ); - setGroup(group); - addIPAddress(ipaddr); - } - - /** - * Create a unique NetBIOS name. - * - * @param name java.lang.String - * @param typ char - * @param group boolean - * @param ipList Vector - */ - public NetBIOSName(String name, char typ, boolean group, Vector ipList) - { - setName(name); - setType(typ); - setGroup(group); - addIPAddresses(ipList); - } - - /** - * Create a unique NetBIOS name. - * - * @param name java.lang.String - * @param typ char - * @param group boolean - * @param ipaddr byte[] - * @param ttl int - */ - public NetBIOSName(String name, char typ, boolean group, byte[] ipaddr, int ttl) - { - setName(name); - setType(typ); - setGroup(group); - addIPAddress(ipaddr); - setTimeToLive(ttl); - } - - /** - * Create a unique NetBIOS name. - * - * @param name java.lang.String - * @param typ char - * @param group boolean - * @param ipList Vector - * @param ttl int - */ - public NetBIOSName(String name, char typ, boolean group, Vector ipList, int ttl) - { - setName(name); - setType(typ); - setGroup(group); - addIPAddresses(ipList); - setTimeToLive(ttl); - } - - /** - * Create a NetBIOS name from a byte array - * - * @param buf byte[] - * @param off int - */ - public NetBIOSName(byte[] buf, int off) - { - setName(new String(buf, off, NameLength - 1)); - setType((char) buf[off + NameLength - 1]); - } - - /** - * Create a NetBIOS name from an encoded name string - * - * @param name String - */ - public NetBIOSName(String name) - { - setName(name.substring(0, NameLength - 1).trim()); - setType(name.charAt(NameLength - 1)); - } - - /** - * Create a NetBIOS name from the specified name and scope - * - * @param name String - * @param scope String - */ - protected NetBIOSName(String name, String scope) - { - setName(name.substring(0, NameLength - 1).trim()); - setType(name.charAt(NameLength - 1)); - - if (scope != null && scope.length() > 0) - setNameScope(scope); - } - - /** - * Compare objects for equality. - * - * @return boolean - * @param obj java.lang.Object - */ - public boolean equals(Object obj) - { - - // Check if the object is a NetBIOSName type object - - if (obj instanceof NetBIOSName) - { - - // Check if the NetBIOS name, name type and local/remote flags are equal - - NetBIOSName nbn = (NetBIOSName) obj; - if (nbn.getName().equals(getName()) && nbn.getType() == getType() && nbn.isLocalName() == isLocalName()) - return true; - } - - // Objects are not equal - - return false; - } - - /** - * Return the system time that the NetBIOS name expires. - * - * @return long - */ - public final long getExpiryTime() - { - return m_expiry; - } - - /** - * Get the names time to live value, in seconds - * - * @return int - */ - public final int getTimeToLive() - { - return m_ttl; - } - - /** - * Return the number of addresses for this NetBIOS name - * - * @return int - */ - public final int numberOfAddresses() - { - return m_addrList != null ? m_addrList.size() : 0; - } - - /** - * Return the specified IP address that owns the NetBIOS name. - * - * @param idx int - * @return byte[] - */ - public final byte[] getIPAddress(int idx) - { - if (m_addrList == null || idx < 0 || idx >= m_addrList.size()) - return null; - return m_addrList.get(idx); - } - - /** - * Return the specified IP address that owns the NetBIOS name, as a string. - * - * @param idx int - * @return String - */ - public final String getIPAddressString(int idx) - { - if (m_addrList == null || idx < 0 || idx >= m_addrList.size()) - return null; - - // Get the raw IP address and build the address string - - return IPAddress.asString(m_addrList.get(idx)); - } - - /** - * Return the NetBIOS name. - * - * @return java.lang.String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the NetBIOS name as a 16 character string with the name and type - * - * @return byte[] - */ - public final byte[] getNetBIOSName() - { - - // Allocate a buffer to build the full name - - byte[] nameBuf = new byte[NameLength]; - - // Get the name string bytes - - byte[] nameBytes = null; - - try - { - if (hasNameConversionCharacterSet()) - nameBytes = getName().getBytes(getNameConversionCharacterSet()); - else - nameBytes = getName().getBytes(); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - - for (int i = 0; i < nameBytes.length; i++) - nameBuf[i] = nameBytes[i]; - for (int i = nameBytes.length; i < NameLength; i++) - nameBuf[i] = ' '; - nameBuf[NameLength - 1] = (byte) (m_type & 0xFF); - - return nameBuf; - } - - /** - * Determine if the name has a name scope - * - * @return boolean - */ - public final boolean hasNameScope() - { - return m_scope != null ? true : false; - } - - /** - * Return the name scope - * - * @return String - */ - public final String getNameScope() - { - return m_scope; - } - - /** - * Return the NetBIOS name type. - * - * @return char - */ - public final char getType() - { - return m_type; - } - - /** - * Return a hash code for this object. - * - * @return int - */ - public int hashCode() - { - return getName().hashCode() + (int) getType(); - } - - /** - * Returns true if this is a group type NetBIOS name. - * - * @return boolean - */ - public final boolean isGroupName() - { - return m_group; - } - - /** - * Determine if this is a local or remote NetBIOS name. - * - * @return boolean - */ - public final boolean isLocalName() - { - return m_local; - } - - /** - * Returns true if the NetBIOS name is a unique type name. - * - * @return boolean - */ - public final boolean isUniqueName() - { - return m_group ? false : true; - } - - /** - * Remove all TCP/IP addresses from the NetBIOS name - */ - public final void removeAllAddresses() - { - m_addrList.removeAllElements(); - } - - /** - * Set the system time that this NetBIOS name expires at. - * - * @param expires long - */ - public final void setExpiryTime(long expires) - { - m_expiry = expires; - } - - /** - * Set the names time to live, in seconds - * - * @param ttl int - */ - public final void setTimeToLive(int ttl) - { - m_ttl = ttl; - } - - /** - * Set/clear the group name flag. - * - * @param flag boolean - */ - public final void setGroup(boolean flag) - { - m_group = flag; - } - - /** - * Set the name scope - * - * @param scope String - */ - public final void setNameScope(String scope) - { - if (scope == null) - m_scope = null; - else if (scope.length() > 0 && scope.startsWith(".")) - m_scope = scope.substring(1); - else - m_scope = scope; - } - - /** - * Add an IP address to the list of addresses for this NetBIOS name - * - * @param ipaddr byte[] - */ - public final void addIPAddress(byte[] ipaddr) - { - if (m_addrList == null) - m_addrList = new Vector(); - m_addrList.add(ipaddr); - } - - /** - * Add a list of IP addresses to the list of addresses for this NetBIOS name - * - * @param ipaddr Vector - */ - public final void addIPAddresses(Vector addrList) - { - if (m_addrList == null) - m_addrList = new Vector(); - - // Add the addresses - - for (int i = 0; i < addrList.size(); i++) - { - byte[] addr = addrList.get(i); - m_addrList.add(addr); - } - } - - /** - * Set the local/remote NetBIOS name flag. - * - * @param local boolean - */ - public final void setLocalName(boolean local) - { - m_local = local; - } - - /** - * Set the NetBIOS name. - * - * @param name java.lang.String - */ - public final void setName(String name) - { - - // Check if the name contains a name scope, if so then split the name and scope id - - int pos = name.indexOf("."); - if (pos != -1) - { - - // Split the name and scope id - - setNameScope(name.substring(pos + 1)); - m_name = toUpperCaseName(name.substring(0, pos)); - } - else - { - - // Set the name - - m_name = toUpperCaseName(name); - } - } - - /** - * Set the NetBIOS name type. - * - * @param typ char - */ - public final void setType(char typ) - { - m_type = typ; - } - - /** - * Convert a name to uppercase - * - * @return String - */ - public static String toUpperCaseName(String name) - { - - // Trim the name, unless it looks like a special name - - if (name.length() > 2 && name.charAt(0) != 0x01 && name.charAt(1) != 0x02) - name = name.trim(); - - // Convert the string to uppercase - - if (name != null && name.length() > 0) - { - StringBuffer upperName = new StringBuffer(name.length()); - - for (int i = 0; i < name.length(); i++) - { - char ch = name.charAt(i); - if (ch >= 'a' && ch <= 'z') - upperName.append(Character.toUpperCase(ch)); - else - upperName.append(ch); - } - - // Return the uppercased name - - return upperName.toString(); - } - - // Invalid or empty name - - return ""; - } - - /** - * Determine if the name conversion character set has been configured - * - * @return boolean - */ - public final static boolean hasNameConversionCharacterSet() - { - return _nameConversionCharset != null ? true : false; - } - - /** - * Return the name conversion character set name - * - * @return String - */ - public final static String getNameConversionCharacterSet() - { - return _nameConversionCharset; - } - - /** - * Set the name conversion character set - * - * @param charSet String - */ - public final static void setNameConversionCharacterSet(String charSet) - { - _nameConversionCharset = charSet; - } - - /** - * Return the NetBIOS name as a string. - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(m_name); - - if (hasNameScope()) - { - str.append("."); - str.append(m_scope); - } - - str.append(":"); - str.append(TypeAsString(m_type)); - str.append(","); - if (m_group == true) - str.append("Group,"); - else - str.append("Unique,"); - if (numberOfAddresses() > 0) - { - for (int i = 0; i < numberOfAddresses(); i++) - { - str.append(getIPAddressString(i)); - str.append("|"); - } - } - str.append("]"); - return str.toString(); - } - - /** - * Convert a the NetBIOS name into RFC NetBIOS format. - * - * @return byte[] - */ - public byte[] encodeName() - { - - // Build the name string with the name type, make sure that the host - // name is uppercase. - - StringBuffer nbName = new StringBuffer(getName().toUpperCase()); - - if (nbName.length() > NameLength - 1) - nbName.setLength(NameLength - 1); - - // Space pad the name then add the NetBIOS name type - - while (nbName.length() < NameLength - 1) - nbName.append(' '); - nbName.append(getType()); - - // Allocate the return buffer. - // - // Length byte + encoded NetBIOS name length + name scope length + name scope - - int len = 34; - if (hasNameScope()) - len += getNameScope().length() + 1; - - byte[] encBuf = new byte[len]; - - // Convert the NetBIOS name string to the RFC NetBIOS name format - - int pos = 0; - encBuf[pos++] = (byte) 32; - int idx = 0; - - while (idx < nbName.length()) - { - - // Get the current character from the host name string - - char ch = nbName.charAt(idx++); - - if (ch == ' ') - { - - // Append an encoded character - - encBuf[pos++] = (byte) 'C'; - encBuf[pos++] = (byte) 'A'; - } - else - { - - // Append octet for the current character - - encBuf[pos++] = (byte) EncodeConversion.charAt((int) ch / 16); - encBuf[pos++] = (byte) EncodeConversion.charAt((int) ch % 16); - } - } - - // Check if there is a NetBIOS name scope to be appended to the encoded name string - - if (hasNameScope()) - { - - // Get the name scope and uppercase - - StringTokenizer tokens = new StringTokenizer(getNameScope(), "."); - - while (tokens.hasMoreTokens()) - { - - // Get the current token - - String token = tokens.nextToken(); - - // Append the name to the encoded NetBIOS name - - encBuf[pos++] = (byte) token.length(); - for (int i = 0; i < token.length(); i++) - encBuf[pos++] = (byte) token.charAt(i); - } - } - - // Terminate the encoded name string with a null section length - - encBuf[pos++] = (byte) 0; - - // Return the encoded NetBIOS name - - return encBuf; - } - - /** - * Find the best match address that the NetBIOS name is registered on that matches one of the - * local TCP/IP addresses - * - * @param addrList InetAddress[] - * @return int - */ - public final int findBestMatchAddress(InetAddress[] addrList) - { - - // Check if the address list is valid - - if (addrList == null || addrList.length == 0 || numberOfAddresses() == 0) - return -1; - - // If the NetBIOS name only has one address then just return the index - - if (numberOfAddresses() == 1) - return 0; - - // Search for a matching subnet - - int topCnt = 0; - int topIdx = -1; - - for (int localIdx = 0; localIdx < addrList.length; localIdx++) - { - - // Get the address bytes for the current local address - - byte[] localAddr = addrList[localIdx].getAddress(); - - // Match against the addresses that the NetBIOS name is registered against - - for (int addrIdx = 0; addrIdx < numberOfAddresses(); addrIdx++) - { - - // Get the current remote address bytes - - byte[] remoteAddr = (byte[]) m_addrList.elementAt(addrIdx); - int ipIdx = 0; - - while (ipIdx < 4 && remoteAddr[ipIdx] == localAddr[ipIdx]) - ipIdx++; - - // Check if the current address is the best match so far - - if (ipIdx > topIdx) - { - - // Update the best match address - - topIdx = addrIdx; - topCnt = ipIdx; - } - } - } - - // Return the best match index, or -1 if no match found - - return topIdx; - } - - /** - * Decode a NetBIOS name string and create a new NetBIOSName object - * - * @param buf byte[] - * @param off int - * @return NetBIOSName - */ - public static NetBIOSName decodeNetBIOSName(byte[] buf, int off) - { - - // Convert the RFC NetBIOS name string to a normal NetBIOS name string - - StringBuffer nameBuf = new StringBuffer(16); - - int nameLen = (int) buf[off++]; - int idx = 0; - char ch1, ch2; - - while (idx < nameLen) - { - - // Get the current encoded character pair from the encoded name string - - ch1 = (char) buf[off++]; - ch2 = (char) buf[off++]; - - if (ch1 == 'C' && ch2 == 'A') - { - - // Append a character - - nameBuf.append(' '); - } - else - { - - // Convert back to a character code - - int val = EncodeConversion.indexOf(ch1) << 4; - val += EncodeConversion.indexOf(ch2); - - // Append the current character to the decoded name - - nameBuf.append((char) (val & 0xFF)); - } - - // Update the encoded string index - - idx += 2; - - } - - // Decode the NetBIOS name scope, if specified - - StringBuffer scopeBuf = new StringBuffer(128); - nameLen = (int) buf[off++]; - - while (nameLen > 0) - { - - // Append a name seperator if not the first name section - - if (scopeBuf.length() > 0) - scopeBuf.append("."); - - // Copy the name scope section to the scope name buffer - - for (int i = 0; i < nameLen; i++) - scopeBuf.append((char) buf[off++]); - - // Get the next name section length - - nameLen = (int) buf[off++]; - } - - // Create a NetBIOS name - - return new NetBIOSName(nameBuf.toString(), scopeBuf.toString()); - } - - /** - * Decode a NetBIOS name string length - * - * @param buf byte[] - * @param off int - * @return int - */ - public static int decodeNetBIOSNameLength(byte[] buf, int off) - { - - // Calculate the encoded NetBIOS name string length - - int totLen = 1; - int nameLen = (int) buf[off++]; - - while (nameLen > 0) - { - - // Update the total encoded name length - - totLen += nameLen; - off += nameLen; - - // Get the next name section length - - nameLen = (int) buf[off++]; - totLen++; - } - - // Return the encoded NetBIOS name length - - return totLen; - } - - /** - * Return the NetBIOS name type as a string. - * - * @param typ char - * @return String - */ - public final static String TypeAsString(char typ) - { - - // Return the NetBIOS name type string - - String nameTyp = ""; - - switch (typ) - { - case WorkStation: - nameTyp = "WorkStation"; - break; - case Messenger: - nameTyp = "Messenger"; - break; - case RemoteMessenger: - nameTyp = "RemoteMessenger"; - break; - case RASServer: - nameTyp = "RASServer"; - break; - case FileServer: - nameTyp = "FileServer"; - break; - case RASClientService: - nameTyp = "RASClientService"; - break; - case MSExchangeInterchange: - nameTyp = "MSExchangeInterchange"; - break; - case MSExchangeStore: - nameTyp = "MSExchangeStore"; - break; - case MSExchangeDirectory: - nameTyp = "MSExchangeDirectory"; - break; - case LotusNotesServerService: - nameTyp = "LotusNotesServerService"; - break; - case ModemSharingService: - nameTyp = "ModemSharingService"; - break; - case ModemSharingClient: - nameTyp = "ModemSharingClient"; - break; - case McCaffeeAntiVirus: - nameTyp = "McCaffeeAntiVirus"; - break; - case SMSClientRemoteControl: - nameTyp = "SMSClientRemoteControl"; - break; - case SMSAdminRemoteControl: - nameTyp = "SMSAdminRemoteControl"; - break; - case SMSClientRemoteChat: - nameTyp = "SMSClientRemoteChat"; - break; - case SMSClientRemoteTransfer: - nameTyp = "SMSClientRemoteTransfer"; - break; - case DECPathworksService: - nameTyp = "DECPathworksService"; - break; - case MSExchangeIMC: - nameTyp = "MSExchangeIMC"; - break; - case MSExchangeMTA: - nameTyp = "MSExchangeMTA"; - break; - case NetworkMonitorAgent: - nameTyp = "NetworkMonitorAgent"; - break; - case NetworkMonitorApp: - nameTyp = "NetworkMonitorApp"; - break; - case DomainMasterBrowser: - nameTyp = "DomainMasterBrowser"; - break; - case MasterBrowser: - nameTyp = "MasterBrowser"; - break; - case DomainAnnounce: - nameTyp = "DomainAnnounce"; - break; - case DomainControllers: - nameTyp = "DomainControllers"; - break; - default: - nameTyp = "0x" + Integer.toHexString((int) typ); - break; - } - - return nameTyp; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSNameList.java b/source/java/org/alfresco/filesys/netbios/NetBIOSNameList.java deleted file mode 100644 index 1f68d4aecb..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSNameList.java +++ /dev/null @@ -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 m_nameList; - - /** - * Class constructor - */ - public NetBIOSNameList() - { - m_nameList = new Vector(); - } - - /** - * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java b/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java deleted file mode 100644 index d6fdb9123d..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSPacket.java +++ /dev/null @@ -1,1338 +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 org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NetBIOS Packet Class - */ -public class NetBIOSPacket -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.netbios"); - - // Minimum valid receive length - - public static final int MIN_RXLEN = 4; - - // NetBIOS opcodes - - public static final int NAME_QUERY = 0x00; - public static final int NAME_REGISTER = 0x05; - public static final int NAME_RELEASE = 0x06; - public static final int WACK = 0x07; - public static final int REFRESH = 0x08; - public static final int NAME_REGISTER_MULTI = 0x0F; - - public static final int RESP_QUERY = 0x10; - public static final int RESP_REGISTER = 0x15; - public static final int RESP_RELEASE = 0x16; - - // NetBIOS opcode masks - - public static final int MASK_OPCODE = 0xF800; - public static final int MASK_NMFLAGS = 0x07F0; - public static final int MASK_RCODE = 0x000F; - - public static final int MASK_NOOPCODE = 0x07FF; - public static final int MASK_NOFLAGS = 0xF80F; - public static final int MASK_NORCODE = 0xFFF0; - - public static final int MASK_RESPONSE = 0x0010; - - // Flags bit values - - public static final int FLG_BROADCAST = 0x0001; - public static final int FLG_RECURSION = 0x0008; - public static final int FLG_RECURSDES = 0x0010; - public static final int FLG_TRUNCATION = 0x0020; - public static final int FLG_AUTHANSWER = 0x0040; - - // NetBIOS name lookup types - - public static final int NAME_TYPE_NB = 0x0020; - public static final int NAME_TYPE_NBSTAT = 0x0021; - - // RFC NetBIOS encoded name length - - public static final int NAME_LEN = 32; - - // NetBIOS name classes - - public static final int NAME_CLASS_IN = 0x0001; - - // Bit shifts for opcode/flags values - - private static final int SHIFT_FLAGS = 4; - private static final int SHIFT_OPCODE = 11; - - // Default NetBIOS buffer size to allocate - - public static final int DEFAULT_BUFSIZE = 1024; - - // NetBIOS packet offsets - - private static final int NB_TRANSID = 0; - private static final int NB_OPCODE = 2; - private static final int NB_QDCOUNT = 4; - private static final int NB_ANCOUNT = 6; - private static final int NB_NSCOUNT = 8; - private static final int NB_ARCOUNT = 10; - private static final int NB_DATA = 12; - - // NetBIOS name registration error reponse codes (RCODE field) - - public static final int FMT_ERR = 0x01; - public static final int SRV_ERR = 0x02; - public static final int IMP_ERR = 0x04; - public static final int RFS_ERR = 0x05; - public static final int ACT_ERR = 0x06; - public static final int CFT_ERR = 0x07; - - // Name flags - - public static final int NAME_PERM = 0x0200; - public static final int NAME_ACTIVE = 0x0400; - public static final int NAME_CONFLICT = 0x0800; - public static final int NAME_DEREG = 0x1000; - public static final int NAME_GROUP = 0x8000; - - public static final int NAME_TYPE_BNODE = 0x0000; - public static final int NAME_TYPE_PNODE = 0x2000; - public static final int NAME_TYPE_MNODE = 0x4000; - public static final int NAME_TYPE_RESVD = 0x6000; - - // Adapter status name in encoded format - - private static final String AdapterStatusNBName = "CKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - - // NetBIOS packet buffer - - private byte[] m_nbbuf; - - // Actual used packet length - - private int m_datalen; - - /** - * Default constructor - */ - public NetBIOSPacket() - { - m_nbbuf = new byte[DEFAULT_BUFSIZE]; - m_datalen = NB_DATA; - } - - /** - * Create a NetBIOS packet with the specified buffer. - * - * @param buf byte[] - */ - public NetBIOSPacket(byte[] buf) - { - m_nbbuf = buf; - m_datalen = NB_DATA; - } - - /** - * Create a NetBIOS packet with the specified buffer size. - * - * @param siz int - */ - public NetBIOSPacket(int siz) - { - m_nbbuf = new byte[siz]; - m_datalen = NB_DATA; - } - - /** - * Dump the packet structure to the console. - * - * @param sessPkt True if this is a NetBIOS session packet, else false. - */ - public void DumpPacket(boolean sessPkt) - { - - // Display the transaction id - - logger.debug("NetBIOS Packet Dump :-"); - - // Detrmine the packet type - - if (sessPkt == true) - { - - switch (getPacketType()) - { - - // NetBIOS session request - - case RFCNetBIOSProtocol.SESSION_REQUEST: - StringBuffer name = new StringBuffer(); - for (int i = 0; i < 32; i++) - name.append((char) m_nbbuf[39 + i]); - logger.debug("Session request from " + NetBIOSSession.DecodeName(name.toString())); - break; - - // NetBIOS message - - case RFCNetBIOSProtocol.SESSION_MESSAGE: - break; - } - } - else - { - - // Display the packet type - - logger.debug(" Transaction Id : " + getTransactionId()); - - String opCode = null; - - switch (getOpcode()) - { - case NAME_QUERY: - opCode = "QUERY"; - break; - case RESP_QUERY: - opCode = "QUERY (Response)"; - break; - case NAME_REGISTER: - opCode = "NAME REGISTER"; - break; - case RESP_REGISTER: - opCode = "NAME REGISTER (Response)"; - break; - case NAME_RELEASE: - opCode = "NAME RELEASE"; - break; - case RESP_RELEASE: - opCode = "NAME RELEASE (Response)"; - break; - case WACK: - opCode = "WACK"; - break; - case REFRESH: - opCode = "REFRESH"; - break; - default: - opCode = Integer.toHexString(getOpcode()); - break; - } - logger.debug(" Opcode : " + opCode); - - // Display the flags - - logger.debug(" Flags : " + Integer.toHexString(getFlags())); - - // Display the name counts - - logger.debug(" QDCount : " + getQuestionCount()); - logger.debug(" ANCount : " + getAnswerCount()); - logger.debug(" NSCount : " + getNameServiceCount()); - logger.debug(" ARCount : " + getAdditionalCount()); - - // Dump the question name, if there is one - - if (getQuestionCount() > 0) - { - - // Get the encoded name string - - StringBuffer encName = new StringBuffer(); - for (int i = 1; i <= 32; i++) - encName.append((char) m_nbbuf[NB_DATA + i]); - - // Decode the name - - String name = NetBIOSSession.DecodeName(encName.toString()); - logger.debug(" QName : " + name + " <" + NetBIOSName.TypeAsString(name.charAt(15)) + ">"); - } - } - - // Dump the raw data - - logger.debug("********** Raw NetBIOS Data Dump **********"); - HexDump.Dump(getBuffer(), getLength(), 0); - } - - /** - * Get the additional byte count. - * - * @return int - */ - public final int getAdditionalCount() - { - return DataPacker.getShort(m_nbbuf, NB_ARCOUNT); - } - - /** - * Get the answer name details - * - * @return String - */ - public final String getAnswerName() - { - - // Pack the encoded name into the NetBIOS packet - - return NetBIOSSession.DecodeName(m_nbbuf, NB_DATA + 1); - } - - /** - * Get the answer count. - * - * @return int - */ - public final int getAnswerCount() - { - return DataPacker.getShort(m_nbbuf, NB_ANCOUNT); - } - - /** - * Get the answer name list - * - * @return NetBIOSNameList - */ - public final NetBIOSNameList getAnswerNameList() - { - - // Check if there are any answer names - - int cnt = getAnswerCount(); - if (cnt == 0) - return null; - - NetBIOSNameList nameList = new NetBIOSNameList(); - int pos = NB_DATA; - - while (cnt-- > 0) - { - - // Get a NetBIOS name from the buffer - - int nameLen = NetBIOSName.decodeNetBIOSNameLength(m_nbbuf, pos); - NetBIOSName name = NetBIOSName.decodeNetBIOSName(m_nbbuf, pos); - - // Skip the type, class and TTL - - pos += nameLen; - pos += 8; - - // Get the count of data bytes - - int dataCnt = DataPacker.getShort(m_nbbuf, pos); - pos += 2; - - while (dataCnt > 0) - { - - // Get the flags, check if the name is a unique or group name - - int flags = DataPacker.getShort(m_nbbuf, pos); - pos += 2; - if ((flags & NAME_GROUP) != 0) - name.setGroup(true); - - // Get the IP address and add to the list of addresses for the current name - - byte[] ipaddr = new byte[4]; - for (int i = 0; i < 4; i++) - ipaddr[i] = m_nbbuf[pos++]; - - name.addIPAddress(ipaddr); - - // Update the data count - - dataCnt -= 6; - } - - // Add the name to the name list - - nameList.addName(name); - } - - // Return the name list - - return nameList; - } - - /** - * Get the answer name list from an adapter status reply - * - * @return NetBIOSNameList - */ - public final NetBIOSNameList getAdapterStatusNameList() - { - - // Check if there are any answer names - - int cnt = getAnswerCount(); - if (cnt == 0) - return null; - - int pos = NB_DATA; - - // Skip the initial name - - int nameLen = (int) (m_nbbuf[pos++] & 0xFF); - pos += nameLen; - pos = DataPacker.wordAlign(pos); - pos += 8; - - // Get the count of data bytes and name count - - int dataCnt = DataPacker.getShort(m_nbbuf, pos); - if ( dataCnt < 16) - return null; - - pos += 2; - - int nameCnt = (int) (m_nbbuf[pos++] & 0xFF); - NetBIOSNameList nameList = new NetBIOSNameList(); - - while (nameCnt > 0 && dataCnt > 0) - { - - // Get the NetBIOS name/type - - NetBIOSName nbName = new NetBIOSName(m_nbbuf, pos); - pos += 16; - - // Get the name type flags, check if this is a unique or group name - - int typ = DataPacker.getShort(m_nbbuf, pos); - pos += 2; - - if ((typ & NAME_GROUP) != 0) - nbName.setGroup(true); - - // Add the name to the list - - nameList.addName(nbName); - - // Update the data count and name count - - dataCnt -= 18; - nameCnt--; - } - - // Return the name list - - return nameList; - } - - /** - * Return the NetBIOS buffer. - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_nbbuf; - } - - /** - * Get the flags from the received NetBIOS packet. - * - * @return int - */ - public final int getFlags() - { - int flags = DataPacker.getShort(m_nbbuf, NB_QDCOUNT) & MASK_NMFLAGS; - flags = flags >> SHIFT_FLAGS; - return flags; - } - - /** - * Return the NetBIOS header flags value. - * - * @return int - */ - public final int getHeaderFlags() - { - return m_nbbuf[1] & 0x00FF; - } - - /** - * Return the NetBIOS header data length value. - * - * @return int - */ - public final int getHeaderLength() - { - return DataPacker.getIntelShort(m_nbbuf, 2) & 0xFFFF; - } - - /** - * Return the NetBIOS header message type. - * - * @return int - */ - public final int getHeaderType() - { - return m_nbbuf[0] & 0x00FF; - } - - /** - * Return the received packet length. - * - * @return int - */ - public final int getLength() - { - return m_datalen; - } - - /** - * Return the name service count. - * - * @return int - */ - public final int getNameServiceCount() - { - return DataPacker.getShort(m_nbbuf, NB_NSCOUNT); - } - - /** - * Return the NetBIOS opcode. - * - * @return int - */ - public final int getOpcode() - { - int op = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_OPCODE; - op = op >> SHIFT_OPCODE; - return op; - } - - /** - * Return the NetBIOS packet type. - * - * @return int - */ - public final int getPacketType() - { - return (int) (m_nbbuf[0] & 0xFF); - } - - /** - * Return the question count. - * - * @return int - */ - public final int getQuestionCount() - { - return DataPacker.getShort(m_nbbuf, NB_QDCOUNT); - } - - /** - * Get the question name. - */ - public final String getQuestionName() - { - - // Pack the encoded name into the NetBIOS packet - - return NetBIOSSession.DecodeName(m_nbbuf, NB_DATA + 1); - } - - /** - * Get the question name length. - */ - public final int getQuestionNameLength() - { - - // Pack the encoded name into the NetBIOS packet - - return (int) m_nbbuf[NB_DATA] & 0xFF; - } - - /** - * Return the result code for the received packet. - * - * @return int - */ - public final int getResultCode() - { - int res = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_RCODE; - return res; - } - - /** - * Return the NetBIOS transaction id. - * - * @return int - */ - public final int getTransactionId() - { - return DataPacker.getShort(m_nbbuf, NB_TRANSID); - } - - /** - * Determine if the received packet is a repsonse packet. - * - * @return boolean - */ - public final boolean isResponse() - { - if ((getOpcode() & MASK_RESPONSE) != 0) - return true; - return false; - } - - /** - * Set the additional byte count. - * - * @param cnt int - */ - public final void setAdditionalCount(int cnt) - { - DataPacker.putShort((short) cnt, m_nbbuf, NB_ARCOUNT); - } - - /** - * Set the answer byte count. - * - * @param cnt int - */ - public final void setAnswerCount(int cnt) - { - DataPacker.putShort((short) cnt, m_nbbuf, NB_ANCOUNT); - } - - /** - * Set the answer name. - * - * @param name java.lang.String - * @param qtyp int - * @param qcls int - */ - public final int setAnswerName(String name, char ntyp, int qtyp, int qcls) - { - - // RFC encode the NetBIOS name string - - String encName = NetBIOSSession.ConvertName(name, ntyp); - byte[] nameByts = encName.getBytes(); - - // Pack the encoded name into the NetBIOS packet - - int pos = NB_DATA; - m_nbbuf[pos++] = (byte) NAME_LEN; - - for (int i = 0; i < 32; i++) - m_nbbuf[pos++] = nameByts[i]; - m_nbbuf[pos++] = 0x00; - - // Set the name type and class - - DataPacker.putShort((short) qtyp, m_nbbuf, pos); - pos += 2; - - DataPacker.putShort((short) qcls, m_nbbuf, pos); - pos += 2; - - // Set the packet length - - if (pos > m_datalen) - setLength(pos); - return pos; - } - - /** - * Set the flags. - * - * @param flg int - */ - public final void setFlags(int flg) - { - int val = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_NOFLAGS; - val += (flg << SHIFT_FLAGS); - DataPacker.putShort((short) val, m_nbbuf, NB_OPCODE); - } - - /** - * Set the NetBIOS packet header flags value. - * - * @param flg int - */ - public final void setHeaderFlags(int flg) - { - m_nbbuf[1] = (byte) (flg & 0x00FF); - } - - /** - * Set the NetBIOS packet data length in the packet header. - * - * @param len int - */ - public final void setHeaderLength(int len) - { - DataPacker.putIntelShort(len, m_nbbuf, 2); - } - - /** - * Set the NetBIOS packet type in the packet header. - * - * @param typ int - */ - public final void setHeaderType(int typ) - { - m_nbbuf[0] = (byte) (typ & 0x00FF); - } - - /** - * Set the IP address. - * - * @return int - * @param off int - * @param ipaddr byte[] - */ - public final int setIPAddress(int off, byte[] ipaddr) - { - - // Pack the IP address - - for (int i = 0; i < 4; i++) - m_nbbuf[off + i] = ipaddr[i]; - - // Set the packet length - - int pos = off + 4; - if (pos > m_datalen) - setLength(pos); - - // Return the new packet offset - - return pos; - } - - /** - * Set the packet data length. - * - * @param len int - */ - public final void setLength(int len) - { - m_datalen = len; - } - - /** - * Set the name registration flags. - * - * @return int - * @param off int - * @param flg int - */ - public final int setNameRegistrationFlags(int off, int flg) - { - - // Set the name registration flags - - DataPacker.putShort((short) 0x0006, m_nbbuf, off); - DataPacker.putShort((short) flg, m_nbbuf, off + 2); - - // Set the packet length - - int pos = off + 4; - if (pos > m_datalen) - setLength(pos); - - // Return the new packet offset - - return pos; - } - - /** - * Set the name service count. - * - * @param cnt int - */ - public final void setNameServiceCount(int cnt) - { - DataPacker.putShort((short) cnt, m_nbbuf, NB_NSCOUNT); - } - - /** - * Set the NetBIOS opcode. - * - * @param op int - */ - public final void setOpcode(int op) - { - int val = DataPacker.getShort(m_nbbuf, NB_OPCODE) & MASK_NOOPCODE; - val = val + (op << SHIFT_OPCODE); - DataPacker.putShort((short) val, m_nbbuf, NB_OPCODE); - } - - /** - * Set the question count. - * - * @param cnt int - */ - public final void setQuestionCount(int cnt) - { - DataPacker.putShort((short) cnt, m_nbbuf, NB_QDCOUNT); - } - - /** - * Set the question name. - * - * @param name NetBIOSName - * @param qtyp int - * @param qcls int - * @return int - */ - public final int setQuestionName(NetBIOSName name, int qtyp, int qcls) - { - - // Encode the NetBIOS name - - byte[] nameByts = name.encodeName(); - - // Pack the encoded name into the NetBIOS packet - - int pos = NB_DATA; - System.arraycopy(nameByts, 0, m_nbbuf, pos, nameByts.length); - pos += nameByts.length; - - // Set the name type and class - - DataPacker.putShort((short) qtyp, m_nbbuf, pos); - pos += 2; - - DataPacker.putShort((short) qcls, m_nbbuf, pos); - pos += 2; - - // Set the packet length - - if (pos > m_datalen) - setLength(pos); - return pos; - } - - /** - * Set the question name. - * - * @param name java.lang.String - * @param qtyp int - * @param qcls int - */ - public final int setQuestionName(String name, char ntyp, int qtyp, int qcls) - { - - // RFC encode the NetBIOS name string - - String encName = NetBIOSSession.ConvertName(name, ntyp); - byte[] nameByts = encName.getBytes(); - - // Pack the encoded name into the NetBIOS packet - - int pos = NB_DATA; - m_nbbuf[pos++] = (byte) NAME_LEN; - - for (int i = 0; i < 32; i++) - m_nbbuf[pos++] = nameByts[i]; - m_nbbuf[pos++] = 0x00; - - // Set the name type and class - - DataPacker.putShort((short) qtyp, m_nbbuf, pos); - pos += 2; - - DataPacker.putShort((short) qcls, m_nbbuf, pos); - pos += 2; - - // Set the packet length - - if (pos > m_datalen) - setLength(pos); - return pos; - } - - /** - * Pack the resource data into the packet. - * - * @return int - * @param off int - * @param flg int - * @param data byte[] - * @param len int - */ - public final int setResourceData(int off, int flg, byte[] data, int len) - { - - // Set the resource data type - - DataPacker.putShort((short) flg, m_nbbuf, off); - - // Pack the data - - int pos = off + 2; - for (int i = 0; i < len; i++) - m_nbbuf[pos++] = data[i]; - - // Set the packet length - - if (pos > m_datalen) - setLength(pos); - return pos; - } - - /** - * Set the resource data length in the NetBIOS packet. - * - * @return int - * @param off int - * @param len int - */ - public final int setResourceDataLength(int off, int len) - { - - // Set the resource data length - - DataPacker.putShort((short) len, m_nbbuf, off); - - // Set the packet length - - int pos = off + 2; - if (pos > m_datalen) - setLength(pos); - - // Return the new packet offset - - return pos; - } - - /** - * Set the resource record. - * - * @param pktoff Packet offset to pack the resource record. - * @param offset Offset to name. - * @param qtyp int - * @param qcls int - */ - public final int setResourceRecord(int pktoff, int rroff, int qtyp, int qcls) - { - - // Pack the resource record details - - DataPacker.putShort((short) (0xC000 + rroff), m_nbbuf, pktoff); - DataPacker.putShort((short) qtyp, m_nbbuf, pktoff + 2); - DataPacker.putShort((short) qcls, m_nbbuf, pktoff + 4); - - // Set the packet length - - int pos = pktoff + 6; - if (pos > m_datalen) - setLength(pos); - - // Return the new packet offset - - return pos; - } - - /** - * Set the transaction id. - * - * @param id int - */ - public final void setTransactionId(int id) - { - DataPacker.putShort((short) id, m_nbbuf, NB_TRANSID); - } - - /** - * Set the time to live for the packet. - * - * @return int - * @param off int - * @param ttl int - */ - public final int setTTL(int off, int ttl) - { - - // Set the time to live value for the packet - - DataPacker.putInt(ttl, m_nbbuf, off); - - // Set the packet length - - int pos = off + 4; - if (pos > m_datalen) - setLength(pos); - - // Return the new packet offset - - return pos; - } - - /** - * Return a packet type as a string - * - * @param typ int - * @return String - */ - public final static String getTypeAsString(int typ) - { - - // Return the NetBIOS packet type as a string - - String typStr = ""; - - switch (typ) - { - case RFCNetBIOSProtocol.SESSION_ACK: - typStr = "SessionAck"; - break; - case RFCNetBIOSProtocol.SESSION_KEEPALIVE: - typStr = "SessionKeepAlive"; - break; - case RFCNetBIOSProtocol.SESSION_MESSAGE: - typStr = "SessionMessage"; - break; - case RFCNetBIOSProtocol.SESSION_REJECT: - typStr = "SessionReject"; - break; - case RFCNetBIOSProtocol.SESSION_REQUEST: - typStr = "SessionRequest"; - break; - case RFCNetBIOSProtocol.SESSION_RETARGET: - typStr = "SessionRetarget"; - break; - default: - typStr = "Unknown 0x" + Integer.toHexString(typ); - break; - } - - // Return the packet type string - - return typStr; - } - - /** - * Build a name query response packet for the specified NetBIOS name - * - * @param name NetBIOSName - * @return int - */ - public final int buildNameQueryResponse(NetBIOSName name) - { - - // Fill in the header - - setOpcode(NetBIOSPacket.RESP_QUERY); - setFlags(NetBIOSPacket.FLG_RECURSDES + NetBIOSPacket.FLG_AUTHANSWER); - - setQuestionCount(0); - setAnswerCount(1); - setAdditionalCount(0); - setNameServiceCount(0); - - int pos = setAnswerName(name.getName(), name.getType(), 0x20, 0x01); - pos = setTTL(pos, 10000); - pos = setResourceDataLength(pos, name.numberOfAddresses() * 6); - - // Pack the IP address(es) for this name - - for (int i = 0; i < name.numberOfAddresses(); i++) - { - - // Get the current IP address - - byte[] ipaddr = name.getIPAddress(i); - - // Pack the NetBIOS flags and IP address - - DataPacker.putShort((short) 0x00, m_nbbuf, pos); - pos += 2; - - for (int j = 0; j < 4; j++) - m_nbbuf[pos++] = ipaddr[j]; - } - - // Set the packet length, and return the length - - setLength(pos); - return getLength(); - } - - /** - * Build an add name request packet for the specified NetBIOS name - * - * @param name NetBIOSName - * @param addrIdx int - * @param tranId int - * @return int - */ - public final int buildAddNameRequest(NetBIOSName name, int addrIdx, int tranId) - { - - // Initialize an add name NetBIOS packet - - setTransactionId(tranId); - setOpcode(NetBIOSPacket.NAME_REGISTER); - setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); - - setQuestionCount(1); - setAnswerCount(0); - setNameServiceCount(0); - setAdditionalCount(1); - - int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); - pos = setResourceRecord(pos, 12, 0x20, 0x01); - - if (name.getTimeToLive() == 0) - pos = setTTL(pos, NetBIOSName.DefaultTTL); - else - pos = setTTL(pos, name.getTimeToLive()); - - short flg = 0; - if (name.isGroupName()) - flg = (short) 0x8000; - pos = setNameRegistrationFlags(pos, flg); - pos = setIPAddress(pos, name.getIPAddress(addrIdx)); - - // Return the packet length - - setLength(pos); - return pos; - } - - /** - * Build a refresh name request packet for the specified NetBIOS name - * - * @param name NetBIOSName - * @param addrIdx int - * @param tranId int - * @return int - */ - public final int buildRefreshNameRequest(NetBIOSName name, int addrIdx, int tranId) - { - - // Initialize an add name NetBIOS packet - - setTransactionId(tranId); - setOpcode(NetBIOSPacket.REFRESH); - setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); - - setQuestionCount(1); - setAnswerCount(0); - setNameServiceCount(0); - setAdditionalCount(1); - - int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); - pos = setResourceRecord(pos, 12, 0x20, 0x01); - - if (name.getTimeToLive() == 0) - pos = setTTL(pos, NetBIOSName.DefaultTTL); - else - pos = setTTL(pos, name.getTimeToLive()); - - short flg = 0; - if (name.isGroupName()) - flg = (short) 0x8000; - pos = setNameRegistrationFlags(pos, flg); - pos = setIPAddress(pos, name.getIPAddress(addrIdx)); - - // Return the packet length - - setLength(pos); - return pos; - } - - /** - * Build a delete name request packet for the specified NetBIOS name - * - * @param name NetBIOSName - * @param addrIdx int - * @param tranId int - * @return int - */ - public final int buildDeleteNameRequest(NetBIOSName name, int addrIdx, int tranId) - { - - // Initialize a delete name NetBIOS packet - - setTransactionId(tranId); - setOpcode(NetBIOSPacket.NAME_RELEASE); - setFlags(NetBIOSPacket.FLG_BROADCAST + NetBIOSPacket.FLG_RECURSION); - - setQuestionCount(1); - setAnswerCount(0); - setNameServiceCount(0); - setAdditionalCount(1); - - int pos = setQuestionName(name.getName(), name.getType(), 0x20, 0x01); - pos = setResourceRecord(pos, 12, 0x20, 0x01); - pos = setTTL(pos, 30000); - - short flg = 0; - if (name.isGroupName()) - flg = (short) 0x8000; - pos = setNameRegistrationFlags(pos, flg); - pos = setIPAddress(pos, name.getIPAddress(addrIdx)); - - // Return the packet length - - setLength(pos); - return pos; - } - - /** - * Build a name quesy request packet for the specified NetBIOS name - * - * @param name NetBIOSName - * @param tranId int - * @return int - */ - public final int buildNameQueryRequest(NetBIOSName name, int tranId) - { - - // Initialize a name query NetBIOS packet - - setTransactionId(tranId); - setOpcode(NetBIOSPacket.NAME_QUERY); - setFlags(NetBIOSSession.hasWINSServer() ? 0 : NetBIOSPacket.FLG_BROADCAST); - setQuestionCount(1); - return setQuestionName(name, NetBIOSPacket.NAME_TYPE_NB, NetBIOSPacket.NAME_CLASS_IN); - } - - /** - * Build a session setup request packet - * - * @param fromName NetBIOSName - * @param toName NetBIOSName - * @return int - */ - public final int buildSessionSetupRequest(NetBIOSName fromName, NetBIOSName toName) - { - - // Initialize the session setup packet header - - m_nbbuf[0] = (byte) RFCNetBIOSProtocol.SESSION_REQUEST; - m_nbbuf[1] = (byte) 0; // flags - - // Set the remote NetBIOS name - - int pos = 4; - byte[] encToName = toName.encodeName(); - System.arraycopy(encToName, 0, m_nbbuf, pos, encToName.length); - pos += encToName.length; - - // Set the local NetBIOS name - - byte[] encFromName = fromName.encodeName(); - System.arraycopy(encFromName, 0, m_nbbuf, pos, encFromName.length); - pos += encFromName.length; - - // Set the packet length - - setLength(pos); - - // Set the length in the session request header - - DataPacker.putShort((short) (pos - RFCNetBIOSProtocol.HEADER_LEN), m_nbbuf, 2); - - // Return the packet length - - return pos; - } - - /** - * Build an adapter status response - * - * @param nameList NetBIOSNameList - * @param int nodeType - * @return int - */ - public final int buildAdapterStatusResponse(NetBIOSNameList nameList, int nodeType) { - - // Fill in the header - - setOpcode(NetBIOSPacket.RESP_QUERY); - setFlags(NetBIOSPacket.FLG_RECURSDES + NetBIOSPacket.FLG_AUTHANSWER); - - setQuestionCount(0); - setAnswerCount(1); - setAdditionalCount(0); - setNameServiceCount(0); - - // Pack the encoded adapter status name into the NetBIOS packet - - int pos = NB_DATA; - m_nbbuf [ pos++] = ( byte) NAME_LEN; - - pos = DataPacker.putString( AdapterStatusNBName, m_nbbuf, pos, true); - - // Set the name type and class - - DataPacker.putShort (( short) 0x21, m_nbbuf, pos); - pos += 2; - - DataPacker.putShort (( short) 0x01, m_nbbuf, pos); - pos += 2; - - pos = setTTL(pos, 10000); - pos = setResourceDataLength(pos, (nameList.numberOfNames() * 18) + 42); - - // Pack the names - - m_nbbuf[pos++] = (byte) nameList.numberOfNames(); - - for ( int i = 0; i < nameList.numberOfNames(); i++) { - - // Get the current name - - NetBIOSName nbName = nameList.getName( i); - - // Pack the NetBIOS name and flags - - System.arraycopy( nbName.getNetBIOSName(), 0, m_nbbuf, pos, NetBIOSName.NameLength); - pos += NetBIOSName.NameLength; - - int flags = nodeType + NAME_ACTIVE; - if ( nbName.isGroupName()) - flags += NAME_GROUP; - - DataPacker.putShort(( short) flags, m_nbbuf, pos); - pos += 2; - } - - // Zero out the statistics, MAC address area - - for ( int i = 0; i < 42; i++) - m_nbbuf[pos++] = (byte) 0; - - // Set the packet length, and return the length - - setLength(pos); - return getLength(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java b/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java deleted file mode 100644 index 2870f7e31a..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetBIOSSession.java +++ /dev/null @@ -1,1964 +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.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Vector; - -import org.alfresco.filesys.smb.NetworkSession; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; -import org.alfresco.filesys.util.StringList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NetBIOS session class. - */ -public final class NetBIOSSession implements NetworkSession -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.netbios"); - - // Constants - // - // Caller name template - - public static final int MaxCallerNameTemplateLength = 8; - public static final char SessionIdChar = '#'; - public static final char JVMIdChar = '@'; - public static final String ValidTemplateChars = "@#_"; - - // Default find name buffer size - - private static final int FindNameBufferSize = 2048; - - // Default socket timeout, in milliseconds - - private static int _defTimeout = RFCNetBIOSProtocol.TMO; - - // Remote socket to connect to, default is 139. - - private int m_remotePort; - - // Socket used to connect and read/write to remote host - - private Socket m_nbSocket; - - // Input and output data streams, from the socket network connection - - private DataInputStream m_nbIn; - private DataOutputStream m_nbOut; - - // Send/receive timeout, in milliseconds - - private int m_tmo = _defTimeout; - - // Local and remote name types - - private char m_locNameType = NetBIOSName.FileServer; - private char m_remNameType = NetBIOSName.FileServer; - - // Unique session identifier, used to generate a unique caller name when opening a new session - - private static int m_sessIdx = 0; - - // Unique JVM id, used to generate a unique caller name when multiple JVMs may be running on the - // same - // host - - private static int m_jvmIdx = 0; - - // Caller name template string. The template is used to create a unique caller name when opening - // a new session. - // The template is appended to the local host name, which may be truncated to allow room for the - // template to be - // appended and still be within the 16 character NetBIOS name limit. - // - // The caller name generation replaces '#' characters with a zero padded session index as a hex - // value and '@' - // characters with a zero padded JVM index. Multiple '#' and/or '@' characters can be specified - // to indicate the - // field width. Any other characters in the template are passed through to the final caller name - // string. - // - // The maximum template string length is 8 characters to allow for at least 8 characters from - // the host name. - - private static String m_callerTemplate = "_##"; - - // Truncated host name, caller name generation appends the caller template result to this string - - private static String m_localNamePart; - - // Transaction identifier, used for datagrams - - private static short m_tranIdx = 1; - - // RFC NetBIOS name service datagram socket - - private static DatagramSocket m_dgramSock = null; - - // Debug enable flag - - private static boolean m_debug = false; - - // Subnet mask, required for broadcast name lookup requests - - private static String m_subnetMask = null; - - // WINS server address - - private static InetAddress m_winsServer; - - // Name lookup types - - public static final int DNSOnly = 1; - public static final int WINSOnly = 2; - public static final int WINSAndDNS = 3; - - // Flag to control whether name lookups use WINS/NetBIOS lookup or DNS - - private static int m_lookupType = WINSAndDNS; - - // NetBIOS name lookup timeout value. - - private static int m_lookupTmo = 500; - - // Flag to control use of the '*SMBSERVER' name when connecting to a file server - - private static boolean m_useWildcardFileServer = true; - - /** - * NetBIOS session class constructor. Create a NetBIOS session with the default socket number - * and no current network connection. - */ - public NetBIOSSession() - { - m_remotePort = RFCNetBIOSProtocol.PORT; - m_nbSocket = null; - } - - /** - * NetBIOS session class constructor - * - * @param tmo Send/receive timeout value in milliseconds - */ - public NetBIOSSession(int tmo) - { - m_tmo = tmo; - m_remotePort = RFCNetBIOSProtocol.PORT; - m_nbSocket = null; - } - - /** - * NetBIOS session class constructor - * - * @param tmo Send/receive timeout value in milliseconds - * @param port Remote port to connect to - */ - public NetBIOSSession(int tmo, int port) - { - m_tmo = tmo; - m_remotePort = port; - m_nbSocket = null; - } - - /** - * Return the protocol name - * - * @return String - */ - public final String getProtocolName() - { - return "TCP/IP NetBIOS"; - } - - /** - * Determine if the session is connected to a remote host - * - * @return boolean - */ - public final boolean isConnected() - { - - // Check if the socket is valid - - if (m_nbSocket == null) - return false; - return true; - } - - /** - * Check if there is data available on this network session - * - * @return boolean - * @exception IOException - */ - public final boolean hasData() throws IOException - { - - // Check if the connection is active - - if (m_nbSocket == null || m_nbIn == null) - return false; - - // Check if there is data available - - return m_nbIn.available() > 0 ? true : false; - } - - /** - * Convert a host name string into RFC NetBIOS format. - * - * @param hostName Host name to be converted. - * @return Converted host name string. - */ - public static String ConvertName(String hostName) - { - return ConvertName(hostName, NetBIOSName.FileServer); - } - - /** - * Convert a host name string into RFC NetBIOS format. - * - * @param hostName Host name to be converted. - * @param nameType NetBIOS name type, added as the 16th byte of the name before conversion. - * @return Converted host name string. - */ - public static String ConvertName(String hostName, char nameType) - { - - // Build the name string with the name type, make sure that the host - // name is uppercase. - - StringBuffer hName = new StringBuffer(hostName.toUpperCase()); - - if (hName.length() > 15) - hName.setLength(15); - - // Space pad the name then add the NetBIOS name type - - while (hName.length() < 15) - hName.append(' '); - hName.append(nameType); - - // Convert the NetBIOS name string to the RFC NetBIOS name format - - String convstr = new String("ABCDEFGHIJKLMNOP"); - StringBuffer nameBuf = new StringBuffer(32); - - int idx = 0; - - while (idx < hName.length()) - { - - // Get the current character from the host name string - - char ch = hName.charAt(idx++); - - if (ch == ' ') - { - - // Append an encoded character - - nameBuf.append("CA"); - } - else - { - - // Append octet for the current character - - nameBuf.append(convstr.charAt((int) ch / 16)); - nameBuf.append(convstr.charAt((int) ch % 16)); - } - - } // end while - - // Return the encoded string - - return nameBuf.toString(); - } - - /** - * Convert an encoded NetBIOS name to a normal name string - * - * @param buf Buffer that contains the NetBIOS encoded name - * @param off Offset that the name starts within the buffer - * @return Normal NetBIOS name string - */ - public static String DecodeName(byte[] buf, int off) - { - - // Convert the RFC NetBIOS name string to a normal NetBIOS name string - - String convstr = new String("ABCDEFGHIJKLMNOP"); - StringBuffer nameBuf = new StringBuffer(16); - - int idx = 0; - char ch1, ch2; - - while (idx < 32) - { - - // Get the current encoded character pair from the encoded name string - - ch1 = (char) buf[off + idx]; - ch2 = (char) buf[off + idx + 1]; - - if (ch1 == 'C' && ch2 == 'A') - { - - // Append a character - - nameBuf.append(' '); - } - else - { - - // Convert back to a character code - - int val = convstr.indexOf(ch1) << 4; - val += convstr.indexOf(ch2); - - // Append the current character to the decoded name - - nameBuf.append((char) (val & 0xFF)); - } - - // Update the encoded string index - - idx += 2; - - } // end while - - // Return the decoded string - - return nameBuf.toString(); - } - - /** - * Convert an encoded NetBIOS name to a normal name string - * - * @param encnam RFC NetBIOS encoded name - * @return Normal NetBIOS name string - */ - - public static String DecodeName(String encnam) - { - - // Check if the encoded name string is valid, must be 32 characters - - if (encnam == null || encnam.length() != 32) - return ""; - - // Convert the RFC NetBIOS name string to a normal NetBIOS name string - - String convstr = new String("ABCDEFGHIJKLMNOP"); - StringBuffer nameBuf = new StringBuffer(16); - - int idx = 0; - char ch1, ch2; - - while (idx < 32) - { - - // Get the current encoded character pair from the encoded name string - - ch1 = encnam.charAt(idx); - ch2 = encnam.charAt(idx + 1); - - if (ch1 == 'C' && ch2 == 'A') - { - - // Append a character - - nameBuf.append(' '); - } - else - { - - // Convert back to a character code - - int val = convstr.indexOf(ch1) << 4; - val += convstr.indexOf(ch2); - - // Append the current character to the decoded name - - nameBuf.append((char) (val & 0xFF)); - } - - // Update the encoded string index - - idx += 2; - - } // end while - - // Return the decoded string - - return nameBuf.toString(); - } - - /** - * Convert a host name string into RFC NetBIOS format. - * - * @param hostName Host name to be converted. - * @param nameType NetBIOS name type, added as the 16th byte of the name before conversion. - * @param buf Buffer to write the encoded name into. - * @param off Offset within the buffer to start writing. - * @return Buffer position - */ - public static int EncodeName(String hostName, char nameType, byte[] buf, int off) - { - - // Build the name string with the name type, make sure that the host - // name is uppercase. - - StringBuffer hName = new StringBuffer(hostName.toUpperCase()); - - if (hName.length() > 15) - hName.setLength(15); - - // Space pad the name then add the NetBIOS name type - - while (hName.length() < 15) - hName.append(' '); - hName.append(nameType); - - // Convert the NetBIOS name string to the RFC NetBIOS name format - - String convstr = new String("ABCDEFGHIJKLMNOP"); - int idx = 0; - int bufpos = off; - - // Set the name length byte - - buf[bufpos++] = 0x20; - - // Copy the encoded NetBIOS name to the buffer - - while (idx < hName.length()) - { - - // Get the current character from the host name string - - char ch = hName.charAt(idx++); - - if (ch == ' ') - { - - // Append an encoded character - - buf[bufpos++] = (byte) 'C'; - buf[bufpos++] = (byte) 'A'; - } - else - { - - // Append octet for the current character - - buf[bufpos++] = (byte) convstr.charAt((int) ch / 16); - buf[bufpos++] = (byte) convstr.charAt((int) ch % 16); - } - - } // end while - - // Null terminate the string - - buf[bufpos++] = 0; - return bufpos; - } - - /** - * Find a NetBIOS name on the network - * - * @param nbname NetBIOS name to search for, not yet RFC encoded - * @param nbType Name type, appended as the 16th byte of the name - * @param tmo Timeout value for receiving incoming datagrams - * @return NetBIOS name details - * @exception java.io.IOException If an I/O error occurs - */ - public static NetBIOSName FindName(String nbName, char nbType, int tmo) throws java.io.IOException - { - - // Call the main FindName method - - return FindName(new NetBIOSName(nbName, nbType, false), tmo); - } - - /** - * Find a NetBIOS name on the network - * - * @param nbname NetBIOS name to search for - * @param tmo Timeout value for receiving incoming datagrams - * @return NetBIOS name details - * @exception java.io.IOException If an I/O error occurs - */ - public static NetBIOSName FindName(NetBIOSName nbName, int tmo) throws java.io.IOException - { - - // Get the local address details - - InetAddress locAddr = InetAddress.getLocalHost(); - - // Create a datagram socket - - if (m_dgramSock == null) - { - - // Create a datagram socket - - m_dgramSock = new DatagramSocket(); - } - - // Set the datagram socket timeout, in milliseconds - - m_dgramSock.setSoTimeout(tmo); - - // Create a name lookup NetBIOS packet - - NetBIOSPacket nbpkt = new NetBIOSPacket(); - nbpkt.buildNameQueryRequest(nbName, m_tranIdx++); - - // Get the local host numeric address - - String locIP = locAddr.getHostAddress(); - int dotIdx = locIP.indexOf('.'); - if (dotIdx == -1) - return null; - - // If a WINS server has been configured the request is sent directly to the WINS server, if - // not then a broadcast is done on the local subnet. - - InetAddress destAddr = null; - - if (hasWINSServer() == false) - { - - // Check if the subnet mask has been set, if not then generate a subnet mask - - if (getSubnetMask() == null) - GenerateSubnetMask(null); - - // Build a broadcast destination address - - destAddr = InetAddress.getByName(getSubnetMask()); - } - else - { - - // Use the WINS server address - - destAddr = getWINSServer(); - } - - // Build the name lookup request - - DatagramPacket dgram = new DatagramPacket(nbpkt.getBuffer(), nbpkt.getLength(), destAddr, - RFCNetBIOSProtocol.NAME_PORT); - - // Allocate a receive datagram packet - - byte[] rxbuf = new byte[FindNameBufferSize]; - DatagramPacket rxdgram = new DatagramPacket(rxbuf, rxbuf.length); - - // Create a NetBIOS packet using the receive buffer - - NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); - - // DEBUG - - if (m_debug) - nbpkt.DumpPacket(false); - - // Send the find name datagram - - m_dgramSock.send(dgram); - - // Receive a reply datagram - - boolean rxOK = false; - - do - { - - // Receive a datagram packet - - m_dgramSock.receive(rxdgram); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - { - logger.debug("NetBIOS: Rx Datagram"); - rxpkt.DumpPacket(false); - } - - // Check if this is a valid response datagram - - if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) - rxOK = true; - - } while (!rxOK); - - // Get the list of names from the response, should only be one name - - NetBIOSNameList nameList = rxpkt.getAnswerNameList(); - if (nameList != null && nameList.numberOfNames() > 0) - return nameList.getName(0); - return null; - } - - /** - * Build a list of nodes that own the specified NetBIOS name. - * - * @param nbname NetBIOS name to search for, not yet RFC encoded - * @param nbType Name type, appended as the 16th byte of the name - * @param tmo Timeout value for receiving incoming datagrams - * @return List of node name Strings - * @exception java.io.IOException If an I/O error occurs - */ - public static StringList FindNameList(String nbName, char nbType, int tmo) throws IOException - { - - // Get the local address details - - InetAddress locAddr = InetAddress.getLocalHost(); - - // Create a datagram socket - - if (m_dgramSock == null) - { - - // Create a datagram socket - - m_dgramSock = new DatagramSocket(); - } - - // Set the datagram socket timeout, in milliseconds - - m_dgramSock.setSoTimeout(tmo); - - // Create a name lookup NetBIOS packet - - NetBIOSPacket nbpkt = new NetBIOSPacket(); - - nbpkt.setTransactionId(m_tranIdx++); - nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); - nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); - nbpkt.setQuestionCount(1); - nbpkt.setQuestionName(nbName, nbType, NetBIOSPacket.NAME_TYPE_NB, NetBIOSPacket.NAME_CLASS_IN); - - // Get the local host numeric address - - String locIP = locAddr.getHostAddress(); - int dotIdx = locIP.indexOf('.'); - if (dotIdx == -1) - return null; - - // If a WINS server has been configured the request is sent directly to the WINS server, if - // not then a broadcast is done on the local subnet. - - InetAddress destAddr = null; - - if (hasWINSServer() == false) - { - - // Check if the subnet mask has been set, if not then generate a subnet mask - - if (getSubnetMask() == null) - GenerateSubnetMask(null); - - // Build a broadcast destination address - - destAddr = InetAddress.getByName(getSubnetMask()); - } - else - { - - // Use the WINS server address - - destAddr = getWINSServer(); - } - - // Build the request datagram - - DatagramPacket dgram = new DatagramPacket(nbpkt.getBuffer(), nbpkt.getLength(), destAddr, - RFCNetBIOSProtocol.NAME_PORT); - - // Allocate a receive datagram packet - - byte[] rxbuf = new byte[FindNameBufferSize]; - DatagramPacket rxdgram = new DatagramPacket(rxbuf, rxbuf.length); - - // Create a NetBIOS packet using the receive buffer - - NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); - - // DEBUG - - if (m_debug) - nbpkt.DumpPacket(false); - - // Create a vector to store the remote host addresses - - Vector addrList = new Vector(); - - // Calculate the end time, to stop receiving datagrams - - long endTime = System.currentTimeMillis() + tmo; - - // Send the find name datagram - - m_dgramSock.send(dgram); - - // Receive reply datagrams - - do - { - - // Receive a datagram packet - - try - { - m_dgramSock.receive(rxdgram); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - { - logger.debug("NetBIOS: Rx Datagram"); - rxpkt.DumpPacket(false); - } - - // Check if this is a valid response datagram - - if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) - { - - // Get the address of the remote host for this datagram and add it to the list - // of responders - - addrList.add(rxdgram.getAddress()); - } - } - catch (java.io.IOException ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - logger.debug(ex.toString()); - } - - } while (System.currentTimeMillis() < endTime); - - // Check if we received any replies - - if (addrList.size() == 0) - return null; - - // Create a node name list - - StringList nameList = new StringList(); - - // Convert the reply addresses to node names - - for (int i = 0; i < addrList.size(); i++) - { - - // Get the current address from the list - - InetAddress addr = addrList.elementAt(i); - - // Convert the address to a node name string - - String name = NetBIOSName(addr.getHostName()); - - // Check if the name is already in the name list - - if (!nameList.containsString(name)) - nameList.addString(name); - } - - // Return the node name list - - return nameList; - } - - /** - * Get the NetBIOS name list for the specified IP address - * - * @param ipAddr String - * @return NetBIOSNameList - */ - public static NetBIOSNameList FindNamesForAddress(String ipAddr) throws UnknownHostException, SocketException - { - return FindNamesForAddress( ipAddr, 1); - } - - /** - * Get the NetBIOS name list for the specified IP address - * - * @param ipAddr String - * @param retryCnt int - * @return NetBIOSNameList - */ - public static NetBIOSNameList FindNamesForAddress(String ipAddr, int retryCnt) - throws UnknownHostException, SocketException - { - - // Create a datagram socket - - if (m_dgramSock == null) - { - - // Create a datagram socket - - m_dgramSock = new DatagramSocket(); - } - - // Set the datagram socket timeout, in milliseconds - - m_dgramSock.setSoTimeout(5000); - - // Create a name lookup NetBIOS packet - - NetBIOSPacket nbpkt = new NetBIOSPacket(); - - nbpkt.setTransactionId(m_tranIdx++); - nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); - nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); - nbpkt.setQuestionCount(1); - nbpkt.setQuestionName("*\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NetBIOSName.WorkStation, NetBIOSPacket.NAME_TYPE_NBSTAT, - NetBIOSPacket.NAME_CLASS_IN); - - // Send the request to the specified address - - InetAddress destAddr = InetAddress.getByName(ipAddr); - DatagramPacket dgram = new DatagramPacket(nbpkt.getBuffer(), nbpkt.getLength(), destAddr, - RFCNetBIOSProtocol.NAME_PORT); - - // Allocate a receive datagram packet - - byte[] rxbuf = new byte[FindNameBufferSize]; - DatagramPacket rxdgram = new DatagramPacket(rxbuf, rxbuf.length); - - // Create a NetBIOS packet using the receive buffer - - NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - nbpkt.DumpPacket(false); - - // Create a vector to store the remote hosts NetBIOS names - - NetBIOSNameList nameList = null; - - try - { - // Loop until we get a valid reply or the retry count is zero - - while ( retryCnt-- > 0 && nameList == null) - { - // Send the name query datagram - - m_dgramSock.send(dgram); - - // Receive a datagram packet - - m_dgramSock.receive(rxdgram); - rxpkt.setLength( rxdgram.getLength()); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - { - logger.debug("NetBIOS: Rx Datagram"); - rxpkt.DumpPacket(false); - } - - // Check if this is a valid response datagram - - if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY && rxpkt.getAnswerCount() >= 1) - { - - // Get the received name list - - nameList = rxpkt.getAdapterStatusNameList(); - - // If the name list is valid update the names with the original address that was connected to - - if( nameList != null) - { - for ( int i = 0; i < nameList.numberOfNames(); i++) - { - NetBIOSName nbName = nameList.getName(i); - nbName.addIPAddress(destAddr.getAddress()); - } - } - } - } - } - catch (java.io.IOException ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - logger.debug(ex.toString()); - - // Unknown host - - throw new UnknownHostException(ipAddr); - } - - // Return the NetBIOS name list - - return nameList; - } - - /** - * Determine the subnet mask from the local hosts TCP/IP address - * - * @param addr TCP/IP address to set the subnet mask for, in 'nnn.nnn.nnn.nnn' format. - */ - public static String GenerateSubnetMask(String addr) throws java.net.UnknownHostException - { - - // Set the TCP/IP address string - - String localIP = addr; - - // Get the local TCP/IP address, if a null string has been specified - - 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 subnet mask to use - - if (ipVal <= 127) - { - - // Class A address - - m_subnetMask = "" + 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_subnetMask = 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_subnetMask = localIP.substring(0, dotPos - 1) + ".255"; - } - } - - // Check if the subnet mask has been set, if not then use a general - // broadcast mask - - if (m_subnetMask == null) - { - - // Invalid TCP/IP address string format, use a general broadcast mask - // for now. - - m_subnetMask = "255.255.255.255"; - } - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Set subnet mask to " + m_subnetMask); - - // Return the subnet mask string - - return m_subnetMask; - } - - /** - * Get the WINS/NetBIOS name lookup timeout, in milliseconds. - * - * @return int - */ - public static int getLookupTimeout() - { - return m_lookupTmo; - } - - /** - * Return the name lookup type that is used when setting up new sessions, valid values are - * DNSOnly, WINSOnly, WINSAndDNS. DNSOnly is the default type. - * - * @return int - */ - public static int getLookupType() - { - return m_lookupType; - } - - /** - * Return the subnet mask string - * - * @return Subnet mask string, in 'nnn.nnn.nnn.nnn' format - */ - public static String getSubnetMask() - { - return m_subnetMask; - } - - /** - * Determine if the WINS server address is configured - * - * @return boolean - */ - public final static boolean hasWINSServer() - { - return m_winsServer != null ? true : false; - } - - /** - * Return the WINS server address - * - * @return InetAddress - */ - public final static InetAddress getWINSServer() - { - return m_winsServer; - } - - /** - * Determine if SMB session debugging is enabled - * - * @return true if debugging is enabled, else false. - */ - public static boolean isDebug() - { - return m_debug; - } - - /** - * Return the next session index - * - * @return int - */ - private final static synchronized int getSessionId() - { - return m_sessIdx++; - } - - /** - * Return the JVM unique id, used when generating caller names - * - * @return int - */ - public final static int getJVMIndex() - { - return m_jvmIdx; - } - - /** - * Convert the TCP/IP host name to a NetBIOS name string. - * - * @return java.lang.String - * @param hostName java.lang.String - */ - public static String NetBIOSName(String hostName) - { - - // Check if the host name contains a domain name - - String nbName = new String(hostName.toUpperCase()); - int pos = nbName.indexOf("."); - - if (pos != -1) - { - - // Strip the domain name for the NetBIOS name - - nbName = nbName.substring(0, pos); - } - - // Return the NetBIOS name string - - return nbName; - } - - /** - * Enable/disable NetBIOS session debugging - * - * @param dbg true to enable debugging, else false - */ - public static void setDebug(boolean dbg) - { - m_debug = dbg; - } - - /** - * Set the WINS/NetBIOS name lookup timeout value, in milliseconds. - * - * @param tmo int - */ - public static void setLookupTimeout(int tmo) - { - if (tmo >= 250) - m_lookupTmo = tmo; - } - - /** - * Set the name lookup type(s) to be used when opening new sessions, valid values are DNSOnly, - * WINSOnly, WINSAndDNS. DNSOnly is the default type. - * - * @param typ int - */ - public static void setLookupType(int typ) - { - if (typ >= DNSOnly && typ <= WINSAndDNS) - m_lookupType = typ; - } - - /** - * Set the subnet mask string - * - * @param subnet Subnet mask string, in 'nnn.nnn.nnn.nnn' format - */ - public static void setSubnetMask(String subnet) - { - m_subnetMask = subnet; - } - - /** - * Set the WINS server address - * - * @param addr InetAddress - */ - public final static void setWINSServer(InetAddress addr) - { - m_winsServer = addr; - } - - /** - * Get the NetBIOS adapter status for the specified node. - * - * @return java.util.Vector - * @param nodeName java.lang.String - */ - private static Vector AdapterStatus(String nodeName) throws java.io.IOException - { - - // Create the socket - - DatagramSocket nameSock = new DatagramSocket(); - - // Enable the timeout on the socket - - nameSock.setSoTimeout(2000); - - // Create an adapter status NetBIOS packet - - NetBIOSPacket nbpkt = new NetBIOSPacket(); - - // nbpkt.setTransactionId( m_tranIdx++); - nbpkt.setTransactionId(9999); - nbpkt.setOpcode(NetBIOSPacket.NAME_QUERY); - nbpkt.setFlags(NetBIOSPacket.FLG_BROADCAST); - nbpkt.setQuestionCount(1); - nbpkt.setQuestionName(nodeName, NetBIOSName.WorkStation, NetBIOSPacket.NAME_TYPE_NBSTAT, - NetBIOSPacket.NAME_CLASS_IN); - - // Build a broadcast destination address - - InetAddress destAddr = InetAddress.getByName(nodeName); - DatagramPacket dgram = new DatagramPacket(nbpkt.getBuffer(), nbpkt.getLength(), destAddr, - RFCNetBIOSProtocol.NAME_PORT); - - // Allocate a receive datagram packet - - byte[] rxbuf = new byte[512]; - DatagramPacket rxdgram = new DatagramPacket(rxbuf, rxbuf.length); - - // Create a NetBIOS packet using the receive buffer - - NetBIOSPacket rxpkt = new NetBIOSPacket(rxbuf); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - nbpkt.DumpPacket(false); - - // Send the find name datagram - - nameSock.send(dgram); - - // Receive a reply datagram - - boolean rxOK = false; - - do - { - - // Receive a datagram packet - - nameSock.receive(rxdgram); - - // DEBUG - - if (logger.isDebugEnabled() && m_debug) - { - logger.debug("NetBIOS: Rx Datagram"); - rxpkt.DumpPacket(false); - } - - // Check if this is a valid response datagram - - if (rxpkt.isResponse() && rxpkt.getOpcode() == NetBIOSPacket.RESP_QUERY) - rxOK = true; - - } while (!rxOK); - - // Return the remote host address - - return null; - } - - /** - * Connect to a remote host. - * - * @param remHost Remote host node name/NetBIOS name. - * @param locName Local name/NetBIOS name. - * @param remAddr Optional remote address, if null then lookup will be done to convert name to - * address - * @exception java.io.IOException I/O error occurred. - * @exception java.net.UnknownHostException Remote host is unknown. - */ - public void Open(String remHost, String locName, String remAddr) throws java.io.IOException, - java.net.UnknownHostException - { - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Call " + remHost); - - // Convert the remote host name to an address - - boolean dnsLookup = false; - InetAddress addr = null; - - // Set the remote address is specified - - if (remAddr != null) - { - - // Use the specified remote address - - addr = InetAddress.getByName(remAddr); - } - else - { - - // Try a WINS/NetBIOS type name lookup, if enabled - - if (getLookupType() != DNSOnly) - { - try - { - NetBIOSName netName = FindName(remHost, NetBIOSName.FileServer, 500); - if (netName != null && netName.numberOfAddresses() > 0) - addr = InetAddress.getByName(netName.getIPAddressString(0)); - } - catch (Exception ex) - { - } - } - - // Try a DNS type name lookup, if enabled - - if (addr == null && getLookupType() != WINSOnly) - { - addr = InetAddress.getByName(remHost); - dnsLookup = true; - } - } - - // Check if we translated the remote host name to an address - - if (addr == null) - throw new java.net.UnknownHostException(remHost); - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Remote node hase address " + addr.getHostAddress() + " (" - + (dnsLookup ? "DNS" : "WINS") + ")"); - - // Determine the remote name to call - - String remoteName = null; - - if (getRemoteNameType() == NetBIOSName.FileServer && useWildcardFileServerName() == true) - remoteName = "*SMBSERVER"; - else - remoteName = remHost; - - // Open a session to the remote server - - int resp = openSession(remoteName, addr); - - // Check the server response - - if (resp == RFCNetBIOSProtocol.SESSION_ACK) - return; - else if (resp == RFCNetBIOSProtocol.SESSION_REJECT) - { - - // Try the connection again with the remote host name - - if (remoteName.equals(remHost) == false) - resp = openSession(remHost, addr); - - // Check if we got a valid response this time - - if (resp == RFCNetBIOSProtocol.SESSION_ACK) - return; - - // Server rejected the connection - - throw new java.io.IOException("NetBIOS session reject"); - } - else if (resp == RFCNetBIOSProtocol.SESSION_RETARGET) - throw new java.io.IOException("NetBIOS ReTarget"); - - // Invalid session response, hangup the session - - Close(); - throw new java.io.IOException("Invalid NetBIOS response, 0x" + Integer.toHexString(resp)); - } - - /** - * Open a NetBIOS session to a remote server - * - * @param remoteName String - * @param addr InetAddress - * @return int - * @exception IOException - */ - private final int openSession(String remoteName, InetAddress addr) throws IOException - { - - // Create the socket - - m_nbSocket = new Socket(addr, m_remotePort); - - // Enable the timeout on the socket, and disable Nagle algorithm - - m_nbSocket.setSoTimeout(m_tmo); - m_nbSocket.setTcpNoDelay(true); - - // Attach input/output streams to the socket - - m_nbIn = new DataInputStream(m_nbSocket.getInputStream()); - m_nbOut = new DataOutputStream(m_nbSocket.getOutputStream()); - - // Allocate a buffer to receive the session response - - byte[] inpkt = new byte[RFCNetBIOSProtocol.SESSRESP_LEN]; - - // Create the from/to NetBIOS names - - NetBIOSName fromName = createUniqueCallerName(); - NetBIOSName toName = new NetBIOSName(remoteName, getRemoteNameType(), false); - - // Debug - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Call from " + fromName + " to " + toName); - - // Build the session request packet - - NetBIOSPacket nbPkt = new NetBIOSPacket(); - nbPkt.buildSessionSetupRequest(fromName, toName); - - // Send the session request packet - - m_nbOut.write(nbPkt.getBuffer(), 0, nbPkt.getLength()); - - // Allocate a buffer for the session request response, and read the response - - int resp = -1; - - if (m_nbIn.read(inpkt, 0, RFCNetBIOSProtocol.SESSRESP_LEN) >= RFCNetBIOSProtocol.HEADER_LEN) - { - - // Check the session request response - - resp = (int) (inpkt[0] & 0xFF); - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Rx " + NetBIOSPacket.getTypeAsString(resp)); - } - - // Check for a positive response - - if (resp != RFCNetBIOSProtocol.SESSION_ACK) - { - - // Close the socket and streams - - m_nbIn.close(); - m_nbIn = null; - - m_nbOut.close(); - m_nbOut = null; - - m_nbSocket.close(); - m_nbSocket = null; - } - - // Return the response code - - return resp; - } - - /** - * Return the local NetBIOS name type. - * - * @return char - */ - public char getLocalNameType() - { - return m_locNameType; - } - - /** - * Return the remote NetBIOS name type. - * - * @return char - */ - public char getRemoteNameType() - { - return m_remNameType; - } - - /** - * Get the session timeout value - * - * @return NetBIOS session timeout value - */ - public int getTimeout() - { - return m_tmo; - } - - /** - * Close the NetBIOS session. - * - * @exception IOException If an I/O error occurs - */ - public void Close() throws IOException - { - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: HangUp"); - - // Close the session if active - - if (m_nbSocket != null) - { - m_nbSocket.close(); - m_nbSocket = null; - } - } - - /** - * Receive a data packet from the remote host. - * - * @param buf Byte buffer to receive the data into. - * @param tmo Receive timeout in milliseconds, or zero for no timeout - * @return Length of the received data. - * @exception java.io.IOException I/O error occurred. - */ - public int Receive(byte[] buf, int tmo) throws java.io.IOException - { - - // Set the read timeout - - if (tmo != m_tmo) - { - m_nbSocket.setSoTimeout(tmo); - m_tmo = tmo; - } - - // Read a data packet, dump any session keep alive packets - - int pkttyp; - int rdlen; - - do - { - - // Read a packet header - - rdlen = m_nbIn.read(buf, 0, RFCNetBIOSProtocol.HEADER_LEN); - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Read " + rdlen + " bytes"); - - // Check if a header was received - - if (rdlen < RFCNetBIOSProtocol.HEADER_LEN) - throw new java.io.IOException("NetBIOS Short Read"); - - // Get the packet type from the header - - pkttyp = (int) (buf[0] & 0xFF); - - } while (pkttyp == RFCNetBIOSProtocol.SESSION_KEEPALIVE); - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Rx Pkt Type = " + pkttyp + ", " + Integer.toHexString(pkttyp)); - - // Check that the packet is a session data packet - - if (pkttyp != RFCNetBIOSProtocol.SESSION_MESSAGE) - throw new java.io.IOException("NetBIOS Unknown Packet Type, " + pkttyp); - - // Extract the data size from the packet header - - int pktlen = (int) DataPacker.getShort(buf, 2); - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Rx Data Len = " + pktlen); - - // Check if the user buffer is long enough to contain the data - - if (buf.length < (pktlen + RFCNetBIOSProtocol.HEADER_LEN)) - { - - // Debug mode - - logger.debug("NetBIOS: Rx Pkt Type = " + pkttyp + ", " + Integer.toHexString(pkttyp)); - logger.debug("NetBIOS: Rx Buf Too Small pkt=" + pktlen + " buflen=" + buf.length); - HexDump.Dump(buf, 16, 0); - - throw new java.io.IOException("NetBIOS Recv Buffer Too Small (pkt=" + pktlen + "/buf=" + buf.length + ")"); - } - - // Read the data part of the packet into the users buffer, this may take - // several reads - - int totlen = 0; - int offset = RFCNetBIOSProtocol.HEADER_LEN; - - while (pktlen > 0) - { - - // Read the data - - rdlen = m_nbIn.read(buf, offset, pktlen); - - // Update the received length and remaining data length - - totlen += rdlen; - pktlen -= rdlen; - - // Update the user buffer offset as more reads will be required - // to complete the data read - - offset += rdlen; - - } // end while reading data - - // Return the received data length, not including the NetBIOS header - - return totlen; - } - - /** - * Send a data packet to the remote host. - * - * @param data Byte array containing the data to be sent. - * @param siz Length of the data to send. - * @return true if the data was sent successfully, else false. - * @exception java.io.IOException I/O error occurred. - */ - public boolean Send(byte[] data, int siz) throws java.io.IOException - { - - // Check that the session is valid - - if (m_nbSocket == null) - return false; - - // Debug mode - - if (logger.isDebugEnabled() && m_debug) - logger.debug("NetBIOS: Tx " + siz + " bytes"); - - // Fill in the NetBIOS message header, this is already allocated as - // part of the users buffer. - - data[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; - data[1] = (byte) 0; - - DataPacker.putShort((short) siz, data, 2); - - // Output the data packet - - int bufSiz = siz + RFCNetBIOSProtocol.HEADER_LEN; - m_nbOut.write(data, 0, bufSiz); - return true; - } - - /** - * Set the local NetBIOS name type for this session. - * - * @param nameType int - */ - public void setLocalNameType(char nameType) - { - m_locNameType = nameType; - } - - /** - * Set the remote NetBIOS name type. - * - * @param param char - */ - public void setRemoteNameType(char nameType) - { - m_remNameType = nameType; - } - - /** - * Set the session timeout value - * - * @param tmo Session timeout value - */ - public void setTimeout(int tmo) - { - m_tmo = tmo; - } - - /** - * Set the caller session name template string that is appended to the local host name to create - * a unique caller name. - * - * @param template String - * @exception NameTemplateExcepition - */ - public final static void setCallerNameTemplate(String template) throws NameTemplateException - { - - // Check if the template string is valid, is not too long - - if (template == null || template.length() == 0 || template.length() > MaxCallerNameTemplateLength) - throw new NameTemplateException("Invalid template string, " + template); - - // Template must contain at least one session id template character - - if (template.indexOf(SessionIdChar) == -1) - throw new NameTemplateException("No session id character in template"); - - // Check if the template contains any invalid characters - - for (int i = 0; i < template.length(); i++) - { - if (ValidTemplateChars.indexOf(template.charAt(i)) == -1) - throw new NameTemplateException("Invalid character in template, '" + template.charAt(i) + "'"); - } - - // Set the caller name template string - - m_callerTemplate = template; - - // Clear the local name part string so that it will be regenerated to match the new template - // string - - m_localNamePart = null; - } - - /** - * Set the JVM index, used to generate unique caller names when multiple JVMs are run on the - * same host. - * - * @param jvmIdx int - */ - public final static void setJVMIndex(int jvmIdx) - { - if (jvmIdx >= 0) - m_jvmIdx = jvmIdx; - } - - /** - * Create a unique caller name for a new NetBIOS session. The unique name contains the local - * host name plus an index that is unique for this JVM, plus an optional JVM index. - * - * @return NetBIOSName - */ - private final NetBIOSName createUniqueCallerName() - { - - // Check if the local name part has been set - - if (m_localNamePart == null) - { - - String localName = null; - - try - { - localName = InetAddress.getLocalHost().getHostName(); - } - catch (Exception ex) - { - } - - // Check if the name contains a domain - - int pos = localName.indexOf("."); - - if (pos != -1) - localName = localName.substring(0, pos); - - // Truncate the name if the host name plus the template is longer than 15 characters. - - int nameLen = 16 - m_callerTemplate.length(); - - if (localName.length() > nameLen) - localName = localName.substring(0, nameLen - 1); - - // Set the local host name part - - m_localNamePart = localName.toUpperCase(); - } - - // Get a unique session id and the unique JVM id - - int sessId = getSessionId(); - int jvmId = getJVMIndex(); - - // Build the NetBIOS name string - - StringBuffer nameBuf = new StringBuffer(16); - - nameBuf.append(m_localNamePart); - - // Process the caller name template string - - int idx = 0; - int len = -1; - - while (idx < m_callerTemplate.length()) - { - - // Get the current template character - - char ch = m_callerTemplate.charAt(idx++); - - switch (ch) - { - - // Session id - - case SessionIdChar: - len = findRepeatLength(m_callerTemplate, idx, SessionIdChar); - appendZeroPaddedHexValue(sessId, len, nameBuf); - idx += len - 1; - break; - - // JVM id - - case JVMIdChar: - len = findRepeatLength(m_callerTemplate, idx, JVMIdChar); - appendZeroPaddedHexValue(jvmId, len, nameBuf); - idx += len - 1; - break; - - // Pass any other characters through to the name string - - default: - nameBuf.append(ch); - break; - } - } - - // Create the NetBIOS name object - - return new NetBIOSName(nameBuf.toString(), getLocalNameType(), false); - } - - /** - * Find the length of the character block in the specified string - * - * @param str String - * @param pos int - * @param ch char - * @return int - */ - private final int findRepeatLength(String str, int pos, char ch) - { - int len = 1; - - while (pos < str.length() && str.charAt(pos++) == ch) - len++; - return len; - } - - /** - * Append a zero filled hex string to the specified string - * - * @param val int - * @param len int - * @param str StringBuffer - */ - private final void appendZeroPaddedHexValue(int val, int len, StringBuffer str) - { - - // Create the hex string of the value - - String hex = Integer.toHexString(val); - - // Pad the final string as required - - for (int i = 0; i < len - hex.length(); i++) - str.append("0"); - str.append(hex); - } - - /** - * Return the default socket timeout value - * - * @return int - */ - public static final int getDefaultTimeout() - { - return _defTimeout; - } - - /** - * Set the default socket timeout for new sessions - * - * @param tmo int - */ - public static final void setDefaultTimeout(int tmo) - { - _defTimeout = tmo; - } - - /** - * Return the use wildcard file server name flag status. If true the target name when conencting - * to a remote file server will be '*SMBSERVER', if false the remote name will be used. - * - * @return boolean - */ - public static final boolean useWildcardFileServerName() - { - return m_useWildcardFileServer; - } - - /** - * Set the use wildcard file server name flag. If true the target name when conencting to a - * remote file server will be '*SMBSERVER', if false the remote name will be used. - * - * @param useWildcard boolean - */ - public static final void setWildcardFileServerName(boolean useWildcard) - { - m_useWildcardFileServer = useWildcard; - } - - /** - * Finalize the NetBIOS session object - */ - protected void finalize() - { - - // Close the socket - - if (m_nbSocket != null) - { - try - { - m_nbSocket.close(); - } - catch (java.io.IOException ex) - { - } - m_nbSocket = null; - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/NetworkSettings.java b/source/java/org/alfresco/filesys/netbios/NetworkSettings.java deleted file mode 100644 index 11f5ad5ce7..0000000000 --- a/source/java/org/alfresco/filesys/netbios/NetworkSettings.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/RFCNetBIOSProtocol.java b/source/java/org/alfresco/filesys/netbios/RFCNetBIOSProtocol.java deleted file mode 100644 index 4f15846c75..0000000000 --- a/source/java/org/alfresco/filesys/netbios/RFCNetBIOSProtocol.java +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/AddNameListener.java b/source/java/org/alfresco/filesys/netbios/server/AddNameListener.java deleted file mode 100644 index 8c25c70152..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/AddNameListener.java +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameEvent.java b/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameEvent.java deleted file mode 100644 index 0711f04495..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameEvent.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameServer.java b/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameServer.java deleted file mode 100644 index fb0b46b0d2..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/NetBIOSNameServer.java +++ /dev/null @@ -1,2054 +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.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetBIOSNameList; -import org.alfresco.filesys.netbios.NetBIOSPacket; -import org.alfresco.filesys.netbios.NetworkSettings; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.ServerListener; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NetBIOS name server class. - */ -public class NetBIOSNameServer extends NetworkServer implements Runnable -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.netbios"); - - // Various NetBIOS packet sizes - - public static final int AddNameSize = 256; - public static final int DeleteNameSize = 256; - public static final int RefreshNameSize = 256; - - // Add name thread broadcast interval and retry count - - private static final int AddNameInterval = 2000; // ms between transmits - private static final int AddNameRetries = 5; // number of broadcasts - - private static final int AddNameWINSInterval = 250; // ms between requests when using WINS - - // Delete name interval and retry count - - private static final int DeleteNameInterval = 200; // ms between transmits - private static final int DeleteNameRetries = 1; // number of broadcasts - - // Refresh name retry count - - public static final int RefreshNameRetries = 2; // number of broadcasts - - // NetBIOS flags - - public static final int GroupName = 0x8000; - - // Default time to live value for names registered by this server, in seconds - - public static final int DefaultTTL = 10800; // 3 hours - - // Name refresh thread wakeup interval - - public static final long NameRefreshWakeupInterval = 180000L; // 3 minutes - - // Name transaction id - - private static int m_tranId; - - // NetBIOS name service datagram socket - - private DatagramSocket m_socket; - - // Shutdown flag - - private boolean m_shutdown; - - // Local address to bind the name server to - - private InetAddress m_bindAddress; - - // Broadcast address, if not using WINS - - private InetAddress m_bcastAddr; - - // Port/socket to bind to - - private int m_port = RFCNetBIOSProtocol.NAME_PORT; - - // WINS server addresses - - private InetAddress m_winsPrimary; - private InetAddress m_winsSecondary; - - // Local add name listener list - - private Vector m_addListeners; - - // Local name query listener list - - private Vector m_queryListeners; - - // Remote name add listener list - - private Vector m_remoteListeners; - - // Local NetBIOS name table - - private Vector m_localNames; - - // Remote NetBIOS name table - - private Hashtable m_remoteNames; - - // List of active add name requests - - private Vector m_reqList; - - // NetBIOS request handler and name refresh threads - - private NetBIOSRequestHandler m_reqHandler; - private NetBIOSNameRefresh m_refreshThread; - - // Server thread - - private Thread m_srvThread; - - // NetBIOS request handler thread inner class - - class NetBIOSRequestHandler extends Thread - { - - // Shutdown request flag - - private boolean m_hshutdown = false; - - /** - * Default constructor - */ - public NetBIOSRequestHandler() - { - setDaemon(true); - setName("NetBIOSRequest"); - } - - /** - * Shutdown the request handler thread - */ - public final void shutdownRequest() - { - m_hshutdown = true; - - synchronized (m_reqList) - { - m_reqList.notify(); - } - } - - /** - * Main thread code - */ - public void run() - { - - // Loop until shutdown requested - - while (m_hshutdown == false) - { - - try - { - - // Wait for something to do - - NetBIOSRequest req = null; - - synchronized (m_reqList) - { - - // Check if there are any requests in the queue - - if (m_reqList.size() == 0) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("NetBIOS handler waiting for request ..."); - - // Wait for some work ... - - m_reqList.wait(); - } - - // Remove a request from the queue - - if (m_reqList.size() > 0) - req = m_reqList.get(0); - else if (m_hshutdown == true) - break; - } - - // Get the request retry count, for WINS only send one request - - int reqRetry = req.getRetryCount(); - if (hasPrimaryWINSServer()) - reqRetry = 1; - - // Process the request - - boolean txsts = true; - int retry = 0; - - while (req.hasErrorStatus() == false && retry++ < reqRetry) - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("NetBIOS handler, processing " + req); - - // Process the request - - switch (req.isType()) - { - - // Add name request - - case NetBIOSRequest.AddName: - - // Check if a WINS server is configured - - if (hasPrimaryWINSServer()) - txsts = sendAddName(req, getPrimaryWINSServer(), false); - else - txsts = sendAddName(req, getBroadcastAddress(), true); - break; - - // Delete name request - - case NetBIOSRequest.DeleteName: - - // Check if a WINS server is configured - - if (hasPrimaryWINSServer()) - txsts = sendDeleteName(req, getPrimaryWINSServer(), false); - else - txsts = sendDeleteName(req, getBroadcastAddress(), true); - break; - - // Refresh name request - - case NetBIOSRequest.RefreshName: - - // Check if a WINS server is configured - - if (hasPrimaryWINSServer()) - txsts = sendRefreshName(req, getPrimaryWINSServer(), false); - else - txsts = sendRefreshName(req, getBroadcastAddress(), true); - break; - } - - // Check if the request was successful - - if (txsts == true && req.getRetryInterval() > 0) - { - - // Sleep for a while - - sleep(req.getRetryInterval()); - } - } - - // Check if the request was successful - - if (req.hasErrorStatus() == false) - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("NetBIOS handler successful, " + req); - - // Update the name record - - NetBIOSName nbName = req.getNetBIOSName(); - - switch (req.isType()) - { - - // Add name request - - case NetBIOSRequest.AddName: - - // Add the name to the list of local names - - if (m_localNames.contains(nbName) == false) - m_localNames.addElement(nbName); - - // Update the expiry time for the name - - nbName.setExpiryTime(System.currentTimeMillis() + (nbName.getTimeToLive() * 1000L)); - - // Inform listeners that the request was successful - - fireAddNameEvent(nbName, NetBIOSNameEvent.ADD_SUCCESS); - break; - - // Delete name request - - case NetBIOSRequest.DeleteName: - - // Remove the name from the list of local names - - m_localNames.remove(req.getNetBIOSName()); - break; - - // Refresh name registration request - - case NetBIOSRequest.RefreshName: - - // Update the expiry time for the name - - nbName.setExpiryTime(System.currentTimeMillis() + (nbName.getTimeToLive() * 1000L)); - break; - } - } - else - { - - // Error occurred - - switch (req.isType()) - { - - // Add name request - - case NetBIOSRequest.AddName: - - // Remove the name from the local name list - - m_localNames.remove(req.getNetBIOSName()); - break; - } - } - - // Remove the request from the queue - - synchronized (m_reqList) - { - m_reqList.remove(0); - } - } - catch (InterruptedException ex) - { - } - - // Check if the request handler has been shutdown - - if (m_hshutdown == true) - break; - } - } - - /** - * Send an add name request - * - * @param req NetBIOSRequest - * @param dest InetAddress - * @param bcast boolean - * @return boolean - */ - private final boolean sendAddName(NetBIOSRequest req, InetAddress dest, boolean bcast) - { - - try - { - - // Allocate a buffer for the add name NetBIOS packet - - byte[] buf = new byte[AddNameSize]; - NetBIOSPacket addPkt = new NetBIOSPacket(buf); - - // Build an add name packet for each IP address - - for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) - { - - // Build an add name request for the current IP address - - int len = addPkt.buildAddNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); - if (bcast == false) - addPkt.setFlags(0); - - // Allocate the datagram packet, using the add name buffer - - DatagramPacket pkt = new DatagramPacket(buf, len, dest, RFCNetBIOSProtocol.NAME_PORT); - - // Send the add name request - - if (m_socket != null) - m_socket.send(pkt); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug(" Add name " + (bcast ? "broadcast" : "WINS") + ", " + req); - } - } - catch (IOException ex) - { - fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_IOERROR); - req.setErrorStatus(true); - return false; - } - - // Add name broadcast successful - - return true; - } - - /** - * Send a refresh name request - * - * @param req NetBIOSRequest - * @param dest InetAddress - * @param bcast boolean - * @return boolean - */ - private final boolean sendRefreshName(NetBIOSRequest req, InetAddress dest, boolean bcast) - { - - try - { - - // Allocate a buffer for the refresh name NetBIOS packet - - byte[] buf = new byte[RefreshNameSize]; - NetBIOSPacket refreshPkt = new NetBIOSPacket(buf); - - // Build a refresh name packet for each IP address - - for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) - { - - // Build a refresh name request for the current IP address - - int len = refreshPkt.buildRefreshNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); - if (bcast == false) - refreshPkt.setFlags(0); - - // Allocate the datagram packet, using the refresh name buffer - - DatagramPacket pkt = new DatagramPacket(buf, len, dest, RFCNetBIOSProtocol.NAME_PORT); - - // Send the refresh name request - - if (m_socket != null) - m_socket.send(pkt); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug(" Refresh name " + (bcast ? "broadcast" : "WINS") + ", " + req); - } - } - catch (IOException ex) - { - req.setErrorStatus(true); - return false; - } - - // Add name broadcast successful - - return true; - } - - /** - * Send a delete name request via a network broadcast - * - * @param req NetBIOSRequest - * @param dest InetAddress - * @param bcast boolean - * @return boolean - */ - private final boolean sendDeleteName(NetBIOSRequest req, InetAddress dest, boolean bcast) - { - - try - { - - // Allocate a buffer for the delete name NetBIOS packet - - byte[] buf = new byte[DeleteNameSize]; - NetBIOSPacket delPkt = new NetBIOSPacket(buf); - - // Build a delete name packet for each IP address - - for (int i = 0; i < req.getNetBIOSName().numberOfAddresses(); i++) - { - - // Build an add name request for the current IP address - - int len = delPkt.buildDeleteNameRequest(req.getNetBIOSName(), i, req.getTransactionId()); - if (bcast == false) - delPkt.setFlags(0); - - // Allocate the datagram packet, using the add name buffer - - DatagramPacket pkt = new DatagramPacket(buf, len, dest, RFCNetBIOSProtocol.NAME_PORT); - - // Send the add name request - - if (m_socket != null) - m_socket.send(pkt); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug(" Delete name " + (bcast ? "broadcast" : "WINS") + ", " + req); - } - } - catch (IOException ex) - { - req.setErrorStatus(true); - return false; - } - - // Delete name broadcast successful - - return true; - } - }; - - // NetBIOS name refresh thread inner class - - class NetBIOSNameRefresh extends Thread - { - - // Shutdown request flag - - private boolean m_hshutdown = false; - - /** - * Default constructor - */ - public NetBIOSNameRefresh() - { - setDaemon(true); - setName("NetBIOSRefresh"); - } - - /** - * Shutdown the name refresh thread - */ - public final void shutdownRequest() - { - m_hshutdown = true; - - // Wakeup the thread - - this.interrupt(); - } - - /** - * Main thread code - */ - public void run() - { - - // Loop for ever - - while (m_hshutdown == false) - { - - try - { - - // Sleep for a while - - sleep(NameRefreshWakeupInterval); - - // Check if there is a shutdown pending - - if (m_hshutdown == true) - break; - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("NetBIOS name refresh wakeup ..."); - - // Check if there are any registered names that will expire in the next interval - - synchronized (m_localNames) - { - - // Get the current time plus the wakeup interval - - long expireTime = System.currentTimeMillis() + NameRefreshWakeupInterval; - - // Loop through the local name list - - for (int i = 0; i < m_localNames.size(); i++) - { - - // Get a name from the list - - NetBIOSName nbName = m_localNames.get(i); - - // Check if the name has expired, or will expire before the next wakeup - // event - - if (nbName.getExpiryTime() < expireTime) - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("Queuing name refresh for " + nbName); - - // Queue a refresh request for the NetBIOS name - - NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.RefreshName, nbName, - getNextTransactionId()); - nbReq.setRetryCount(RefreshNameRetries); - - // Queue the request - - synchronized (m_reqList) - { - - // Add the request to the list - - m_reqList.addElement(nbReq); - - // Wakeup the processing thread - - m_reqList.notify(); - } - } - } - } - } - catch (Exception ex) - { - - // Debug - - if ( m_hshutdown == false) - logger.error("NetBIOS Name refresh thread exception", ex); - } - } - } - }; - - /** - * Default constructor - * - * @param serviceRegistry repository connection - * @param config ServerConfiguration - * @exception SocketException If a network setup error occurs - */ - public NetBIOSNameServer(ServerConfiguration config) throws SocketException - { - super("NetBIOS", config); - - // Set the NetBIOS name server port - - setServerPort( config.getNetBIOSNamePort()); - - // Perform common constructor code - - commonConstructor(); - } - - /** - * Common constructor code - * - * @exception SocketException If a network setup error occurs - */ - private final void commonConstructor() throws SocketException - { - // Allocate the local and remote name tables - - m_localNames = new Vector(); - m_remoteNames = new Hashtable(); - - // Check if NetBIOS name server debug output is enabled - - if (getConfiguration().hasNetBIOSDebug()) - setDebug(true); - - // Set the local address to bind the server to, and server port - - setBindAddress(getConfiguration().getNetBIOSBindAddress()); - - // Copy the WINS server addresses, if set - - setPrimaryWINSServer(getConfiguration().getPrimaryWINSServer()); - setSecondaryWINSServer(getConfiguration().getSecondaryWINSServer()); - - // Check if WINS is not enabled, use broadcasts instead - - if (hasPrimaryWINSServer() == false) - { - - try - { - m_bcastAddr = InetAddress.getByName(getConfiguration().getBroadcastMask()); - } - catch (Exception ex) - { - } - } - } - - /** - * Return the local address the server binds to, or null if all local addresses are used. - * - * @return java.net.InetAddress - */ - public final InetAddress getBindAddress() - { - return m_bindAddress; - } - - /** - * Return the next available transaction id for outgoing NetBIOS packets. - * - * @return int - */ - protected final synchronized int getNextTransactionId() - { - return m_tranId++; - } - - /** - * Return the port/socket that the server is bound to. - * - * @return int - */ - public final int getPort() - { - return m_port; - } - - /** - * Determine if the server binds to a particulat local address, or all addresses - * - * @return boolean - */ - public final boolean hasBindAddress() - { - return m_bindAddress != null ? true : false; - } - - /** - * Return the remote name table - * - * @return Hashtable - */ - public final Hashtable getNameTable() - { - return m_remoteNames; - } - - /** - * Return the broadcast address, if WINS is disabled - * - * @return InetAddress - */ - public final InetAddress getBroadcastAddress() - { - return m_bcastAddr; - } - - /** - * Determine if the primary WINS server address has been set - * - * @return boolean - */ - public final boolean hasPrimaryWINSServer() - { - return m_winsPrimary != null ? true : false; - } - - /** - * Return the primary WINS server address - * - * @return InetAddress - */ - public final InetAddress getPrimaryWINSServer() - { - return m_winsPrimary; - } - - /** - * Determine if the secondary WINS server address has been set - * - * @return boolean - */ - public final boolean hasSecondaryWINSServer() - { - return m_winsSecondary != null ? true : false; - } - - /** - * Return the secondary WINS server address - * - * @return InetAddress - */ - public final InetAddress getSecondaryWINSServer() - { - return m_winsSecondary; - } - - /** - * Add a NetBIOS name. - * - * @param name NetBIOS name to be added - * @exception java.io.IOException I/O error occurred. - */ - public final synchronized void AddName(NetBIOSName name) throws IOException - { - - // Check if the NetBIOS name socket has been initialized - - if (m_socket == null) - throw new IOException("NetBIOS name socket not initialized"); - - // Create an add name request and add to the request list - - NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.AddName, name, getNextTransactionId()); - - // Set the retry interval - - if (hasPrimaryWINSServer()) - nbReq.setRetryInterval(AddNameWINSInterval); - else - nbReq.setRetryInterval(AddNameInterval); - - // Add the name to the local name list - - m_localNames.addElement(name); - - // Queue the request - - synchronized (m_reqList) - { - - // Add the request to the list - - m_reqList.addElement(nbReq); - - // Wakeup the processing thread - - m_reqList.notify(); - } - } - - /** - * Delete a NetBIOS name. - * - * @param name NetBIOS name to be deleted - * @exception java.io.IOException I/O error occurred. - */ - public final synchronized void DeleteName(NetBIOSName name) throws IOException - { - - // Check if the NetBIOS name socket has been initialized - - if (m_socket == null) - throw new IOException("NetBIOS name socket not initialized"); - - // Create a delete name request and add to the request list - - NetBIOSRequest nbReq = new NetBIOSRequest(NetBIOSRequest.DeleteName, name, getNextTransactionId(), - DeleteNameRetries); - nbReq.setRetryInterval(DeleteNameInterval); - - synchronized (m_reqList) - { - - // Add the request to the list - - m_reqList.addElement(nbReq); - - // Wakeup the processing thread - - m_reqList.notify(); - } - } - - /** - * Add a local add name listener to the NetBIOS name server. - * - * @param l AddNameListener - */ - public final synchronized void addAddNameListener(AddNameListener l) - { - - // Check if the add name listener list is allocated - - if (m_addListeners == null) - m_addListeners = new Vector(); - m_addListeners.addElement(l); - } - - /** - * Add a query name listener to the NetBIOS name server. - * - * @param l QueryNameListener - */ - public final synchronized void addQueryListener(QueryNameListener l) - { - - // Check if the query name listener list is allocated - - if (m_queryListeners == null) - m_queryListeners = new Vector(); - m_queryListeners.addElement(l); - } - - /** - * Add a remote name listener to the NetBIOS name server. - * - * @param l RemoteNameListener - */ - public final synchronized void addRemoteListener(RemoteNameListener l) - { - - // Check if the remote name listener list is allocated - - if (m_remoteListeners == null) - m_remoteListeners = new Vector(); - m_remoteListeners.addElement(l); - } - - /** - * Trigger an add name event to all registered listeners. - * - * @param name NetBIOSName - * @param sts int - */ - protected final synchronized void fireAddNameEvent(NetBIOSName name, int sts) - { - - // Check if there are any listeners - - if (m_addListeners == null || m_addListeners.size() == 0) - return; - - // Create a NetBIOS name event - - NetBIOSNameEvent evt = new NetBIOSNameEvent(name, sts); - - // Inform all registered listeners - - for (int i = 0; i < m_addListeners.size(); i++) - { - AddNameListener addListener = m_addListeners.get(i); - addListener.netbiosNameAdded(evt); - } - } - - /** - * Trigger an query name event to all registered listeners. - * - * @param name NetBIOSName - * @param sts int - */ - protected final synchronized void fireQueryNameEvent(NetBIOSName name, InetAddress addr) - { - - // Check if there are any listeners - - if (m_queryListeners == null || m_queryListeners.size() == 0) - return; - - // Create a NetBIOS name event - - NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.QUERY_NAME); - - // Inform all registered listeners - - for (int i = 0; i < m_queryListeners.size(); i++) - { - QueryNameListener queryListener = m_queryListeners.get(i); - queryListener.netbiosNameQuery(evt, addr); - } - } - - /** - * Trigger a name register event to all registered listeners. - * - * @param name NetBIOSName - * @param sts int - */ - protected final synchronized void fireNameRegisterEvent(NetBIOSName name, InetAddress addr) - { - - // Check if there are any listeners - - if (m_remoteListeners == null || m_remoteListeners.size() == 0) - return; - - // Create a NetBIOS name event - - NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.REGISTER_NAME); - - // Inform all registered listeners - - for (int i = 0; i < m_remoteListeners.size(); i++) - { - RemoteNameListener nameListener = m_remoteListeners.get(i); - nameListener.netbiosAddRemoteName(evt, addr); - } - } - - /** - * Trigger a name release event to all registered listeners. - * - * @param name NetBIOSName - * @param sts int - */ - protected final synchronized void fireNameReleaseEvent(NetBIOSName name, InetAddress addr) - { - - // Check if there are any listeners - - if (m_remoteListeners == null || m_remoteListeners.size() == 0) - return; - - // Create a NetBIOS name event - - NetBIOSNameEvent evt = new NetBIOSNameEvent(name, NetBIOSNameEvent.REGISTER_NAME); - - // Inform all registered listeners - - for (int i = 0; i < m_remoteListeners.size(); i++) - { - RemoteNameListener nameListener = m_remoteListeners.get(i); - nameListener.netbiosReleaseRemoteName(evt, addr); - } - } - - /** - * Open the server socket - * - * @exception SocketException - */ - private void openSocket() throws java.net.SocketException - { - - // Check if the server should bind to a particular local address, or all addresses - - if (hasBindAddress()) - m_socket = new DatagramSocket(getPort(), m_bindAddress); - else - m_socket = new DatagramSocket(getPort()); - } - - /** - * Process a NetBIOS name query. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processNameQuery(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - - // Check that the name query packet is valid - - if (pkt.getQuestionCount() != 1) - return; - - // Get the name that is being queried - - String searchName = pkt.getQuestionName(); - char nameType = searchName.charAt(15); - - int len = 0; - while (len <= 14 && searchName.charAt(len) != ' ' && searchName.charAt(len) != 0) - len++; - searchName = searchName.substring(0, len); - - // Check if this is an adapter status request - - if ( searchName.equals( NetBIOSName.AdapterStatusName)) { - - // Process the adapter status request - - processAdapterStatus( pkt, fromAddr, fromPort); - return; - } - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Query name=" + searchName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" - + len); - - // Search for the name in the local name table - - Enumeration enm = m_localNames.elements(); - NetBIOSName nbName = null; - boolean foundName = false; - - while (enm.hasMoreElements() && foundName == false) - { - - // Get the current NetBIOS name item from the local name table - - nbName = enm.nextElement(); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("NetBIOS Name - " + nbName.getName() + ", len=" + nbName.getName().length() + ",type=" - + NetBIOSName.TypeAsString(nbName.getType())); - - // Check if the name matches the query name - - if (nbName.getType() == nameType && nbName.getName().compareTo(searchName) == 0) - foundName = true; - } - - // Check if we found a matching name - - if (foundName == true) - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Found name " + searchName + " in local name table : " + nbName.toString()); - - // Build the name query response - - int pktLen = pkt.buildNameQueryResponse(nbName); - - // Debug - - if (logger.isDebugEnabled()) - { - logger.debug("%% NetBIOS Reply to " + fromAddr.getHostAddress() + " :-"); - pkt.DumpPacket(false); - } - - // Send the reply packet - - try - { - - // Send the name query reply - - sendPacket(pkt, pktLen, fromAddr, fromPort); - } - catch (java.io.IOException ex) - { - logger.error("Name query response error", ex); - } - - // Inform listeners of the name query - - fireQueryNameEvent(nbName, fromAddr); - } - else - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Failed to find match for name " + searchName); - } - } - - /** - * Process a NetBIOS name register request. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processNameRegister(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - - // Check that the name register packet is valid - - if (pkt.getQuestionCount() != 1) - return; - - // Get the name that is being registered - - String regName = pkt.getQuestionName(); - char nameType = regName.charAt(15); - - int len = 0; - while (len <= 14 && regName.charAt(len) != ' ') - len++; - regName = regName.substring(0, len); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Register name=" + regName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" - + len); - - // Create a NetBIOS name for the host - - byte[] hostIP = fromAddr.getAddress(); - NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); - - // Add the name to the remote host name table - - m_remoteNames.put(nbName, hostIP); - - // Inform listeners that a new remote name has been added - - fireNameRegisterEvent(nbName, fromAddr); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Added remote name " + nbName.toString() + " to remote names table"); - } - - /** - * Process a NetBIOS name release. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processNameRelease(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - - // Check that the name release packet is valid - - if (pkt.getQuestionCount() != 1) - return; - - // Get the name that is being released - - String regName = pkt.getQuestionName(); - char nameType = regName.charAt(15); - - int len = 0; - while (len <= 14 && regName.charAt(len) != ' ') - len++; - regName = regName.substring(0, len); - - // Debug - - if (logger.isDebugEnabled()) - logger - .debug("%% Release name=" + regName + ", type=" + NetBIOSName.TypeAsString(nameType) + ", len=" - + len); - - // Create a NetBIOS name for the host - - byte[] hostIP = fromAddr.getAddress(); - NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); - - // Remove the name from the remote host name table - - m_remoteNames.remove(nbName); - - // Inform listeners that a remote name has been released - - fireNameReleaseEvent(nbName, fromAddr); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Released remote name " + nbName.toString() + " from remote names table"); - } - - /** - * Process a NetBIOS query response. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processQueryResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - } - - /** - * Process a NetBIOS name register response. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processRegisterResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - - // Check if there are any reply name details - - if (pkt.getAnswerCount() == 0) - return; - - // Get the details from the response packet - - int tranId = pkt.getTransactionId(); - - // Find the matching request - - NetBIOSRequest req = findRequest(tranId); - if (req == null) - return; - - // Get the error code from the response - - int errCode = pkt.getResultCode(); - - if (errCode != 0) - { - - // Mark the request error - - req.setErrorStatus(true); - - // Get the name details - - String regName = pkt.getAnswerName(); - char nameType = regName.charAt(15); - - int len = 0; - while (len <= 14 && regName.charAt(len) != ' ') - len++; - regName = regName.substring(0, len); - - // Create a NetBIOS name for the host - - byte[] hostIP = fromAddr.getAddress(); - NetBIOSName nbName = new NetBIOSName(regName, nameType, false, hostIP); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Negative Name Registration name=" + nbName); - - // Inform listeners of the add name failure - - fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_FAILED); - } - else - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Name Registration Successful name=" + req.getNetBIOSName().getName()); - - // Inform listeners that the add name was successful - - fireAddNameEvent(req.getNetBIOSName(), NetBIOSNameEvent.ADD_SUCCESS); - } - } - - /** - * Process a NetBIOS name release response. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processReleaseResponse(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - } - - /** - * Process a NetBIOS WACK. - * - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processWack(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) - { - } - - /** - * Process an adapter status request - * @param pkt NetBIOSPacket - * @param fromAddr InetAddress - * @param fromPort int - */ - protected final void processAdapterStatus(NetBIOSPacket pkt, InetAddress fromAddr, int fromPort) { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("%% Adapter status request"); - - // Build the local name list - - NetBIOSNameList nameList = new NetBIOSNameList(); - for ( int i = 0; i < m_localNames.size(); i++) - nameList.addName( m_localNames.get( i)); - - // Build the name query response - - int pktLen = pkt.buildAdapterStatusResponse( nameList, hasPrimaryWINSServer() ? NetBIOSPacket.NAME_TYPE_PNODE : NetBIOSPacket.NAME_TYPE_BNODE); - - // Debug - - if (logger.isDebugEnabled()) { - logger.debug("%% NetBIOS Reply to " + fromAddr.getHostAddress() + " :-"); - pkt.DumpPacket(false); - } - - // Send the reply packet - - try { - - // Send the name query reply - - sendPacket(pkt, pktLen, fromAddr, fromPort); - } - catch (java.io.IOException ex) { - if ( logger.isErrorEnabled()) - logger.error(ex); - } - } - - /** - * Remove a local add name listener from the NetBIOS name server. - * - * @param l AddNameListener - */ - public final synchronized void removeAddNameListener(AddNameListener l) - { - - // Check if the listener list is valid - - if (m_addListeners == null) - return; - m_addListeners.removeElement(l); - } - - /** - * Remove a query name listner from the NetBIOS name server. - * - * @param l QueryNameListener - */ - public final synchronized void removeQueryNameListener(QueryNameListener l) - { - - // Check if the listener list is valid - - if (m_queryListeners == null) - return; - m_queryListeners.removeElement(l); - } - - /** - * Remove a remote name listener from the NetBIOS name server. - * - * @param l RemoteNameListener - */ - public final synchronized void removeRemoteListener(RemoteNameListener l) - { - - // Check if the listener list is valid - - if (m_remoteListeners == null) - return; - m_remoteListeners.removeElement(l); - } - - /** - * Run the NetBIOS name server. - */ - public void run() - { - - // Initialize the NetBIOS name socket - - NetBIOSPacket nbPkt = null; - DatagramPacket pkt = null; - byte[] buf = null; - - try - { - - // Get a list of the local IP addresses - - Vector ipList = new Vector(); - - if (hasBindAddress()) - { - - // Use the specified bind address - - ipList.add(getBindAddress().getAddress()); - } - else - { - - // Get a list of all the local addresses - - InetAddress[] addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); - - for (int i = 0; i < addrs.length; i++) - { - - // Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses - - if (addrs[i].getHostAddress().equals("127.0.0.1") == false - && addrs[i].getHostAddress().equals("0.0.0.0") == false) - ipList.add(addrs[i].getAddress()); - } - - // Check if the address list is empty, use the network interface list to get the local IP addresses - - if ( ipList.size() == 0) - { - // Enumerate the network adapter list - - Enumeration niEnum = NetworkInterface.getNetworkInterfaces(); - - if ( niEnum != null) - { - while ( niEnum.hasMoreElements()) - { - // Get the current network interface - - NetworkInterface ni = niEnum.nextElement(); - - // Enumerate the addresses for the network adapter - - Enumeration niAddrs = ni.getInetAddresses(); - if ( niAddrs != null) - { - // Check for any valid addresses - - while ( niAddrs.hasMoreElements()) - { - InetAddress curAddr = niAddrs.nextElement(); - - if ( curAddr.getHostAddress().equals("127.0.0.1") == false && - curAddr.getHostAddress().equals("0.0.0.0") == false) - ipList.add( curAddr.getAddress()); - } - } - } - - // DEBUG - - if ( ipList.size() > 0 && logger.isDebugEnabled()) - logger.debug("Found " + ipList.size() + " addresses using interface list"); - } - } - else - { - // DBEUG - - if ( logger.isDebugEnabled()) - logger.debug("Found " + ipList.size() + " addresses using host name lookup"); - } - - // Check if any addresses were added to the list - - if ( ipList.size() == 0) - { - // Log the available IP addresses - - logger.error("Failed to get IP address(es) for NetBIOS name"); - for ( int i = 0; i < addrs.length; i++) - logger.error( " Address: " + addrs[i]); - logger.error("Check hosts file and/or DNS setup"); - logger.error("NetBIOS name server is shutting down"); - - return; - } - } - - // Initialize the NetBIOS name socket - - if (m_socket == null) - openSocket(); - - // Allocate the NetBIOS request queue, and add the server name/alias name requests - - m_reqList = new Vector(); - - // Add the server name requests to the queue - - AddName(new NetBIOSName(getConfiguration().getServerName(), NetBIOSName.FileServer, false, ipList, - DefaultTTL)); - AddName(new NetBIOSName(getConfiguration().getServerName(), NetBIOSName.WorkStation, false, ipList, - DefaultTTL)); - - if (getConfiguration().getDomainName() != null) - AddName(new NetBIOSName(getConfiguration().getDomainName(), NetBIOSName.Domain, true, ipList, - DefaultTTL)); - - // Create the request handler thread - - m_reqHandler = new NetBIOSRequestHandler(); - m_reqHandler.start(); - - // Create the name refresh thread - - m_refreshThread = new NetBIOSNameRefresh(); - m_refreshThread.start(); - - // Allocate a receive buffer, NetBIOS packet and datagram packet - - buf = new byte[1024]; - nbPkt = new NetBIOSPacket(buf); - pkt = new DatagramPacket(buf, buf.length); - } - catch (Exception ex) - { - - // Debug - - logger.error("NetBIOSNameServer setup error:", ex); - - // Save the exception and inform listeners of the error - - setException(ex); - fireServerEvent(ServerListener.ServerError); - } - - // If there are any pending requests in the queue then wakeup the request handler thread - - if (m_reqList != null && m_reqList.size() > 0) - { - synchronized (m_reqList) - { - m_reqList.notify(); - } - } - - // Indicate that the server is active - - setActive(true); - fireServerEvent(ServerListener.ServerActive); - - // Loop - - if (hasException() == false) - { - - // Clear the shutdown request flag - - m_shutdown = false; - - while (m_shutdown == false) - { - - try - { - - // Wait for an incoming packet .... - - m_socket.receive(pkt); - - // Check for a zero length datagram - - if (pkt.getLength() == 0) - continue; - - // Get the incoming NetBIOS packet opcode - - InetAddress fromAddr = pkt.getAddress(); - int fromPort = pkt.getPort(); - - switch (nbPkt.getOpcode()) - { - - // Name query - - case NetBIOSPacket.NAME_QUERY: - processNameQuery(nbPkt, fromAddr, fromPort); - break; - - // Name register - - case NetBIOSPacket.NAME_REGISTER: - processNameRegister(nbPkt, fromAddr, fromPort); - break; - - // Name release - - case NetBIOSPacket.NAME_RELEASE: - processNameRelease(nbPkt, fromAddr, fromPort); - break; - - // Name register response - - case NetBIOSPacket.RESP_REGISTER: - processRegisterResponse(nbPkt, fromAddr, fromPort); - break; - - // Name query response - - case NetBIOSPacket.RESP_QUERY: - processQueryResponse(nbPkt, fromAddr, fromPort); - break; - - // Name release response - - case NetBIOSPacket.RESP_RELEASE: - processReleaseResponse(nbPkt, fromAddr, fromPort); - break; - - // WACK - - case NetBIOSPacket.WACK: - processWack(nbPkt, fromAddr, fromPort); - break; - - // Refresh - - case NetBIOSPacket.REFRESH: - processNameRegister(nbPkt, fromAddr, fromPort); - break; - - // Multi-homed name registration - - case NetBIOSPacket.NAME_REGISTER_MULTI: - processNameRegister(nbPkt, fromAddr, fromPort); - break; - - // Unknown opcode - - default: -// logger.error("Unknown OpCode 0x" + Integer.toHexString(nbPkt.getOpcode())); - break; - } - } - catch (Exception ex) - { - - // Debug - - if ( m_shutdown == false) - logger.error("NetBIOSNameServer error", ex); - - // Store the error and inform listeners of the server error. If the server is - // shutting down we expect a - // socket error as the socket is closed by the shutdown thread and the pending - // read request generates an - // exception. - - if (m_shutdown == false) - { - setException(ex); - fireServerEvent(ServerListener.ServerError); - } - } - } - } - - // Indicate that the server is closed - - setActive(false); - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Send a packet via the NetBIOS naming datagram socket. - * - * @param pkt NetBIOSPacket - * @param len int - * @exception java.io.IOException The exception description. - */ - protected final void sendPacket(NetBIOSPacket nbpkt, int len) throws java.io.IOException - { - - // Allocate the datagram packet, using the add name buffer - - DatagramPacket pkt = new DatagramPacket(nbpkt.getBuffer(), len, NetworkSettings.getBroadcastAddress(), - getPort()); - - // Send the datagram packet - - m_socket.send(pkt); - } - - /** - * Send a packet via the NetBIOS naming datagram socket. - * - * @param pkt NetBIOSPacket - * @param len int - * @param replyAddr InetAddress - * @param replyPort int - * @exception java.io.IOException The exception description. - */ - protected final void sendPacket(NetBIOSPacket nbpkt, int len, InetAddress replyAddr, int replyPort) - throws java.io.IOException - { - // Allocate the datagram packet, using the add name buffer - - DatagramPacket pkt = new DatagramPacket(nbpkt.getBuffer(), len, replyAddr, replyPort); - - // Send the datagram packet - - m_socket.send(pkt); - } - - /** - * Set the local address that the server should bind to - * - * @param addr java.net.InetAddress - */ - public final void setBindAddress(InetAddress addr) - { - m_bindAddress = addr; - } - - /** - * Set the server port - * - * @param port int - */ - public final void setServerPort(int port) - { - m_port = port; - } - - /** - * Set the primary WINS server address - * - * @param addr InetAddress - */ - public final void setPrimaryWINSServer(InetAddress addr) - { - m_winsPrimary = addr; - } - - /** - * Set the secondary WINS server address - * - * @param addr InetAddress - */ - public final void setSecondaryWINSServer(InetAddress addr) - { - m_winsSecondary = addr; - } - - /** - * Find the NetBIOS request with the specified transation id - * - * @param id int - * @return NetBIOSRequest - */ - private final NetBIOSRequest findRequest(int id) - { - - // Check if the request list is valid - - if (m_reqList == null) - return null; - - // Need to lock access to the request list - - NetBIOSRequest req = null; - - synchronized (m_reqList) - { - - // Search for the required request - - int idx = 0; - - while (req == null && idx < m_reqList.size()) - { - - // Get the current request and check if it is the required request - - NetBIOSRequest curReq = (NetBIOSRequest) m_reqList.elementAt(idx++); - if (curReq.getTransactionId() == id) - req = curReq; - } - } - - // Return the request, or null if not found - - return req; - } - - /** - * Shutdown the NetBIOS name server - * - * @param immediate boolean - */ - public void shutdownServer(boolean immediate) - { - - // Close the name refresh thread - - try - { - - if (m_refreshThread != null) - { - m_refreshThread.shutdownRequest(); - } - } - catch (Exception ex) - { - - // Debug - - logger.error("Shutdown NetBIOS server error", ex); - } - - // If the shutdown is not immediate then release all of the names registered by this server - - if (isActive() && immediate == false) - { - - // Release all local names - - for (int i = 0; i < m_localNames.size(); i++) - { - - // Get the current name details - - NetBIOSName nbName = (NetBIOSName) m_localNames.elementAt(i); - - // Queue a delete name request - - try - { - DeleteName(nbName); - } - catch (IOException ex) - { - logger.error("Shutdown NetBIOS server error", ex); - } - } - - // Wait for the request handler thread to process the delete name requests - - while (m_reqList.size() > 0) - { - try - { - Thread.sleep(100); - } - catch (InterruptedException ex) - { - } - } - } - - // Close the request handler thread - - try - { - - // Close the request handler thread - - if (m_reqHandler != null) - { - m_reqHandler.shutdownRequest(); - m_reqHandler.join(1000); - m_reqHandler = null; - } - } - catch (Exception ex) - { - - // Debug - - logger.error("Shutdown NetBIOS request handler error", ex); - } - - // Indicate that the server is closing - - m_shutdown = true; - - try - { - - // Close the server socket so that any pending receive is cancelled - - if (m_socket != null) - { - - try - { - m_socket.close(); - } - catch (Exception ex) - { - } - m_socket = null; - } - } - catch (Exception ex) - { - logger.error("Shutdown NetBIOS server error", ex); - } - - // Fire a shutdown notification event - - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Start the NetBIOS name server is a seperate thread - */ - public void startServer() - { - - // Create a seperate thread to run the NetBIOS name server - - m_srvThread = new Thread(this); - m_srvThread.setName("NetBIOS Name Server"); - m_srvThread.setDaemon(true); - - m_srvThread.start(); - - // Fire a server startup event - - fireServerEvent(ServerListener.ServerStartup); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/NetBIOSRequest.java b/source/java/org/alfresco/filesys/netbios/server/NetBIOSRequest.java deleted file mode 100644 index 765f76e938..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/NetBIOSRequest.java +++ /dev/null @@ -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 - *

- * 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(); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/server/PacketReceiver.java b/source/java/org/alfresco/filesys/netbios/server/PacketReceiver.java deleted file mode 100644 index 3082412771..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/PacketReceiver.java +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/QueryNameListener.java b/source/java/org/alfresco/filesys/netbios/server/QueryNameListener.java deleted file mode 100644 index a42f64dfa8..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/QueryNameListener.java +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/server/RemoteNameListener.java b/source/java/org/alfresco/filesys/netbios/server/RemoteNameListener.java deleted file mode 100644 index b803a625d6..0000000000 --- a/source/java/org/alfresco/filesys/netbios/server/RemoteNameListener.java +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/netbios/win32/NetBIOS.java b/source/java/org/alfresco/filesys/netbios/win32/NetBIOS.java deleted file mode 100644 index c946ae909d..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/NetBIOS.java +++ /dev/null @@ -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; - } -} diff --git a/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocket.java b/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocket.java deleted file mode 100644 index 506063a24e..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocket.java +++ /dev/null @@ -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 - * - *

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(""); - - str.append(",Socket:"); - if ( hasSocket()) - { - str.append("0x"); - str.append(Integer.toHexString(getSocket())); - } - else - str.append(""); - - 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(); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocketException.java b/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocketException.java deleted file mode 100644 index f93ce95a09..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/NetBIOSSocketException.java +++ /dev/null @@ -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); - } -} diff --git a/source/java/org/alfresco/filesys/netbios/win32/Win32NetBIOS.java b/source/java/org/alfresco/filesys/netbios/win32/Win32NetBIOS.java deleted file mode 100644 index 45c1f5980d..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/Win32NetBIOS.java +++ /dev/null @@ -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 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 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 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 niList = getNetworkAdapterList(); - - // Search for the address of the specified network adapter - - Enumeration 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 - */ - private static final Hashtable getNetworkAdapterList() - { - - // Get a list of the local network adapters - - Hashtable niList = new Hashtable(); - - try - { - - // Enumerate the available network adapters - - Enumeration niEnum = NetworkInterface.getNetworkInterfaces(); - - while (niEnum.hasMoreElements()) - { - - // Get the current network interface details - - NetworkInterface ni = niEnum.nextElement(); - Enumeration 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; - } - } -} diff --git a/source/java/org/alfresco/filesys/netbios/win32/WinsockError.java b/source/java/org/alfresco/filesys/netbios/win32/WinsockError.java deleted file mode 100644 index 0c83511d2e..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/WinsockError.java +++ /dev/null @@ -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 - * - *

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; - } -} diff --git a/source/java/org/alfresco/filesys/netbios/win32/WinsockNetBIOSException.java b/source/java/org/alfresco/filesys/netbios/win32/WinsockNetBIOSException.java deleted file mode 100644 index 158f3e2545..0000000000 --- a/source/java/org/alfresco/filesys/netbios/win32/WinsockNetBIOSException.java +++ /dev/null @@ -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 - * - *

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(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java b/source/java/org/alfresco/filesys/repo/CifsHelper.java similarity index 98% rename from source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java rename to source/java/org/alfresco/filesys/repo/CifsHelper.java index 73b2283261..4e8ee213e7 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java +++ b/source/java/org/alfresco/filesys/repo/CifsHelper.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/CifsIntegrationTest.java b/source/java/org/alfresco/filesys/repo/CifsIntegrationTest.java similarity index 83% rename from source/java/org/alfresco/filesys/smb/server/repo/CifsIntegrationTest.java rename to source/java/org/alfresco/filesys/repo/CifsIntegrationTest.java index c31318308a..b9d5c9d6e8 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/CifsIntegrationTest.java +++ b/source/java/org/alfresco/filesys/repo/CifsIntegrationTest.java @@ -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) { diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java b/source/java/org/alfresco/filesys/repo/ContentContext.java similarity index 92% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java rename to source/java/org/alfresco/filesys/repo/ContentContext.java index d73d05f28f..37943dcb43 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentContext.java +++ b/source/java/org/alfresco/filesys/repo/ContentContext.java @@ -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.*; /** diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java similarity index 92% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java rename to source/java/org/alfresco/filesys/repo/ContentDiskDriver.java index 292d94b09c..e30fda5fde 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/repo/ContentDiskDriver.java @@ -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 diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskInterface.java b/source/java/org/alfresco/filesys/repo/ContentDiskInterface.java similarity index 92% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentDiskInterface.java rename to source/java/org/alfresco/filesys/repo/ContentDiskInterface.java index 8f2bddb312..83e90a274d 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskInterface.java +++ b/source/java/org/alfresco/filesys/repo/ContentDiskInterface.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentFileInfo.java b/source/java/org/alfresco/filesys/repo/ContentFileInfo.java similarity index 95% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentFileInfo.java rename to source/java/org/alfresco/filesys/repo/ContentFileInfo.java index fa1477a0c3..fc7eacb053 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentFileInfo.java +++ b/source/java/org/alfresco/filesys/repo/ContentFileInfo.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentIOControlHandler.java b/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java similarity index 92% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentIOControlHandler.java rename to source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java index 79a0f8f678..3eddd2ca2a 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentIOControlHandler.java +++ b/source/java/org/alfresco/filesys/repo/ContentIOControlHandler.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentNetworkFile.java b/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java similarity index 94% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentNetworkFile.java rename to source/java/org/alfresco/filesys/repo/ContentNetworkFile.java index 3b9f883cd1..e18ec78be7 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentNetworkFile.java +++ b/source/java/org/alfresco/filesys/repo/ContentNetworkFile.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java b/source/java/org/alfresco/filesys/repo/ContentSearchContext.java similarity index 93% rename from source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java rename to source/java/org/alfresco/filesys/repo/ContentSearchContext.java index 8a640d9a85..4aa6b7d80c 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentSearchContext.java +++ b/source/java/org/alfresco/filesys/repo/ContentSearchContext.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/HomeShareMapper.java b/source/java/org/alfresco/filesys/repo/HomeShareMapper.java similarity index 58% rename from source/java/org/alfresco/filesys/smb/server/repo/HomeShareMapper.java rename to source/java/org/alfresco/filesys/repo/HomeShareMapper.java index 91b8ca2430..a35a928435 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/HomeShareMapper.java +++ b/source/java/org/alfresco/filesys/repo/HomeShareMapper.java @@ -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 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; } } diff --git a/source/java/org/alfresco/filesys/smb/server/repo/LinkMemoryNetworkFile.java b/source/java/org/alfresco/filesys/repo/LinkMemoryNetworkFile.java similarity index 93% rename from source/java/org/alfresco/filesys/smb/server/repo/LinkMemoryNetworkFile.java rename to source/java/org/alfresco/filesys/repo/LinkMemoryNetworkFile.java index 6ab447fd66..2dec86156c 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/LinkMemoryNetworkFile.java +++ b/source/java/org/alfresco/filesys/repo/LinkMemoryNetworkFile.java @@ -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; /** diff --git a/source/java/org/alfresco/filesys/smb/server/repo/NodeRefNetworkFile.java b/source/java/org/alfresco/filesys/repo/NodeRefNetworkFile.java similarity index 90% rename from source/java/org/alfresco/filesys/smb/server/repo/NodeRefNetworkFile.java rename to source/java/org/alfresco/filesys/repo/NodeRefNetworkFile.java index 5f6d137330..da19561055 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/NodeRefNetworkFile.java +++ b/source/java/org/alfresco/filesys/repo/NodeRefNetworkFile.java @@ -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 diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java b/source/java/org/alfresco/filesys/repo/desk/CheckInOutDesktopAction.java similarity index 96% rename from source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java rename to source/java/org/alfresco/filesys/repo/desk/CheckInOutDesktopAction.java index 62cc065163..28b224672e 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java +++ b/source/java/org/alfresco/filesys/repo/desk/CheckInOutDesktopAction.java @@ -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 diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java b/source/java/org/alfresco/filesys/repo/desk/CmdLineDesktopAction.java similarity index 97% rename from source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java rename to source/java/org/alfresco/filesys/repo/desk/CmdLineDesktopAction.java index 04de72fd55..f4837654e2 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java +++ b/source/java/org/alfresco/filesys/repo/desk/CmdLineDesktopAction.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/EchoDesktopAction.java b/source/java/org/alfresco/filesys/repo/desk/EchoDesktopAction.java similarity index 97% rename from source/java/org/alfresco/filesys/smb/server/repo/desk/EchoDesktopAction.java rename to source/java/org/alfresco/filesys/repo/desk/EchoDesktopAction.java index 42453cf499..7f61e6d6a6 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/EchoDesktopAction.java +++ b/source/java/org/alfresco/filesys/repo/desk/EchoDesktopAction.java @@ -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; diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/JavaScriptDesktopAction.java b/source/java/org/alfresco/filesys/repo/desk/JavaScriptDesktopAction.java similarity index 97% rename from source/java/org/alfresco/filesys/smb/server/repo/desk/JavaScriptDesktopAction.java rename to source/java/org/alfresco/filesys/repo/desk/JavaScriptDesktopAction.java index eb5a905763..7d64b5b70e 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/JavaScriptDesktopAction.java +++ b/source/java/org/alfresco/filesys/repo/desk/JavaScriptDesktopAction.java @@ -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 diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/URLDesktopAction.java b/source/java/org/alfresco/filesys/repo/desk/URLDesktopAction.java similarity index 97% rename from source/java/org/alfresco/filesys/smb/server/repo/desk/URLDesktopAction.java rename to source/java/org/alfresco/filesys/repo/desk/URLDesktopAction.java index a8b91c077c..2861abb859 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/URLDesktopAction.java +++ b/source/java/org/alfresco/filesys/repo/desk/URLDesktopAction.java @@ -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; diff --git a/source/java/org/alfresco/filesys/server/DatagramSessionHandler.java b/source/java/org/alfresco/filesys/server/DatagramSessionHandler.java deleted file mode 100644 index 3ea31bbcfd..0000000000 --- a/source/java/org/alfresco/filesys/server/DatagramSessionHandler.java +++ /dev/null @@ -1,420 +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.server; - -import java.io.*; -import java.net.*; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Datagram Session Handler Class - * - *

Implementation of a session handler that uses a Java datagram socket to listen for incoming requests. - * - * @author GKSpencer - */ -public abstract class DatagramSessionHandler implements SessionHandlerInterface, Runnable { - - // Debug logging - - protected static final Log logger = LogFactory.getLog(DatagramSessionHandler.class); - - // Server that the handler is associated with - - private NetworkServer m_server; - - // Address/port to use - - private int m_port; - - private InetAddress m_bindAddr; - - // Datagram socket to listen for incoming requests - - private DatagramSocket m_srvSock; - - // Maximum datagram size - - private int m_maxDgramSize; - - // Session id - - private int m_sessId; - - // Session handler name, protocol name - - private String m_name; - - private String m_protocol; - - // Shutdown request flag - - private boolean m_shutdown; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param server NetworkServer - * @param addr InetAddress - * @param port int - */ - protected DatagramSessionHandler(String name, String protocol, NetworkServer server, InetAddress addr, int port) - { - m_name = name; - m_protocol = protocol; - m_server = server; - - m_bindAddr = addr; - m_port = port; - } - - /** - * Return the maximum datagram size allowed - * - * @return int - */ - public final int getMaximumDatagramSize() - { - return m_maxDgramSize; - } - - /** - * Return the session handler name - * - * @return String - */ - public final String getHandlerName() - { - return m_name; - } - - /** - * Return the short protocol name - * - * @return String - */ - public final String getProtocolName() - { - return m_protocol; - } - - /** - * Check if the server should bind to a specific network address - * - * @return boolean - */ - public final boolean hasBindAddress() - { - return m_bindAddr != null ? true : false; - } - - /** - * Return the network address that the server should bind to - * - * @return InetAddress - */ - public final InetAddress getBindAddres() - { - return m_bindAddr; - } - - /** - * Return the port that the server should bind to - * - * @return int - */ - public final int getPort() - { - return m_port; - } - - /** - * Clear the shutdown flag - */ - protected final void clearShutdown() - { - m_shutdown = false; - } - - /** - * Determine if the shutdown flag has been set - * - * @return boolean - */ - protected final boolean hasShutdown() - { - return m_shutdown; - } - - /** - * Get the next available session id - * - * @return int - */ - protected synchronized int getNextSessionId() - { - return m_sessId++; - } - - /** - * Set the local port that the datagram handler is using - * - * @param port int - */ - protected final void setPort(int port) - { - m_port = port; - } - - /** - * Return the datagrma socket - * - * @return DatagramSocket - */ - protected final DatagramSocket getDatagramSocket() - { - return m_srvSock; - } - - /** - * Initialize the session handler - * - * @param server NetworkServer - */ - public void initializeSessionHandler(NetworkServer server) - throws IOException - { - - // Open the server socket - - if (hasBindAddress()) - m_srvSock = new DatagramSocket(getPort(), getBindAddres()); - else - m_srvSock = new DatagramSocket(getPort()); - - // Set the datagram receive buffer size - - if (m_srvSock.getReceiveBufferSize() < getMaximumDatagramSize()) - m_srvSock.setReceiveBufferSize(getMaximumDatagramSize()); - - // Set the allocated port - - if (getPort() == 0) - setPort(m_srvSock.getLocalPort()); - - // DEBUG - - if (logger.isDebugEnabled()) - { - String bindAddr = hasBindAddress() ? getBindAddres().getHostAddress() : "ALL"; - logger.debug("[" + getProtocolName() + "] Binding " + getHandlerName() + " session handler to address : " + bindAddr); - } - } - - /** - * Close the session handler - * - * @param server NetworkServer - */ - public void closeSessionHandler(NetworkServer server) - { - - // Request the main listener thread shutdown - - m_shutdown = true; - - // Close the server socket to release any pending listen - - if (m_srvSock != null) - m_srvSock.close(); - } - - /** - * Set the maximum datagram size - * - * @param maxSize int - */ - protected final void setMaximumDatagramSize(int maxSize) - { - m_maxDgramSize = maxSize; - } - - /** - * Process a received datagram packet - * - * @param pkt DatagramPacket - * @return boolean Return true to reuse the DatagramPacket, else false to allocate a new packet - * @exception IOException - */ - protected abstract boolean processDatagram(DatagramPacket pkt) - throws IOException; - - /** - * Allocate a buffer for the datagram receive - * - * @param bufSize int - * @return byte[] - */ - protected byte[] allocateBuffer(int bufSize) - { - - // Allocate a buffer for the datagram - - return new byte[bufSize]; - } - - /** - * Send a datagram - * - * @param pkt DatagramPacket - * @exception IOException - */ - protected void sendDatagram(DatagramPacket pkt) - throws IOException - { - - // Check if the datagram socket is valid - - if (m_srvSock == null) - throw new IOException("Datagram socket is null"); - - // Default implementation sends the datagram immediately via the datagram socket - - m_srvSock.send(pkt); - } - - /** - * Socket listener thread - */ - public void run() - { - - try - { - - // Set the thread name - - Thread.currentThread().setName(getProtocolName() + "_" + getHandlerName()); - - // Clear the shutdown flag - - clearShutdown(); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Waiting for datagrams ..."); - - // Wait for incoming connection requests - - byte[] buf = null; - DatagramPacket pkt = null; - boolean reusePkt = false; - - while (hasShutdown() == false) - { - - // Allocate the datagram buffer and packet - - if (reusePkt == false) - { - - // Allocate a new datagram packet and buffer - - buf = allocateBuffer(getMaximumDatagramSize()); - if (pkt == null) - { - - // Allocate the datagram packet - - pkt = new DatagramPacket(buf, buf.length); - } else - { - - // Re-use the existing datagram packet - - pkt.setData(buf, 0, buf.length); - } - } else - { - - // Re-use the existing datagram packet and buffer. - // - // Reset to use our buffer as the datagram packet may have been reused to send a response. - - pkt.setData(buf, 0, buf.length); - } - - // Wait for an incoming datagram - - m_srvSock.receive(pkt); - - try - { - - // Process the datagram packet - - reusePkt = processDatagram(pkt); - } catch (Exception ex) - { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Error processing datagram, " + ex.toString()); - } - } - } 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.debug("[" + getProtocolName() + "] Socket error : " + ex.toString()); - logger.debug(ex); - } - } 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.debug("[" + getProtocolName() + "] Server error : " + ex.toString()); - logger.debug(ex); - } - } - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] " + getHandlerName() + " session handler closed"); - } -} diff --git a/source/java/org/alfresco/filesys/server/NetworkServer.java b/source/java/org/alfresco/filesys/server/NetworkServer.java deleted file mode 100644 index 709d439cd0..0000000000 --- a/source/java/org/alfresco/filesys/server/NetworkServer.java +++ /dev/null @@ -1,555 +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.server; - -import java.net.InetAddress; -import java.util.Vector; - -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.core.ShareMapper; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Network Server Base Class - *

- * Base class for server implementations for different protocols. - */ -public abstract class NetworkServer -{ - private static final Log logger = LogFactory.getLog("org.alfresco.filesys"); - - // Protocol name - - private String m_protoName; - - // Server version - - private String m_version; - - // Server configuration - private ServerConfiguration m_config; - - // Debug enabled flag and debug flags - - private boolean m_debug; - private int m_debugFlags; - - // List of addresses that the server is bound to - - private InetAddress[] m_ipAddr; - - // Server shutdown flag and server active flag - - private volatile boolean m_shutdown = false; - private volatile boolean m_active = false; - - // Server error exception details - - private Exception m_exception; - - // Server events listener - - private ServerListener m_listener; - - // Session listener list - - private Vector m_sessListeners; - - /** - * Class constructor - * - * @param proto String - * @param config ServerConfiguration - */ - public NetworkServer(String proto, ServerConfiguration config) - { - m_protoName = proto; - m_config = config; - } - - /** - * Returns the server configuration. - * - * @return ServerConfiguration - */ - public final ServerConfiguration getConfiguration() - { - return m_config; - } - - /** - * Return the authenticator for this server - * - * @return CifsAuthenticator - */ - public final CifsAuthenticator getAuthenticator() - { - return getConfiguration().getAuthenticator(); - } - - /** - * Determine if an access control manager is configured - * - * @return boolean - */ - public final boolean hasAccessControlManager() - { - return getConfiguration().getAccessControlManager() != null ? true : false; - } - - /** - * Return the access control manager - * - * @return AccessControlManager - */ - public final AccessControlManager getAccessControlManager() - { - return getConfiguration().getAccessControlManager(); - } - - /** - * Return the main server name - * - * @return String - */ - public final String getServerName() - { - return m_config.getServerName(); - } - - /** - * Return the list of IP addresses that the server is bound to. - * - * @return java.net.InetAddress[] - */ - public final InetAddress[] getServerAddresses() - { - return m_ipAddr; - } - - /** - * Return the share mapper - * - * @return ShareMapper - */ - public final ShareMapper getShareMapper() - { - return m_config.getShareMapper(); - } - - /** - * Return the available shared device list. - * - * @param host String - * @param sess SrvSession - * @return SharedDeviceList - */ - public final SharedDeviceList getShareList(String host, SrvSession sess) - { - return getConfiguration().getShareMapper().getShareList(host, sess, false); - } - - /** - * Return the complete shared device list. - * - * @param host String - * @param sess SrvSession - * @return SharedDeviceList - */ - public final SharedDeviceList getFullShareList(String host, SrvSession sess) - { - return getConfiguration().getShareMapper().getShareList(host, sess, true); - } - - /** - * Find the shared device with the specified name. - * - * @param host Host name from the UNC path - * @param name Name of the shared device to find. - * @param typ Shared device type - * @param sess Session details - * @param create Create share flag, false indicates lookup only - * @return SharedDevice with the specified name and type, else null. - * @exception Exception - */ - public final SharedDevice findShare(String host, String name, int typ, SrvSession sess, boolean create) - throws Exception - { - - // Search for the specified share - - SharedDevice dev = getConfiguration().getShareMapper().findShare(host, name, typ, sess, create); - - // Return the shared device, or null - - return dev; - } - - /** - * Determine if the SMB server is active. - * - * @return boolean - */ - public final boolean isActive() - { - return m_active; - } - - /** - * Return the server version string, in 'n.n.n' format - * - * @return String - */ - - public final String isVersion() - { - return m_version; - } - - /** - * Check if there is a stored server exception - * - * @return boolean - */ - public final boolean hasException() - { - return m_exception != null ? true : false; - } - - /** - * Return the stored exception - * - * @return Exception - */ - public final Exception getException() - { - return m_exception; - } - - /** - * Clear the stored server exception - */ - public final void clearException() - { - m_exception = null; - } - - /** - * Return the server protocol name - * - * @return String - */ - public final String getProtocolName() - { - return m_protoName; - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Determine if the specified debug flag is enabled - * - * @return boolean - */ - public final boolean hasDebugFlag(int flg) - { - return (m_debugFlags & flg) != 0 ? true : false; - } - - /** - * Check if the shutdown flag is set - * - * @return boolean - */ - public final boolean hasShutdown() - { - return m_shutdown; - } - - /** - * Set/clear the server active flag - * - * @param active boolean - */ - protected void setActive(boolean active) - { - m_active = active; - } - - /** - * Set the stored server exception - * - * @param ex Exception - */ - protected final void setException(Exception ex) - { - m_exception = ex; - } - - /** - * Set the addresses that the server is bound to - * - * @param adds InetAddress[] - */ - protected final void setServerAddresses(InetAddress[] addrs) - { - m_ipAddr = addrs; - } - - /** - * Set the server version - * - * @param ver String - */ - protected final void setVersion(String ver) - { - m_version = ver; - } - - /** - * Enable/disable debug output for the server - * - * @param dbg boolean - */ - protected final void setDebug(boolean dbg) - { - m_debug = dbg; - } - - /** - * Set the debug flags - * - * @param flags int - */ - protected final void setDebugFlags(int flags) - { - m_debugFlags = flags; - setDebug(flags == 0 ? false : true); - } - - /** - * Set/clear the shutdown flag - * - * @param ena boolean - */ - protected final void setShutdown(boolean ena) - { - m_shutdown = ena; - } - - /** - * Add a server listener to this server - * - * @param l ServerListener - */ - public final void addServerListener(ServerListener l) - { - m_listener = l; - } - - /** - * Remove the server listener - * - * @param l ServerListener - */ - public final void removeServerListener(ServerListener l) - { - if (m_listener == l) - m_listener = null; - } - - /** - * Add a new session listener to the network server. - * - * @param l SessionListener - */ - public final void addSessionListener(SessionListener l) - { - - // Check if the session listener list is allocated - - if (m_sessListeners == null) - m_sessListeners = new Vector(); - m_sessListeners.add(l); - } - - /** - * Remove a session listener from the network server. - * - * @param l SessionListener - */ - public final void removeSessionListener(SessionListener l) - { - - // Check if the listener list is valid - - if (m_sessListeners == null) - return; - m_sessListeners.removeElement(l); - } - - /** - * Fire a server event to the registered listener - * - * @param event int - */ - protected final void fireServerEvent(int event) - { - - // Check if there is a listener registered with this server - - if (m_listener != null) - { - try - { - m_listener.serverStatusEvent(this, event); - } - catch (Exception ex) - { - } - } - } - - /** - * Start the network server - */ - public abstract void startServer(); - - /** - * Shutdown the network server - * - * @param immediate boolean - */ - public abstract void shutdownServer(boolean immediate); - - /** - * Trigger a closed session event to all registered session listeners. - * - * @param sess SrvSession - */ - protected final void fireSessionClosedEvent(SrvSession sess) - { - - // Check if there are any listeners - - if (m_sessListeners == null || m_sessListeners.size() == 0) - return; - - // Inform all registered listeners - - for (int i = 0; i < m_sessListeners.size(); i++) - { - - // Get the current session listener - - try - { - SessionListener sessListener = (SessionListener) m_sessListeners.elementAt(i); - sessListener.sessionClosed(sess); - } - catch (Exception ex) - { - logger.error("Session listener error [closed]: ", ex); - } - } - } - - /** - * Trigger a new session event to all registered session listeners. - * - * @param sess SrvSession - */ - protected final void fireSessionLoggedOnEvent(SrvSession sess) - { - - // Check if there are any listeners - - if (m_sessListeners == null || m_sessListeners.size() == 0) - return; - - // Inform all registered listeners - - for (int i = 0; i < m_sessListeners.size(); i++) - { - - // Get the current session listener - - try - { - SessionListener sessListener = (SessionListener) m_sessListeners.elementAt(i); - sessListener.sessionLoggedOn(sess); - } - catch (Exception ex) - { - logger.error("Session listener error [logon]: ", ex); - } - } - } - - /** - * Trigger a new session event to all registered session listeners. - * - * @param sess SrvSession - */ - protected final void fireSessionOpenEvent(SrvSession sess) - { - - // Check if there are any listeners - - if (m_sessListeners == null || m_sessListeners.size() == 0) - return; - - // Inform all registered listeners - - for (int i = 0; i < m_sessListeners.size(); i++) - { - - // Get the current session listener - - try - { - SessionListener sessListener = (SessionListener) m_sessListeners.elementAt(i); - sessListener.sessionCreated(sess); - } - catch (Exception ex) - { - logger.error("Session listener error [open]: ", ex); - } - } - } -} diff --git a/source/java/org/alfresco/filesys/server/NetworkServerList.java b/source/java/org/alfresco/filesys/server/NetworkServerList.java deleted file mode 100644 index db7b706334..0000000000 --- a/source/java/org/alfresco/filesys/server/NetworkServerList.java +++ /dev/null @@ -1,167 +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.server; - -import java.util.Vector; - -/** - * Network Server List Class - */ -public class NetworkServerList -{ - // List of network servers - - private Vector m_servers; - - /** - * Class constructor - */ - public NetworkServerList() - { - m_servers = new Vector(); - } - - /** - * Return the number of servers in the list - * - * @return int - */ - public final int numberOfServers() - { - return m_servers.size(); - } - - /** - * Add a server to the list - * - * @param server NetworkServer - */ - public final void addServer(NetworkServer server) - { - m_servers.add(server); - } - - /** - * Return the specified server - * - * @param idx int - * @return NetworkServer - */ - public final NetworkServer getServer(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_servers.size()) - return null; - return m_servers.get(idx); - } - - /** - * Find a server in the list by name - * - * @param name String - * @return NetworkServer - */ - public final NetworkServer findServer(String name) - { - - // Search for the required server - - for (int i = 0; i < m_servers.size(); i++) - { - - // Get the current server from the list - - NetworkServer server = m_servers.get(i); - - if (server.getProtocolName().equals(name)) - return server; - } - - // Server not found - - return null; - } - - /** - * Remove the server at the specified position within the list - * - * @param idx int - * @return NetworkServer - */ - public final NetworkServer removeServer(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_servers.size()) - return null; - - // Remove the server from the list - - NetworkServer server = m_servers.get(idx); - m_servers.remove(idx); - return server; - } - - /** - * Remove the server with the specified protocol name - * - * @param proto String - * @return NetworkServer - */ - public final NetworkServer removeServer(String proto) - { - - // Search for the required server - - for (int i = 0; i < m_servers.size(); i++) - { - - // Get the current server from the list - - NetworkServer server = m_servers.get(i); - - if (server.getProtocolName().equals(proto)) - { - m_servers.remove(i); - return server; - } - } - - // Server not found - - return null; - } - - /** - * Remove all servers from the list - */ - public final void removeAll() - { - m_servers.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/server/PacketHandlerInterface.java b/source/java/org/alfresco/filesys/server/PacketHandlerInterface.java deleted file mode 100644 index ab01a2d8db..0000000000 --- a/source/java/org/alfresco/filesys/server/PacketHandlerInterface.java +++ /dev/null @@ -1,79 +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.server; - -import java.io.*; - -/** - * Packet Handler Interface - * - *

Implemented by classes that read/write request packets to a network connection. - * - * @author GKSpencer - */ -public interface PacketHandlerInterface { - - /** - * Return the protocol name - * - * @return String - */ - public String getProtocolName(); - - /** - * Return the number of bytes available for reading without blocking - * - * @return int - * @exception IOException - */ - public int availableBytes() - throws IOException; - - /** - * Read a packet of data - * - * @param pkt byte[] - * @param offset int - * @param maxLen int - * @return int - * @exception IOException - */ - public int readPacket(byte[] pkt, int offset, int maxLen) - throws IOException; - - /** - * Write a packet of data - * - * @param pkt byte[] - * @param offset int - * @param len int - * @exception IOException - */ - public void writePacket(byte[] pkt, int offset, int len) - throws IOException; - - /** - * Close the packet handler - */ - public void closePacketHandler(); -} diff --git a/source/java/org/alfresco/filesys/server/PacketHandlerList.java b/source/java/org/alfresco/filesys/server/PacketHandlerList.java deleted file mode 100644 index df729d17d5..0000000000 --- a/source/java/org/alfresco/filesys/server/PacketHandlerList.java +++ /dev/null @@ -1,104 +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.server; - -import java.util.*; - -/** - * Packet Handler List Class - * - * @author GKSpencer - */ -public class PacketHandlerList { - - // List of session handlers - - private Vector m_handlers; - - /** - * Default constructor - */ - public PacketHandlerList() { - m_handlers = new Vector(); - } - - /** - * Add a handler to the list - * - * @param handler PacketHandlerInterface - */ - public final void addHandler(PacketHandlerInterface handler) { - m_handlers.addElement(handler); - } - - /** - * Return the number of handlers in the list - * - * @return int - */ - public final int numberOfHandlers() { - return m_handlers.size(); - } - - /** - * Return the specified handler - * - * @param idx int - * @return PacketHandlerInterface - */ - public final PacketHandlerInterface getHandlerAt(int idx) { - - // Range check the index - - if (idx < 0 || idx >= m_handlers.size()) - return null; - return (PacketHandlerInterface) m_handlers.elementAt(idx); - } - - /** - * Remove a handler from the list - * - * @param idx int - * @return PacketHandlerInterface - */ - public final PacketHandlerInterface remoteHandler(int idx) { - - // Range check the index - - if (idx < 0 || idx >= m_handlers.size()) - return null; - - // Remove the handler, and return it - - PacketHandlerInterface handler = (PacketHandlerInterface) m_handlers.elementAt(idx); - m_handlers.removeElementAt(idx); - return handler; - } - - /** - * Remove all handlers from the list - */ - public final void removeAllHandlers() { - m_handlers.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/server/ServerListener.java b/source/java/org/alfresco/filesys/server/ServerListener.java deleted file mode 100644 index ba49291e31..0000000000 --- a/source/java/org/alfresco/filesys/server/ServerListener.java +++ /dev/null @@ -1,49 +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.server; - -/** - * Server Listener Interface - *

- * The server listener allows external components to receive notification of server startup, - * shutdown and error events. - */ -public interface ServerListener -{ - // Server event types - - public static final int ServerStartup = 0; - public static final int ServerActive = 1; - public static final int ServerShutdown = 2; - public static final int ServerError = 3; - - /** - * Receive a server event notification - * - * @param server NetworkServer - * @param event int - */ - public void serverStatusEvent(NetworkServer server, int event); -} diff --git a/source/java/org/alfresco/filesys/server/SessionHandlerInterface.java b/source/java/org/alfresco/filesys/server/SessionHandlerInterface.java deleted file mode 100644 index bed100ed24..0000000000 --- a/source/java/org/alfresco/filesys/server/SessionHandlerInterface.java +++ /dev/null @@ -1,57 +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.server; - -import java.io.*; - -/** - * Session Handler Interface - * - *

Implemented by classes that wait for an incoming session request. - * - * @author GKSpencer - */ -public interface SessionHandlerInterface -{ - /** - * Return the protocol name - * - * @return String - */ - public String getHandlerName(); - - /** - * Initialize the session handler - * - * @param server - * NetworkServer - * @exception IOException - */ - public void initializeSessionHandler(NetworkServer server) - throws IOException; - - /** - * Close the session handler - */ - public void closeSessionHandler(NetworkServer server); -} diff --git a/source/java/org/alfresco/filesys/server/SessionHandlerList.java b/source/java/org/alfresco/filesys/server/SessionHandlerList.java deleted file mode 100644 index 52c4f0a1ca..0000000000 --- a/source/java/org/alfresco/filesys/server/SessionHandlerList.java +++ /dev/null @@ -1,170 +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.server; - -import java.util.*; - -/** - * Session Handler List Class - * - * @author GKSpencer - */ -public class SessionHandlerList { - - // List of session handlers - - private Vector m_handlers; - - /** - * Default constructor - */ - public SessionHandlerList() - { - m_handlers = new Vector(); - } - - /** - * Add a handler to the list - * - * @param handler SessionHandlerInterface - */ - public final void addHandler(SessionHandlerInterface handler) - { - m_handlers.addElement(handler); - } - - /** - * Return the number of handlers in the list - * - * @return int - */ - public final int numberOfHandlers() - { - return m_handlers.size(); - } - - /** - * Return the specified handler - * - * @param idx int - * @return SessionHandlerInterface - */ - public final SessionHandlerInterface getHandlerAt(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_handlers.size()) - return null; - return (SessionHandlerInterface) m_handlers.elementAt(idx); - } - - /** - * Find the required handler by name - * - * @param name String - * @return SessionHandlerInterface - */ - public final SessionHandlerInterface findHandler(String name) - { - - // Search for the required handler - - for (int i = 0; i < m_handlers.size(); i++) - { - - // Get the current handler - - SessionHandlerInterface handler = (SessionHandlerInterface) m_handlers.elementAt(i); - - if (handler.getHandlerName().equals(name)) - return handler; - } - - // Handler not found - - return null; - } - - /** - * Remove a handler from the list - * - * @param idx int - * @return SessionHandlerInterface - */ - public final SessionHandlerInterface remoteHandler(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_handlers.size()) - return null; - - // Remove the handler, and return it - - SessionHandlerInterface handler = (SessionHandlerInterface) m_handlers.elementAt(idx); - m_handlers.removeElementAt(idx); - return handler; - } - - /** - * Remove a handler from the list - * - * @param name String - * @return SessionHandlerInterface - */ - public final SessionHandlerInterface remoteHandler(String name) - { - - // Search for the required handler - - for (int i = 0; i < m_handlers.size(); i++) - { - - // Get the current handler - - SessionHandlerInterface handler = (SessionHandlerInterface) m_handlers.elementAt(i); - - if (handler.getHandlerName().equals(name)) - { - - // Remove the handler from the list - - m_handlers.removeElementAt(i); - return handler; - } - } - - // Handler not found - - return null; - } - - /** - * Remove all handlers from the list - */ - public final void removeAllHandlers() - { - m_handlers.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/server/SessionListener.java b/source/java/org/alfresco/filesys/server/SessionListener.java deleted file mode 100644 index fd737a5fc7..0000000000 --- a/source/java/org/alfresco/filesys/server/SessionListener.java +++ /dev/null @@ -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.server; - -/** - *

- * The session listener interface provides a hook into the server so that an application is notified - * when a new session is created and closed by a network server. - */ -public interface SessionListener -{ - - /** - * Called when a network session is closed. - * - * @param sess Network session details. - */ - public void sessionClosed(SrvSession sess); - - /** - * Called when a new network session is created by a network server. - * - * @param sess Network session that has been created for the new connection. - */ - public void sessionCreated(SrvSession sess); - - /** - * Called when a user logs on to a network server - * - * @param sess Network session that has been logged on. - */ - public void sessionLoggedOn(SrvSession sess); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/SocketPacketHandler.java b/source/java/org/alfresco/filesys/server/SocketPacketHandler.java deleted file mode 100644 index ed270a1252..0000000000 --- a/source/java/org/alfresco/filesys/server/SocketPacketHandler.java +++ /dev/null @@ -1,161 +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.server; - -import java.io.*; -import java.net.*; - -/** - * Java Socket Based Packet Handler Class - * - * @author GKSpencer - */ -public abstract class SocketPacketHandler implements PacketHandlerInterface { - - // Socket to read/write to/from - - private Socket m_socket; - - // Input/output streams for receiving/sending data - - private DataInputStream m_in; - private DataOutputStream m_out; - - /** - * Class constructor - * - * @param socket Socket - * @param protocol String - * @exception IOException - */ - protected SocketPacketHandler(Socket socket) throws IOException { - m_socket = socket; - - // Open the input/output streams - - m_in = new DataInputStream(m_socket.getInputStream()); - m_out = new DataOutputStream(m_socket.getOutputStream()); - } - - /** - * Return the protocol name - * - * @return String - */ - public abstract String getProtocolName(); - - /** - * Return the number of bytes available for reading without blocking - * - * @return int - * @exception IOException - */ - public int availableBytes() throws IOException { - if (m_in != null) - return m_in.available(); - return 0; - } - - /** - * Read a packet of data - * - * @param pkt byte[] - * @param offset int - * @param maxLen int - * @return int - * @exception IOException - */ - public int readPacket(byte[] pkt, int offset, int maxLen) throws IOException { - - // Read a packet of data - - if (m_in != null) - return m_in.read(pkt, offset, maxLen); - return 0; - } - - /** - * Write a packet of data - * - * @param pkt byte[] - * @param offset int - * @param len int - * @exception IOException - */ - public void writePacket(byte[] pkt, int offset, int len) throws IOException { - - // Output the raw packet - - if (m_out != null) { - - synchronized (m_out) { - m_out.write(pkt, offset, len); - } - } - } - - /** - * Close the packet handler - */ - public void closePacketHandler() { - - // Close the socket - - if (m_socket != null) { - try { - m_socket.close(); - } catch (Exception ex) { - } - m_socket = null; - } - - // Close the input stream - - if (m_in != null) { - try { - m_in.close(); - } catch (Exception ex) { - } - m_in = null; - } - - // Close the output stream - - if (m_out != null) { - try { - m_out.close(); - } catch (Exception ex) { - } - m_out = null; - } - } - - /** - * Return the socket - * - * @return Socket - */ - protected final Socket getSocket() { - return m_socket; - } -} diff --git a/source/java/org/alfresco/filesys/server/SocketSessionHandler.java b/source/java/org/alfresco/filesys/server/SocketSessionHandler.java deleted file mode 100644 index 72524ede68..0000000000 --- a/source/java/org/alfresco/filesys/server/SocketSessionHandler.java +++ /dev/null @@ -1,335 +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.server; - -import java.io.*; -import java.net.*; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Socket Session Handler Class - * - *

Implementation of a session handler that uses a Java socket to listen for incoming session requests. - * - * @author GKSpencer - */ -public abstract class SocketSessionHandler implements SessionHandlerInterface, Runnable { - - // Debug logging - - protected static final Log logger = LogFactory.getLog(SocketSessionHandler.class); - - // Constants - // - // Default socket listen back log limit - - public static final int ListenBacklog = 10; - - // Server that the handler is associated with - - private NetworkServer m_server; - - // Address/port to use - - private int m_port; - private InetAddress m_bindAddr; - - // Socket listen back log limit - - private int m_backLog = ListenBacklog; - - // Server socket to listen for incoming connections - - private ServerSocket m_srvSock; - - // Session id - - private int m_sessId; - - // Session handler name, protocol name - - private String m_name; - private String m_protocol; - - // Shutdown request flag - - private boolean m_shutdown; - - // Debug enable - - private boolean m_debug; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param server NetworkServer - * @param addr InetAddress - * @param port int - */ - public SocketSessionHandler(String name, String protocol, NetworkServer server, InetAddress addr, int port) { - m_name = name; - m_protocol = protocol; - m_server = server; - - m_bindAddr = addr; - m_port = port; - } - - /** - * Return the session handler name - * - * @return String - */ - public final String getHandlerName() { - return m_name; - } - - /** - * Return the short protocol name - * - * @return String - */ - public final String getProtocolName() { - return m_protocol; - } - - /** - * Check if the server should bind to a specific network address - * - * @return boolean - */ - public final boolean hasBindAddress() { - return m_bindAddr != null ? true : false; - } - - /** - * Return the network address that the server should bind to - * - * @return InetAddress - */ - public final InetAddress getBindAddress() { - return m_bindAddr; - } - - /** - * Return the port that the server should bind to - * - * @return int - */ - public final int getPort() { - return m_port; - } - - /** - * Return the socket listen backlog limit - * - * @return int - */ - public final int getListenBacklog() { - return m_backLog; - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() { - return m_debug; - } - - /** - * Clear the shutdown flag - */ - protected final void clearShutdown() { - m_shutdown = false; - } - - /** - * Determine if the shutdown flag has been set - * - * @return boolean - */ - protected final boolean hasShutdown() { - return m_shutdown; - } - - /** - * Get the next available session id - * - * @return int - */ - protected synchronized int getNextSessionId() { - return m_sessId++; - } - - /** - * Enable/disable debug output - * - * @param dbg boolean - */ - public final void setDebug(boolean dbg) { - m_debug = dbg; - } - - /** - * Set the local port that the session handler is using - * - * @param port int - */ - protected final void setPort(int port) { - m_port = port; - } - - /** - * Initialize the session handler - * - * @param server NetworkServer - */ - public void initializeSessionHandler(NetworkServer server) throws IOException { - - // Open the server socket - - if (hasBindAddress()) - m_srvSock = new ServerSocket(getPort(), getListenBacklog(), getBindAddress()); - else - m_srvSock = new ServerSocket(getPort(), getListenBacklog()); - - // Set the allocated port - - if (getPort() == 0) - setPort(m_srvSock.getLocalPort()); - - // DEBUG - - if (logger.isDebugEnabled()) { - String bindAddr = hasBindAddress() ? getBindAddress().getHostAddress() : "ALL"; - logger.debug("[" + getProtocolName() + "] Binding " + getHandlerName() + " session handler to address : " + bindAddr); - } - } - - /** - * Close the session handler - * - * @param server NetworkServer - */ - public void closeSessionHandler(NetworkServer server) { - - // Request the main listener thread shutdown - - m_shutdown = true; - - try { - - // Close the server socket to release any pending listen - - if (m_srvSock != null) - m_srvSock.close(); - } catch (SocketException ex) { - } catch (Exception ex) { - } - } - - /** - * Accept a new connection on the specified socket - * - * @param sock Socket - */ - protected abstract void acceptConnection(Socket sock); - - /** - * Socket listener thread - */ - public void run() { - - try { - - // Clear the shutdown flag - - clearShutdown(); - - // Wait for incoming connection requests - - while (hasShutdown() == false) { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Waiting for session request ..."); - - // Wait for a connection - - Socket sessSock = m_srvSock.accept(); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Session request received from " - + sessSock.getInetAddress().getHostAddress()); - - try { - - // Process the new connection request - - acceptConnection(sessSock); - } - catch (Exception ex) { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Failed to create session, " + ex.toString()); - } - } - } - 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.debug("[" + getProtocolName() + "] Socket error : " + ex.toString()); - logger.debug(ex); - } - } - 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.debug("[" + getProtocolName() + "] Server error : " + ex.toString()); - logger.debug(ex); - } - } - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] " + getHandlerName() + " session handler closed"); - } -} diff --git a/source/java/org/alfresco/filesys/server/SrvSession.java b/source/java/org/alfresco/filesys/server/SrvSession.java deleted file mode 100644 index f4d3fb071d..0000000000 --- a/source/java/org/alfresco/filesys/server/SrvSession.java +++ /dev/null @@ -1,741 +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.server; - -import java.net.InetAddress; - -import javax.transaction.Status; -import javax.transaction.UserTransaction; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.server.auth.AuthContext; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; -import org.alfresco.filesys.server.filesys.FilesysTransaction; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.transaction.SpringAwareUserTransaction; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Server Session Base Class - *

- * Base class for server session implementations for different protocols. - */ -public abstract class SrvSession -{ - // Logging - - private static final Log logger = LogFactory.getLog(SrvSession.class); - - // Network server this session is associated with - - private NetworkServer m_server; - - // Session id/slot number - - private int m_sessId; - - // Unique session id string - - private String m_uniqueId; - - // Process id - - private int m_processId = -1; - - // Session/user is logged on/validated - - private boolean m_loggedOn; - - // Client details - - private ClientInfo m_clientInfo; - - // Debug flags for this session - - private int m_debug; - - // Session shutdown flag - - private boolean m_shutdown; - - // Protocol type - - private String m_protocol; - - // Remote client/host name - - private String m_remoteName; - - // Authentication token, used during logon - - private Object m_authToken; - - // Authentication context, used during the initial session setup phase - - private AuthContext m_authContext; - - // List of dynamic/temporary shares created for this session - - private SharedDeviceList m_dynamicShares; - - // Active transaction and read/write flag - - private ThreadLocal m_tx = new ThreadLocal(); - - // Request and transaction counts - - protected int m_reqCount; - protected int m_transCount; - protected int m_transConvCount; - - /** - * Class constructor - * - * @param sessId int - * @param srv NetworkServer - * @param proto String - * @param remName String - */ - public SrvSession(int sessId, NetworkServer srv, String proto, String remName) - { - m_sessId = sessId; - m_server = srv; - - setProtocolName(proto); - setRemoteName(remName); - } - - /** - * Add a dynamic share to the list of shares created for this session - * - * @param shrDev SharedDevice - */ - public final void addDynamicShare(SharedDevice shrDev) { - - // Check if the dynamic share list must be allocated - - if ( m_dynamicShares == null) - m_dynamicShares = new SharedDeviceList(); - - // Add the new share to the list - - m_dynamicShares.addShare(shrDev); - } - - /** - * Return the authentication token - * - * @return Object - */ - public final Object getAuthenticationToken() - { - return m_authToken; - } - - /** - * Determine if the authentication token is set - * - * @return boolean - */ - public final boolean hasAuthenticationToken() - { - return m_authToken != null ? true : false; - } - - /** - * Return the process id - * - * @return int - */ - public final int getProcessId() - { - return m_processId; - } - - /** - * Return the remote client network address - * - * @return InetAddress - */ - public abstract InetAddress getRemoteAddress(); - - /** - * Return the session id for this session. - * - * @return int - */ - public final int getSessionId() - { - return m_sessId; - } - - /** - * Return the server this session is associated with - * - * @return NetworkServer - */ - public final NetworkServer getServer() - { - return m_server; - } - - /** - * Check if the session has valid client information - * - * @return boolean - */ - public final boolean hasClientInformation() - { - return m_clientInfo != null ? true : false; - } - - /** - * Return the client information - * - * @return ClientInfo - */ - public final ClientInfo getClientInformation() - { - return m_clientInfo; - } - - /** - * Check if the session has an authentication context - * - * @return boolean - */ - public final boolean hasAuthenticationContext() - { - return m_authContext != null ? true : false; - } - - /** - * Return the authentication context for this sesion - * - * @return AuthContext - */ - public final AuthContext getAuthenticationContext() - { - return m_authContext; - } - - /** - * Determine if the session has any dynamic shares - * - * @return boolean - */ - public final boolean hasDynamicShares() { - return m_dynamicShares != null ? true : false; - } - - /** - * Return the list of dynamic shares created for this session - * - * @return SharedDeviceList - */ - public final SharedDeviceList getDynamicShareList() { - return m_dynamicShares; - } - - /** - * Determine if the protocol type has been set - * - * @return boolean - */ - public final boolean hasProtocolName() - { - return m_protocol != null ? true : false; - } - - /** - * Return the protocol name - * - * @return String - */ - public final String getProtocolName() - { - return m_protocol; - } - - /** - * Determine if the remote client name has been set - * - * @return boolean - */ - public final boolean hasRemoteName() - { - return m_remoteName != null ? true : false; - } - - /** - * Return the remote client name - * - * @return String - */ - public final String getRemoteName() - { - return m_remoteName; - } - - /** - * Determine if the session is logged on/validated - * - * @return boolean - */ - public final boolean isLoggedOn() - { - return m_loggedOn; - } - - /** - * Determine if the session has been shut down - * - * @return boolean - */ - public final boolean isShutdown() - { - return m_shutdown; - } - - /** - * Return the unique session id - * - * @return String - */ - public final String getUniqueId() - { - return m_uniqueId; - } - - /** - * Determine if the specified debug flag is enabled. - * - * @return boolean - * @param dbg int - */ - public final boolean hasDebug(int dbgFlag) - { - if ((m_debug & dbgFlag) != 0) - return true; - return false; - } - - /** - * Set the authentication token - * - * @param authToken Object - */ - public final void setAuthenticationToken(Object authToken) - { - m_authToken = authToken; - } - - /** - * Set the authentication context, used during the initial session setup phase - * - * @param ctx AuthContext - */ - public final void setAuthenticationContext( AuthContext ctx) - { - m_authContext = ctx; - } - - /** - * Set the client information - * - * @param client ClientInfo - */ - public final void setClientInformation(ClientInfo client) - { - m_clientInfo = client; - } - - /** - * Set the debug output interface. - * - * @param flgs int - */ - public final void setDebug(int flgs) - { - m_debug = flgs; - } - - /** - * Set the logged on/validated status for the session - * - * @param loggedOn boolean - */ - public final void setLoggedOn(boolean loggedOn) - { - m_loggedOn = loggedOn; - } - - /** - * Set the process id - * - * @param id int - */ - public final void setProcessId(int id) - { - m_processId = id; - } - - /** - * Set the protocol name - * - * @param name String - */ - public final void setProtocolName(String name) - { - m_protocol = name; - } - - /** - * Set the remote client name - * - * @param name String - */ - public final void setRemoteName(String name) - { - m_remoteName = name; - } - - /** - * Set the session id for this session. - * - * @param id int - */ - public final void setSessionId(int id) - { - m_sessId = id; - } - - /** - * Set the unique session id - * - * @param unid String - */ - public final void setUniqueId(String unid) - { - m_uniqueId = unid; - } - - /** - * Set the shutdown flag - * - * @param flg boolean - */ - protected final void setShutdown(boolean flg) - { - m_shutdown = flg; - } - - /** - * Close the network session - */ - public void closeSession() - { - // Release any dynamic shares owned by this session - - if ( hasDynamicShares()) { - - // Close the dynamic shares - - getServer().getShareMapper().deleteShares(this); - } - } - - /** - * Create a read transaction, if not already active - * - * @param transService TransactionService - * @return boolean - * @exception AlfrescoRuntimeException - */ - public final boolean beginReadTransaction( TransactionService transService) - throws AlfrescoRuntimeException - { - return beginTransaction(transService, true); - } - - /** - * Create a write transaction, if not already active - * - * @param transService TransactionService - * @return boolean - * @exception AlfrescoRuntimeException - */ - public final boolean beginWriteTransaction( TransactionService transService) - throws AlfrescoRuntimeException - { - return beginTransaction(transService, false); - } - - /** - * Create and start a transaction, if not already active - * - * @param transService TransactionService - * @param readOnly boolean - * @return boolean - * @exception AlfrescoRuntimeException - */ - private final boolean beginTransaction(TransactionService transService, boolean readOnly) - throws AlfrescoRuntimeException - { - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "Begin transaction readOnly=" + readOnly); - - boolean created = false; - - // Get the filesystem transaction - - FilesysTransaction filesysTx = m_tx.get(); - if ( filesysTx == null) - { - filesysTx = new FilesysTransaction(); - m_tx.set( filesysTx); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Created FilesysTransaction"); - } - - // 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(); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Rolled back existing transaction"); - } - } - 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(); - m_transConvCount++; - } - catch ( Throwable ex) - { - ex.printStackTrace(); -// throw new AlfrescoRuntimeException("Failed to commit read-only transaction, " + ex.getMessage()); - } - finally - { - // Clear the active transaction - - filesysTx.clearTransaction(); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Cleared existing transaction (read/write)"); - } - } - } - - // Create the transaction - - if ( filesysTx.hasTransaction() == false) - { - try - { - // Create the transaction - - UserTransaction userTrans = null; - - if ( AlfrescoTransactionSupport.getTransactionId() != null) { - - // Create a non-propagating transaction as there is an active transaction - - userTrans = transService.getNonPropagatingUserTransaction(readOnly); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("%%%%% Transaction active id=" + AlfrescoTransactionSupport.getTransactionId() + ", started=" + AlfrescoTransactionSupport.getTransactionStartTime()); - } - else { - - // Create a normal transaction - - userTrans = transService.getUserTransaction(readOnly); - } - - // Start the transaction - - userTrans.begin(); - - created = true; - - // Store the transaction - - filesysTx.setTransaction( userTrans, readOnly); - m_transCount++; - - // DEBUG - - if ( logger.isDebugEnabled()) { - logger.debug("Created transaction readOnly=" + readOnly + ", tx=" + userTrans + ", txSts=" + userTrans.getStatus()); - SpringAwareUserTransaction springTx = (SpringAwareUserTransaction) userTrans; - logger.debug(" Tx details readOnly=" + springTx.isReadOnly() + ", txStatus=" + springTx.getStatus() + ",id=" + AlfrescoTransactionSupport.getTransactionId()); - } - } - catch (Exception ex) - { - throw new AlfrescoRuntimeException("Failed to create transaction, " + ex.getMessage()); - } - } - - return created; - } - - /** - * End a transaction by either committing or rolling back - * - * @exception AlfrescoRuntimeException - */ - public final void endTransaction() - throws AlfrescoRuntimeException - { - // Get the filesystem transaction - - FilesysTransaction filesysTx = m_tx.get(); - - // Check if there is an active transaction - - if ( filesysTx != null && filesysTx.hasTransaction()) - { - // Get the active transaction - - UserTransaction tx = filesysTx.getTransaction(); - - try - { - // Commit or rollback the transaction - - if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK || - tx.getStatus() == Status.STATUS_ROLLEDBACK || - tx.getStatus() == Status.STATUS_ROLLING_BACK) - { - // Transaction is marked for rollback - - tx.rollback(); - } - else - { - // Commit the transaction - - tx.commit(); - } - } - catch ( Exception ex) - { - ex.printStackTrace(); -// throw new AlfrescoRuntimeException("Failed to end transaction", ex); - } - finally - { - // Clear the current transaction - - filesysTx.clearTransaction(); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Cleared existing transaction (end)"); - } - } - - } - /** - * Determine if the session has an active transaction - * - * @return boolean - */ - public final boolean hasUserTransaction() - { - // Get the filesystem transaction - - FilesysTransaction filesysTx = m_tx.get(); - if ( filesysTx != null) - return filesysTx.hasTransaction(); - return false; - } - - /** - * Get the active transaction and clear the stored transaction - * - * @return UserTransaction - */ - public final UserTransaction getUserTransaction() - { - // Get the filesystem transaction - - UserTransaction userTrans = null; - FilesysTransaction filesysTx = m_tx.get(); - - if ( filesysTx != null) - { - userTrans = filesysTx.getTransaction(); - filesysTx.clearTransaction(); - } - - return userTrans; - } -} diff --git a/source/java/org/alfresco/filesys/server/SrvSessionList.java b/source/java/org/alfresco/filesys/server/SrvSessionList.java deleted file mode 100644 index d89e75ca4c..0000000000 --- a/source/java/org/alfresco/filesys/server/SrvSessionList.java +++ /dev/null @@ -1,140 +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.server; - -import java.util.Enumeration; -import java.util.Hashtable; - -/** - * Server Session List Class - */ -public class SrvSessionList -{ - - // Session list - - private Hashtable m_sessions; - - /** - * Class constructor - */ - public SrvSessionList() - { - m_sessions = new Hashtable(); - } - - /** - * 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 SrvSession - */ - public final void addSession(SrvSession sess) - { - m_sessions.put(sess.getSessionId(), sess); - } - - /** - * Find the session using the unique session id - * - * @param id int - * @return SrvSession - */ - public final SrvSession findSession(int id) - { - return findSession(id); - } - - /** - * Find the session using the unique session id - * - * @param id Integer - * @return SrvSession - */ - public final SrvSession findSession(Integer id) - { - return m_sessions.get(id); - } - - /** - * Remove a session from the list - * - * @param id int - * @return SrvSession - */ - public final SrvSession removeSession(int id) - { - return removeSession(new Integer(id)); - } - - /** - * Remove a session from the list - * - * @param sess SrvSession - * @return SrvSession - */ - public final SrvSession removeSession(SrvSession sess) - { - return removeSession(sess.getSessionId()); - } - - /** - * Remove a session from the list - * - * @param id Integer - * @return SrvSession - */ - public final SrvSession removeSession(Integer id) - { - - // Find the required session - - SrvSession 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(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/AuthContext.java b/source/java/org/alfresco/filesys/server/auth/AuthContext.java deleted file mode 100644 index a898268c9b..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/AuthContext.java +++ /dev/null @@ -1,37 +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.server.auth; - -/** - * CIFS Authentication Context Class - * - *

Holds authentication specific information for the negotiate/session setup phase of a new CIFS session. - * - * @author gkspencer - */ -public class AuthContext -{ - -} diff --git a/source/java/org/alfresco/filesys/server/auth/AuthenticatorException.java b/source/java/org/alfresco/filesys/server/auth/AuthenticatorException.java deleted file mode 100644 index fba4d07096..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/AuthenticatorException.java +++ /dev/null @@ -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.server.auth; - -/** - * Authenticator Exception Class - * - * @author gkspencer - */ -public class AuthenticatorException extends Exception -{ - private static final long serialVersionUID = 7816213724352083486L; - - /** - * Default constructor. - */ - public AuthenticatorException() - { - super(); - } - - /** - * Class constructor. - * - * @param s String - */ - public AuthenticatorException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java b/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java deleted file mode 100644 index 624a44c38d..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/CifsAuthenticator.java +++ /dev/null @@ -1,1048 +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.server.auth; - -import java.net.InetAddress; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import javax.transaction.UserTransaction; - -import net.sf.acegisecurity.Authentication; - -import org.alfresco.config.ConfigElement; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.passthru.DomainMapping; -import org.alfresco.filesys.server.auth.passthru.RangeDomainMapping; -import org.alfresco.filesys.server.auth.passthru.SubnetDomainMapping; -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.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.DiskSharedDevice; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.smb.Capability; -import org.alfresco.filesys.smb.Dialect; -import org.alfresco.filesys.smb.DialectSelector; -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.SecurityMode; -import org.alfresco.filesys.smb.server.VirtualCircuit; -import org.alfresco.filesys.smb.server.repo.ContentContext; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; -import org.alfresco.filesys.util.IPAddress; -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 Class - * - *

- * An authenticator is used by the CIFS server to authenticate users when in user level access mode - * and authenticate requests to connect to a share when in share level access. - */ -public abstract class CifsAuthenticator -{ - // Logging - - protected static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth"); - - // Encryption algorithm types - - public static final int LANMAN = PasswordEncryptor.LANMAN; - public static final int NTLM1 = PasswordEncryptor.NTLM1; - public static final int NTLM2 = PasswordEncryptor.NTLM2; - - // Authentication status values - - public static final int AUTH_ALLOW = 0; - public static final int AUTH_GUEST = 0x10000000; - public static final int AUTH_DISALLOW = -1; - public static final int AUTH_BADPASSWORD = -2; - public static final int AUTH_BADUSER = -3; - - // Share access permissions, returned by authenticateShareConnect() - - public static final int NoAccess = 0; - public static final int ReadOnly = 1; - public static final int Writeable = 2; - - // Standard encrypted password and challenge length - - public static final int STANDARD_PASSWORD_LEN = 24; - public static final int STANDARD_CHALLENGE_LEN = 8; - - // Default guest user name - - protected static final String GUEST_USERNAME = "guest"; - - // Default SMB dialects to enable - - private DialectSelector m_dialects; - - // Security mode flags - - private int m_securityMode = SecurityMode.UserMode + SecurityMode.EncryptedPasswords; - - // Password encryption algorithms - - private PasswordEncryptor m_encryptor = new PasswordEncryptor(); - - // Flag to enable/disable the guest account, and control mapping of unknown users to the guest account - - private boolean m_allowGuest; - private boolean m_mapToGuest; - - // Default guest user name - - private String m_guestUserName = GUEST_USERNAME; - - // Random number generator used to generate challenge keys - - protected Random m_random = new Random(System.currentTimeMillis()); - - // Server configuration - - protected ServerConfiguration m_config; - - // Authentication component, used to access internal authentication functions - - protected AuthenticationComponent m_authComponent; - - // MD4 hash decoder - - protected MD4PasswordEncoder m_md4Encoder = new MD4PasswordEncoderImpl(); - - // Various services required to get user information - - protected NodeService m_nodeService; - protected PersonService m_personService; - protected TransactionService m_transactionService; - protected AuthenticationService m_authenticationService; - - /** - * Authenticate a connection to a share. - * - * @param client User/client details from the tree connect request. - * @param share Shared device the client wants to connect to. - * @param pwd Share password. - * @param sess Server session. - * @return int Granted file permission level or disallow status if negative. See the - * FilePermission class. - */ - public int authenticateShareConnect(ClientInfo client, SharedDevice share, String sharePwd, SrvSession sess) - { - // Allow write access - // - // Main authentication is handled by authenticateUser() - - return CifsAuthenticator.Writeable; - } - - /** - * Authenticate a user. A user may be granted full access, guest access or no access. - * - * @param client User/client details from the session setup request. - * @param sess Server session - * @param alg Encryption algorithm - * @return int Access level or disallow status. - */ - public int authenticateUser(ClientInfo client, SrvSession sess, int alg) - { - return CifsAuthenticator.AUTH_DISALLOW; - } - - /** - * Initialize the authenticator - * - * @param config ServerConfiguration - * @param params ConfigElement - * @exception InvalidConfigurationException - */ - public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException - { - // Save the server configuration so we can access the authentication component - - m_config = config; - - // Check that the required authentication classes are available - - m_authComponent = m_config.getAuthenticationComponent(); - - if ( m_authComponent == null) - throw new InvalidConfigurationException("Authentication component not available"); - - // Allocate the SMB dialect selector, and initialize using the default list of dialects - - m_dialects = new DialectSelector(); - - m_dialects.AddDialect(Dialect.DOSLanMan1); - m_dialects.AddDialect(Dialect.DOSLanMan2); - m_dialects.AddDialect(Dialect.LanMan1); - m_dialects.AddDialect(Dialect.LanMan2); - m_dialects.AddDialect(Dialect.LanMan2_1); - m_dialects.AddDialect(Dialect.NT); - - // Get hold of various services - - m_nodeService = config.getNodeService(); - m_personService = config.getPersonService(); - m_transactionService = config.getTransactionService(); - m_authenticationService = config.getAuthenticationService(); - - // Set the guest user name - - setGuestUserName( m_authComponent.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; - } - - /** - * Encrypt the plain text password with the specified encryption key using the specified - * encryption algorithm. - * - * @param plainPwd String - * @param encryptKey byte[] - * @param alg int - * @param userName String - * @param domain String - * @return byte[] - */ - protected final byte[] generateEncryptedPassword(String plainPwd, byte[] encryptKey, int alg, String userName, String domain) - { - - // Use the password encryptor - - byte[] encPwd = null; - - try - { - // Encrypt the password - - encPwd = m_encryptor.generateEncryptedPassword(plainPwd, encryptKey, alg, userName, domain); - } - catch (NoSuchAlgorithmException ex) - { - } - catch (InvalidKeyException ex) - { - } - - // Return the encrypted password - - return encPwd; - } - - /** - * Return an authentication context for the new session - * - * @return AuthContext - */ - public AuthContext getAuthContext( SMBSrvSession sess) - { - AuthContext authCtx = null; - - if ( sess.hasAuthenticationContext() && sess.getAuthenticationContext() instanceof NTLanManAuthContext) - { - // Use the existing authentication context - - authCtx = (NTLanManAuthContext) sess.getAuthenticationContext(); - } - else - { - // Create a new authentication context for the session - - authCtx = new NTLanManAuthContext(); - sess.setAuthenticationContext( authCtx); - } - - // Return the authentication context - - return authCtx; - } - - /** - * Return the enabled SMB dialects that the server will use when negotiating sessions. - * - * @return DialectSelector - */ - public final DialectSelector getEnabledDialects() - { - return m_dialects; - } - - /** - * Return the security mode flags - * - * @return int - */ - public final int getSecurityMode() - { - return m_securityMode; - } - - /** - * Generate the CIFS negotiate response packet, the authenticator should add authentication specific fields - * to the response. - * - * @param sess SMBSrvSession - * @param respPkt SMBSrvPacket - * @param extendedSecurity boolean - * @exception AuthenticatorException - */ - public void generateNegotiateResponse(SMBSrvSession sess, SMBSrvPacket respPkt, boolean extendedSecurity) - throws AuthenticatorException - { - // Pack the negotiate response for NT/LanMan challenge/response authentication - - NTLanManAuthContext authCtx = (NTLanManAuthContext) getAuthContext( sess); - if ( authCtx == null) - throw new AuthenticatorException("Failed to get authentication context"); - - // Encryption key and primary domain string should be returned in the byte area - - int pos = respPkt.getByteOffset(); - byte[] buf = respPkt.getBuffer(); - - if ( authCtx.getChallenge() == null) - { - - // Return a dummy encryption key - - for (int i = 0; i < 8; i++) - buf[pos++] = 0; - } - else - { - - // Store the encryption key - - byte[] key = authCtx.getChallenge(); - for (int i = 0; i < key.length; i++) - buf[pos++] = key[i]; - } - - // Pack the local domain name - - String domain = sess.getServer().getConfiguration().getDomainName(); - if (domain != null) - pos = DataPacker.putString(domain, buf, pos, true, true); - - // Pack the local server name - - pos = DataPacker.putString( sess.getServer().getServerName(), buf, pos, true, true); - - // Set the packet length - - respPkt.setByteCount(pos - respPkt.getByteOffset()); - } - - /** - * Process the CIFS session setup request packet and build the session setup response - * - * @param sess SMBSrvSession - * @param reqPkt SMBSrvPacket - * @param respPkt SMBSrvPacket - * @exception SMBSrvException - */ - public void processSessionSetup(SMBSrvSession sess, SMBSrvPacket reqPkt, SMBSrvPacket respPkt) - throws SMBSrvException - { - - // Check that the received packet looks like a valid NT session setup andX request - - if (reqPkt.checkPacketIsValid(13, 0) == false) - { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); - } - - // Extract the session details - - int maxBufSize = reqPkt.getParameter(2); - int maxMpx = reqPkt.getParameter(3); - int vcNum = reqPkt.getParameter(4); - int ascPwdLen = reqPkt.getParameter(7); - int uniPwdLen = reqPkt.getParameter(8); - int capabs = reqPkt.getParameterLong(11); - - // Extract the client details from the session setup request - - byte[] buf = reqPkt.getBuffer(); - - // Determine if ASCII or unicode strings are being used - - boolean isUni = reqPkt.isUnicode(); - - // Extract the password strings - - byte[] ascPwd = reqPkt.unpackBytes(ascPwdLen); - byte[] uniPwd = reqPkt.unpackBytes(uniPwdLen); - - // Extract the user name string - - String user = reqPkt.unpackString(isUni); - - if (user == null) - { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); - } - - // Extract the clients primary domain name string - - String domain = ""; - - if (reqPkt.hasMoreData()) - { - - // Extract the callers domain name - - domain = reqPkt.unpackString(isUni); - - if (domain == null) - { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); - } - } - - // Extract the clients native operating system - - String clientOS = ""; - - if (reqPkt.hasMoreData()) - { - - // Extract the callers operating system name - - clientOS = reqPkt.unpackString(isUni); - - if (clientOS == null) - { - throw new SMBSrvException(SMBStatus.NTInvalidParameter, SMBStatus.ErrSrv, SMBStatus.SRVNonSpecificError); - } - } - - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - { - logger.debug("NT Session setup from user=" + user + ", password=" - + (uniPwd != null ? HexDump.hexString(uniPwd) : "none") + ", ANSIpwd=" - + (ascPwd != null ? HexDump.hexString(ascPwd) : "none") + ", domain=" + domain + ", os=" + clientOS - + ", VC=" + vcNum + ", maxBuf=" + maxBufSize + ", maxMpx=" + maxMpx - + ", authCtx=" + sess.getAuthenticationContext()); - logger.debug(" MID=" + reqPkt.getMultiplexId() + ", UID=" + reqPkt.getUserId() + ", PID=" - + reqPkt.getProcessId()); - } - - // Store the client maximum buffer size, maximum multiplexed requests count and client - // capability flags - - sess.setClientMaximumBufferSize(maxBufSize != 0 ? maxBufSize : SMBSrvSession.DefaultBufferSize); - sess.setClientMaximumMultiplex(maxMpx); - sess.setClientCapabilities(capabs); - - // Create the client information and store in the session - - ClientInfo client = new ClientInfo(user, uniPwd); - client.setANSIPassword(ascPwd); - client.setDomain(domain); - client.setOperatingSystem(clientOS); - - if (sess.hasRemoteAddress()) - client.setClientAddress(sess.getRemoteAddress().getHostAddress()); - - // Check if this is a null session logon - - if (user.length() == 0 && uniPwdLen == 0 && ascPwdLen <= 1) - client.setLogonType(ClientInfo.LogonNull); - - // Authenticate the user - - int sts = authenticateUser(client, sess, CifsAuthenticator.NTLM1); - - if (sts > 0 && (sts & CifsAuthenticator.AUTH_GUEST) != 0) - { - - // Guest logon - - client.setGuest( true); - - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("User " + user + ", logged on as guest"); - } - else if (sts != CifsAuthenticator.AUTH_ALLOW) - { - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("User " + user + ", access denied"); - - // Invalid user, reject the session setup request - - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); - } - else - { - // Save the current user token in the client information - - if ( client.isNullSession() == false) - client.setAuthenticationToken( m_authComponent.getCurrentAuthentication()); - else - client.setAuthenticationToken( null); - - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("User " + user + " logged on " + (client != null ? " (type " + client.getLogonTypeString() + ")" : "")); - } - - // Create a virtual circuit and allocate a UID to the new circuit - - VirtualCircuit vc = new VirtualCircuit( vcNum, client); - int uid = sess.addVirtualCircuit( vc); - - if ( uid == VirtualCircuit.InvalidUID) - { - // DEBUG - - if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Failed to allocate UID for virtual circuit, " + vc); - - // Failed to allocate a UID - - throw new SMBSrvException(SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied); - } - else if ( logger.isDebugEnabled() && sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) { - - // DEBUG - - logger.debug("Allocated UID=" + uid + " for VC=" + vc); - } - - // Indicate that the session is logged on - - sess.setLoggedOn(true); - - // Build the session setup response SMB - - respPkt.setParameterCount(3); - respPkt.setParameter(0, 0); // No chained response - respPkt.setParameter(1, 0); // Offset to chained response - respPkt.setParameter(2, client.isGuest() ? 1 : 0); - respPkt.setByteCount(0); - - respPkt.setTreeId(0); - respPkt.setUserId(uid); - - // Set the various flags - - int flags = respPkt.getFlags(); - flags &= ~SMBSrvPacket.FLG_CASELESS; - respPkt.setFlags(flags); - - int flags2 = SMBSrvPacket.FLG2_LONGFILENAMES; - if (isUni) - flags2 += SMBSrvPacket.FLG2_UNICODE; - respPkt.setFlags2(flags2); - - // Pack the OS, dialect and domain name strings. - - int pos = respPkt.getByteOffset(); - buf = respPkt.getBuffer(); - - if (isUni) - pos = DataPacker.wordAlign(pos); - - pos = DataPacker.putString("Java", buf, pos, true, isUni); - pos = DataPacker.putString("Alfresco CIFS Server " + sess.getServer().isVersion(), buf, pos, true, isUni); - pos = DataPacker.putString(sess.getServer().getConfiguration().getDomainName(), buf, pos, true, isUni); - - respPkt.setByteCount(pos - respPkt.getByteOffset()); - } - - /** - * Return the encryption key/challenge length - * - * @return int - */ - public int getEncryptionKeyLength() - { - return STANDARD_CHALLENGE_LEN; - } - - /** - * Return the server capability flags - * - * @return int - */ - public int getServerCapabilities() - { - return Capability.Unicode + Capability.RemoteAPIs + Capability.NTSMBs + Capability.NTFind + - Capability.NTStatus + Capability.LargeFiles + Capability.LargeRead + Capability.LargeWrite; - } - - /** - * Determine if guest access is allowed - * - * @return boolean - */ - public final boolean allowGuest() - { - return m_allowGuest; - } - - /** - * Return the guest user name - * - * @return String - */ - public final String getGuestUserName() - { - return m_guestUserName; - } - - /** - * Determine if unknown users should be mapped to the guest account - * - * @return boolean - */ - public final boolean mapUnknownUserToGuest() - { - return m_mapToGuest; - } - - /** - * Enable/disable the guest account - * - * @param ena Enable the guest account if true, only allow defined user accounts access if false - */ - public final void setAllowGuest(boolean ena) - { - m_allowGuest = ena; - } - - /** - * Set the guest user name - * - * @param guest String - */ - public final void setGuestUserName( String guest) - { - m_guestUserName = guest; - } - - /** - * Enable/disable mapping of unknown users to the guest account - * - * @param ena Enable mapping of unknown users to the guest if true - */ - public final void setMapToGuest( boolean ena) - { - m_mapToGuest = ena; - } - - /** - * Set the security mode flags - * - * @param flg int - */ - protected final void setSecurityMode(int flg) - { - m_securityMode = flg; - } - - /** - * Close the authenticator, perform any cleanup - */ - public void closeAuthenticator() - { - // Override if cleanup required - } - - /** - * Validate a password by encrypting the plain text password using the specified encryption key - * and encryption algorithm. - * - * @param plainPwd String - * @param encryptedPwd String - * @param encryptKey byte[] - * @param alg int - * @param userName String - * @param domain String - * @return boolean - */ - protected final boolean validatePassword(String plainPwd, byte[] encryptedPwd, byte[] encryptKey, int alg, String userName, String domain) - { - - // Generate an encrypted version of the plain text password - - byte[] encPwd = generateEncryptedPassword(plainPwd != null ? plainPwd : "", encryptKey, alg, userName, domain); - - // Compare the generated password with the received password - - if (encPwd != null && encryptedPwd != null && encPwd.length == STANDARD_PASSWORD_LEN - && encryptedPwd.length == STANDARD_PASSWORD_LEN) - { - - // Compare the password arrays - - for (int i = 0; i < STANDARD_PASSWORD_LEN; i++) - if (encPwd[i] != encryptedPwd[i]) - return false; - - // Password is valid - - return true; - } - - // User or password is invalid - - return false; - } - - /** - * Convert the password string to a byte array - * - * @param pwd String - * @return byte[] - */ - - protected final byte[] convertPassword(String pwd) - { - - // Create a padded/truncated 14 character string - - StringBuffer p14str = new StringBuffer(); - p14str.append(pwd); - if (p14str.length() > 14) - p14str.setLength(14); - else - { - while (p14str.length() < 14) - p14str.append((char) 0x00); - } - - // Convert the P14 string to an array of bytes. Allocate the return 16 byte array. - - return p14str.toString().getBytes(); - } - - /** - * Return the password encryptor - * - * @return PasswordEncryptor - */ - protected final PasswordEncryptor getEncryptor() - { - return m_encryptor; - } - - /** - * Return the authentication status as a string - * - * @param sts int - * @return String - */ - protected final String getStatusAsString(int sts) - { - String str = null; - - switch ( sts) - { - case AUTH_ALLOW: - str = "Allow"; - break; - case AUTH_DISALLOW: - str = "Disallow"; - break; - case AUTH_GUEST: - str = "Guest"; - break; - case AUTH_BADPASSWORD: - str = "BadPassword"; - break; - case AUTH_BADUSER: - str = "BadUser"; - break; - } - - return str; - } - - /** - * Logon using the guest user account - * - * @param client ClientInfo - * @param sess SrvSession - */ - protected final void doGuestLogon( ClientInfo client, SrvSession sess) - { - // Get a guest authentication token - - m_authenticationService.authenticateAsGuest(); - Authentication authToken = m_authComponent.getCurrentAuthentication(); - - client.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_config.getDiskInterface(); - DiskDeviceContext diskCtx = new ContentContext(client.getUserName(), "", "", client.getHomeFolder()); - - // Default the filesystem to look like an 80Gb sized disk with 90% free space - - diskCtx.setDiskInformation(new SrvDiskInfo(2560, 64, 512, 2304)); - - // Create a temporary shared device for the users home directory - - 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) - { - // Get the home folder for the user - - UserTransaction tx = m_transactionService.getUserTransaction(); - NodeRef homeSpaceRef = null; - - try - { - tx.begin(); - homeSpaceRef = (NodeRef) m_nodeService.getProperty(m_personService.getPerson(client.getUserName()), - ContentModel.PROP_HOMEFOLDER); - client.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, or create, the person for this user - - UserTransaction tx = m_transactionService.getUserTransaction( false); - String personName = null; - - Authentication curAuth = null; - - try - { - // Run in the system user context - - curAuth = m_authComponent.getCurrentAuthentication(); - m_authComponent.setSystemUserAsCurrentUser(); - - tx.begin(); - - NodeRef userNode = m_personService.getPerson(userName); - if ( userNode != null) - { - // Get the person name and use that as the current user to line up with permission checks - - personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME); - } - - tx.commit(); - } - catch (Throwable ex) - { - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "Error mapping person for user " + userName, 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); - } - } - finally - { - // Restore the original authentication context - - m_authComponent.setCurrentAuthentication( curAuth); - } - - // 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 - - m_authComponent.clearCurrentSecurityContext(); - } - else if ( client.isGuest() == false) - { - // Set the authentication context for the request - - m_authComponent.setCurrentAuthentication( client.getAuthenticationToken()); - } - else - { - // Enable guest access for the request - - m_authComponent.setGuestUserAsCurrentUser(); - } - } - - - /** - * Map a client IP address to a domain - * - * @param clientIP InetAddress - * @return String - */ - protected final String mapClientAddressToDomain( InetAddress clientIP) - { - // Check if there are any domain mappings - - if ( m_config.hasDomainMappings() == false) - return null; - - // convert the client IP address to an integer value - - int clientAddr = IPAddress.asInteger( clientIP); - for ( DomainMapping domainMap : m_config.getDomainMappings()) - { - if ( domainMap.isMemberOfDomain( clientAddr)) - { - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "Mapped client IP " + clientIP + " to domain " + domainMap.getDomain()); - - return domainMap.getDomain(); - } - } - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "Failed to map client IP " + clientIP + " to a domain"); - - // No domain mapping for the client address - - return null; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/ClientInfo.java b/source/java/org/alfresco/filesys/server/auth/ClientInfo.java deleted file mode 100644 index a41becac74..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ClientInfo.java +++ /dev/null @@ -1,633 +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.server.auth; - -import org.alfresco.service.cmr.repository.NodeRef; - -import net.sf.acegisecurity.Authentication; - -/** - * Client Information Class - * - *

The client information class holds the details of a remote user from a session setup or tree - * connect request. - * - * @author GKSpencer - */ -public class ClientInfo -{ - - // Logon types - - public final static int LogonNormal = 0; - public final static int LogonGuest = 1; - public final static int LogonNull = 2; - public final static int LogonAdmin = 3; - - // Logon type strings - - private static final String[] _logonTypStr = { "Normal", "Guest", "Null", "Administrator" }; - - // User name and password - - private String m_user; - private byte[] m_password; - - // ANSI encrypted password - - private byte[] m_ansiPwd; - - // Logon type - - private int m_logonType; - - // User's domain - - private String m_domain; - - // Operating system type - - private String m_opsys; - - // Remote network address - - private String m_ipAddr; - - // PID of the logon process for multi-stage logons - - private int m_pid = -1; - - // 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; - - // Group and user id - - private int m_gid = -1; - private int m_uid = -1; - - // List of groups for this user - - private int[] m_groups; - - // NFS authentication type - - private int m_nfsAuthType = -1; - - /** - * Default constructor - */ - public ClientInfo() - { - setUserName(""); - } - - /** - * Class constructor - * - * @param user User name - * @param pwd Password - */ - public ClientInfo(String user, byte[] pwd) - { - setUserName(user); - setPassword(pwd); - } - - /** - * Get the remote users domain. - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Get the remote operating system - * - * @return String - */ - public final String getOperatingSystem() - { - return m_opsys; - } - - /** - * Get the password. - * - * @return String. - */ - public final byte[] getPassword() - { - return m_password; - } - - /** - * Return the password as a string - * - * @return String - */ - public final String getPasswordAsString() - { - if (m_password != null) - return new String(m_password); - return null; - } - - /** - * Return the password as a character array - * - * @return char[] - */ - public final char[] getPasswordAsCharArray() - { - char[] cpwd = null; - - if (m_password != null) - { - String pwd = new String(m_password); - cpwd = new char[pwd.length()]; - pwd.getChars(0, pwd.length(), cpwd, 0); - } - return cpwd; - } - - /** - * Determine if the client has specified an ANSI password - * - * @return boolean - */ - public final boolean hasANSIPassword() - { - return m_ansiPwd != null ? true : false; - } - - /** - * Return the ANSI encrypted password - * - * @return byte[] - */ - public final byte[] getANSIPassword() - { - return m_ansiPwd; - } - - /** - * Return the ANSI password as a string - * - * @return String - */ - public final String getANSIPasswordAsString() - { - if (m_ansiPwd != null) - return new String(m_ansiPwd); - return null; - } - - /** - * Get the user name. - * - * @return String - */ - public final String getUserName() - { - return m_user; - } - - /** - * Return the logon type - * - * @return int - */ - public final int getLogonType() - { - return m_logonType; - } - - /** - * Return the logon type as a string - * - * @return String - */ - public final String getLogonTypeString() - { - return _logonTypStr[m_logonType]; - } - - /** - * Determine if the user is logged on as a guest - * - * @return boolean - */ - public final boolean isGuest() - { - return m_logonType == LogonGuest ? true : false; - } - - /** - * Determine if the session is a null session - * - * @return boolean - */ - public final boolean isNullSession() - { - return m_logonType == LogonNull ? true : false; - } - - /** - * Determine if the user if logged on as an administrator - * - * @return boolean - */ - public final boolean isAdministrator() - { - return m_logonType == LogonAdmin ? true : false; - } - - /** - * Determine if the client network address has been set - * - * @return boolean - */ - public final boolean hasClientAddress() - { - return m_ipAddr != null ? true : false; - } - - /** - * Return the client network address - * - * @return String - */ - public final String getClientAddress() - { - return m_ipAddr; - } - - /** - * 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; - } - - /** - * Get the group id - * - * @return int - */ - public final int getGid() - { - return m_gid; - } - - /** - * Return the user id - * - * @return int - */ - public final int getUid() - { - return m_uid; - } - - /** - * Determine if the client has additional groups - * - * @return boolean - */ - public final boolean hasGroupsList() - { - return m_groups != null ? true : false; - } - - /** - * Return the additional groups list - * - * @return int[] - */ - public final int[] getGroupsList() - { - return m_groups; - } - - /** - * Return the NFS authentication type - * - * @return int - */ - public final int getNFSAuthenticationType() - { - return m_nfsAuthType; - } - - /** - * Return the process id - * - * @return int - */ - public final int getProcessId() - { - return m_pid; - } - - /** - * Set the process id - * - * @param pid int - */ - public final void setProcessId( int pid) - { - m_pid = pid; - } - - /** - * Set the remote users domain - * - * @param domain Remote users domain - */ - public final void setDomain(String domain) - { - m_domain = domain; - } - - /** - * Set the remote users operating system type. - * - * @param opsys Remote operating system - */ - public final void setOperatingSystem(String opsys) - { - m_opsys = opsys; - } - - /** - * Set the password. - * - * @param pwd byte[] - */ - public final void setPassword(byte[] pwd) - { - m_password = pwd; - } - - /** - * Set the ANSI encrypted password - * - * @param pwd byte[] - */ - public final void setANSIPassword(byte[] pwd) - { - m_ansiPwd = pwd; - } - - /** - * Set the password - * - * @param pwd Password string. - */ - public final void setPassword(String pwd) - { - if (pwd != null) - m_password = pwd.getBytes(); - else - m_password = null; - } - - /** - * Set the user name - * - * @param user User name string. - */ - public final void setUserName(String user) - { - m_user = user; - } - - /** - * Set the logon type - * - * @param logonType int - */ - public final void setLogonType(int logonType) - { - m_logonType = logonType; - } - - /** - * Set the guest logon flag - * - * @param guest boolean - */ - public final void setGuest(boolean guest) - { - setLogonType(guest == true ? LogonGuest : LogonNormal); - } - - /** - * Set the client network address - * - * @param addr String - */ - public final void setClientAddress(String addr) - { - m_ipAddr = addr; - } - - /** - * 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; - } - - /** - * Set the group id - * - * @param gid int - */ - public final void setGid(int gid) - { - m_gid = gid; - } - - /** - * Set the user id - * - * @param uid int - */ - public final void setUid(int uid) - { - m_uid = uid; - } - - /** - * Set the groups list - * - * @param groups int[] - */ - public final void setGroupsList(int[] groups) - { - m_groups = groups; - } - - /** - * Set the NFS authentication type - * - * @param type int - */ - public final void setNFSAuthenticationType(int type) - { - m_nfsAuthType = type; - } - - /** - * Display the client information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(getUserName()); - str.append(":"); - str.append(getPassword()); - str.append(","); - str.append(getDomain()); - str.append(","); - str.append(getOperatingSystem()); - - if (hasClientAddress()) - { - str.append(","); - str.append(getClientAddress()); - } - - if ( hasAuthenticationToken()) - { - str.append(",token="); - str.append(getAuthenticationToken()); - } - - if ( hasAuthenticationTicket()) - { - str.append(",ticket="); - str.append(getAuthenticationTicket()); - } - - if (isGuest()) - str.append(",Guest"); - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/InvalidUserException.java b/source/java/org/alfresco/filesys/server/auth/InvalidUserException.java deleted file mode 100644 index 2d7b197ad3..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/InvalidUserException.java +++ /dev/null @@ -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.server.auth; - -/** - * Invalid User Exception Class - */ -public class InvalidUserException extends Exception -{ - private static final long serialVersionUID = 3833743295984645425L; - - /** - * Default constructor. - */ - public InvalidUserException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public InvalidUserException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/NTLanManAuthContext.java b/source/java/org/alfresco/filesys/server/auth/NTLanManAuthContext.java deleted file mode 100644 index 00ab5c630e..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/NTLanManAuthContext.java +++ /dev/null @@ -1,96 +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.server.auth; - -import java.util.Random; - -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; - -/** - * NTLM1/LanMan CIFS Authentication Context Class - * - *

Holds the challenge sent to the client during the negotiate phase that is used to verify the hashed password - * in the session setup phase. - * - * @author gkspencer - */ -public class NTLanManAuthContext extends AuthContext -{ - // Random number generator used to generate challenge - - private static Random m_random = new Random(System.currentTimeMillis()); - - // Challenge sent to client - - private byte[] m_challenge; - - /** - * Class constructor - */ - public NTLanManAuthContext() - { - // Generate a new challenge key, pack the key and return - - m_challenge = new byte[8]; - DataPacker.putIntelLong(m_random.nextLong(), m_challenge, 0); - } - - /** - * Class constructor - * - * @param challenge byte[] - */ - public NTLanManAuthContext( byte[] challenge) - { - m_challenge = challenge; - } - - /** - * Get the challenge - * - * return byte[] - */ - public final byte[] getChallenge() - { - return m_challenge; - } - - /** - * Return the CIFS authentication context as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[NTLM,Challenge="); - str.append(HexDump.hexString(m_challenge)); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/PasswordEncryptor.java b/source/java/org/alfresco/filesys/server/auth/PasswordEncryptor.java deleted file mode 100644 index aa1ab15f66..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/PasswordEncryptor.java +++ /dev/null @@ -1,513 +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.server.auth; - -import java.io.UnsupportedEncodingException; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.Mac; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.SecretKeySpec; - -/** - * Password Encryptor Class - * - *

Generates LanMan and NTLMv1 encrypted passwords from the plain text password and challenge key. - * - * @author GKSpencer - */ -public class PasswordEncryptor -{ - - // Encryption algorithm types - - public static final int LANMAN = 0; - public static final int NTLM1 = 1; - public static final int NTLM2 = 2; - public static final int MD4 = 3; - - // Encrpytion algorithm names - - private final static String[] _algNames = { "LanMan", "NTLMv1", "NTLMv2", "MD4" }; - - /** - * Default constructor - */ - public PasswordEncryptor() - { - } - - /** - * Check if the required algorithms are available - * - * @return boolean - */ - public static final boolean checkEncryptionAlgorithms() - { - - boolean algOK = false; - - try - { - - // Check if MD4 is available - - MessageDigest.getInstance("MD4"); - - // Check if DES is available - - Cipher.getInstance("DES"); - - // Check if HMAC-MD5 is available - - Mac.getInstance("HMACMD5"); - - // Indicate required algorithms are available - - algOK = true; - } - catch (NoSuchAlgorithmException ex) - { - } - catch (NoSuchPaddingException ex) - { - } - - // Return the encryption algorithm status - - return algOK; - } - - /** - * Encrypt the plain text password with the specified encryption key using the specified - * encryption algorithm. - * - * @param plainPwd Plaintext password string - * @param encryptKey byte[] Encryption key - * @param alg int Encryption algorithm - * @param userName String - * @param domain String - * @return byte[] Encrypted password - * @exception NoSuchAlgorithmException If a required encryption algorithm is not available - * @exception InvalidKeyException Key is invalid - */ - public byte[] generateEncryptedPassword(String plainPwd, byte[] encryptKey, int alg, String userName, String domain) - throws NoSuchAlgorithmException, InvalidKeyException - { - // Get the password - - String pwd = plainPwd; - if (pwd == null) - pwd = ""; - - // Determine the encryption algorithm - - byte[] encPwd = null; - MessageDigest md4 = null; - int len = 0; - byte[] pwdBytes = null; - - switch (alg) - { - - // LanMan DES encryption - - case LANMAN: - encPwd = P24(pwd, encryptKey); - break; - - // NTLM v1 encryption - - case NTLM1: - - // Create the MD4 hash - - md4 = MessageDigest.getInstance("MD4"); - - try { - pwdBytes = pwd.getBytes("UnicodeLittleUnmarked"); - } - catch (UnsupportedEncodingException ex) { - } - - md4.update(pwdBytes); - byte[] p21 = new byte[21]; - System.arraycopy(md4.digest(), 0, p21, 0, 16); - - // Now use the LM encryption - - encPwd = P24(p21,encryptKey); - break; - - // NTLM v2 encryption - - case NTLM2: - - // Get the MD4 hash of the plaintext password - - byte[] md4Hash = generateEncryptedPassword( plainPwd, encryptKey, MD4, null, null); - - // HMAC-MD5 the username + domain string using the MD4 hash as the key - - Mac hmacMd5 = Mac.getInstance("HMACMD5"); - SecretKeySpec key = new SecretKeySpec( md4Hash, 0, md4Hash.length, "MD5"); - - hmacMd5.init(key); - - // Build the username + domain string and convert to bytes - - StringBuilder str = new StringBuilder(); - - str.append( userName.toUpperCase()); - str.append( domain.toUpperCase()); - - byte[] dataByts = null; - - try - { - // Convert the string to a byte array - - String dataStr = str.toString(); - dataByts = dataStr.getBytes("UnicodeLittleUnmarked"); - } - catch ( UnsupportedEncodingException ex) - { - } - - // Encrypt the username+domain bytes to generate the NTLMv2 hash - - encPwd = hmacMd5.doFinal( dataByts); - break; - - // MD4 encryption - - case MD4: - - // Create the MD4 hash - - md4 = MessageDigest.getInstance("MD4"); - len = pwd.length(); - pwdBytes = new byte[len * 2]; - - for (int i = 0; i < len; i++) - { - char ch = pwd.charAt(i); - pwdBytes[i * 2] = (byte) ch; - pwdBytes[i * 2 + 1] = (byte) ((ch >> 8) & 0xFF); - } - - md4.update(pwdBytes); - encPwd = new byte[16]; - System.arraycopy(md4.digest(), 0, encPwd, 0, 16); - break; - } - - // Return the encrypted password - - return encPwd; - } - - /** - * P16 encryption - * - * @param pwd java.lang.String - * @param s8 byte[] - * @return byte[] - * @exception NoSuchAlgorithmException If a required encryption algorithm is not available - */ - public final byte[] P16(String pwd, byte[] s8) throws NoSuchAlgorithmException - { - - // Make a 14 byte string using the password string. Truncate the - // password or pad with nulls to 14 characters. - - StringBuffer p14str = new StringBuffer(); - p14str.append(pwd.toUpperCase()); - if (p14str.length() > 14) - p14str.setLength(14); - - while (p14str.length() < 14) - p14str.append((char) 0x00); - - // Convert the P14 string to an array of bytes. Allocate a 21 byte buffer as the result is usually passed - // through the P24() method - - byte[] p14 = p14str.toString().getBytes(); - byte[] p16 = new byte[21]; - - try - { - - // DES encrypt the password bytes using the challenge key - - Cipher des = Cipher.getInstance("DES"); - - // Set the encryption seed using the first 7 bytes of the password string. - // Generate the first 8 bytes of the return value. - - byte[] key = generateKey(p14, 0); - - SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES"); - des.init(Cipher.ENCRYPT_MODE, chKey); - byte[] res = des.doFinal(s8); - System.arraycopy(res, 0, p16, 0, 8); - - // Encrypt the second block - - key = generateKey(p14, 7); - - chKey = new SecretKeySpec(key, 0, key.length, "DES"); - des.init(Cipher.ENCRYPT_MODE, chKey); - res = des.doFinal(s8); - System.arraycopy(res, 0, p16, 8, 8); - } - catch (NoSuchPaddingException ex) - { - p16 = null; - } - catch (IllegalBlockSizeException ex) - { - p16 = null; - } - catch (BadPaddingException ex) - { - p16 = null; - } - catch (InvalidKeyException ex) - { - p16 = null; - } - - // Return the 16 byte encrypted value - - return p16; - } - - /** - * P24 DES encryption - * - * @param pwd java.lang.String - * @param c8 byte[] - * @return byte[] - * @exception NoSuchAlgorithmException If a required encryption algorithm is not available - */ - private final byte[] P24(String pwd, byte[] c8) throws NoSuchAlgorithmException - { - - // Generate the 16 byte encrypted value using the password string and well - // known value. - - byte[] s8 = new String("KGS!@#$%").getBytes(); - byte[] p16 = P16(pwd, s8); - - // Generate the 24 byte encrypted value - - return P24(p16, c8); - } - - /** - * P24 DES encryption - * - * @param p21 Plain password or hashed password bytes - * @param ch Challenge bytes - * @return Encrypted password - * @exception NoSuchAlgorithmException If a required encryption algorithm is not available - */ - private final byte[] P24(byte[] p21, byte[] ch) throws NoSuchAlgorithmException - { - - byte[] enc = null; - - try - { - - // DES encrypt the password bytes using the challenge key - - Cipher des = Cipher.getInstance("DES"); - - // Allocate the output bytes - - enc = new byte[24]; - - // Encrypt the first block - - byte[] key = generateKey(p21, 0); - - SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES"); - des.init(Cipher.ENCRYPT_MODE, chKey); - byte[] res = des.doFinal(ch); - System.arraycopy(res, 0, enc, 0, 8); - - // Encrypt the second block - - key = generateKey(p21, 7); - - chKey = new SecretKeySpec(key, 0, key.length, "DES"); - des.init(Cipher.ENCRYPT_MODE, chKey); - res = des.doFinal(ch); - System.arraycopy(res, 0, enc, 8, 8); - - // Encrypt the last block - - key = generateKey(p21, 14); - - chKey = new SecretKeySpec(key, 0, key.length, "DES"); - des.init(Cipher.ENCRYPT_MODE, chKey); - res = des.doFinal(ch); - System.arraycopy(res, 0, enc, 16, 8); - } - catch (NoSuchPaddingException ex) - { - ex.printStackTrace(); - enc = null; - } - catch (IllegalBlockSizeException ex) - { - ex.printStackTrace(); - enc = null; - } - catch (BadPaddingException ex) - { - ex.printStackTrace(); - enc = null; - } - catch (InvalidKeyException ex) - { - ex.printStackTrace(); - enc = null; - } - - // Return the encrypted password, or null if an error occurred - - return enc; - } - - /** - * Return the encryption algorithm as a string - * - * @param alg int - * @return String - */ - public static String getAlgorithmName(int alg) - { - if (alg >= 0 && alg < _algNames.length) - return _algNames[alg]; - return "Unknown"; - } - - /** - * Make a 7-byte string into a 64 bit/8 byte/longword key. - * - * @param byt byte[] - * @param off int - * @return byte[] - */ - private byte[] generateKey(byte[] byt, int off) - { - - // Allocate the key - - byte[] key = new byte[8]; - - // Make a key from the input string - - key[0] = (byte) (byt[off + 0] >> 1); - key[1] = (byte) (((byt[off + 0] & 0x01) << 6) | ((byt[off + 1] & 0xFF) >> 2)); - key[2] = (byte) (((byt[off + 1] & 0x03) << 5) | ((byt[off + 2] & 0xFF) >> 3)); - key[3] = (byte) (((byt[off + 2] & 0x07) << 4) | ((byt[off + 3] & 0xFF) >> 4)); - key[4] = (byte) (((byt[off + 3] & 0x0F) << 3) | ((byt[off + 4] & 0xFF) >> 5)); - key[5] = (byte) (((byt[off + 4] & 0x1F) << 2) | ((byt[off + 5] & 0xFF) >> 6)); - key[6] = (byte) (((byt[off + 5] & 0x3F) << 1) | ((byt[off + 6] & 0xFF) >> 7)); - key[7] = (byte) (byt[off + 6] & 0x7F); - - for (int i = 0; i < 8; i++) - { - key[i] = (byte) (key[i] << 1); - } - - return key; - } - - /** - * NTLM1 encryption of the MD4 hashed password - * - * @param p21 byte[] - * @param c8 byte[] - * @return byte[] - * @exception NoSuchAlgorithmException - */ - public final byte[] doNTLM1Encryption(byte[] p21, byte[] c8) - throws NoSuchAlgorithmException - { - return P24(p21, c8); - } - - /** - * NTLM2 encryption of the MD4 hashed password - * - * @param md4Hash byte[] - * @param userName String - * @param domain String - * @return byte[] - * @exception NoSuchAlgorithmException - */ - public final byte[] doNTLM2Encryption(byte[] md4Hash, String userName, String domain) - throws NoSuchAlgorithmException, InvalidKeyException - { - // Use the MD4 hashed password as the key for HMAC-MD5 - - Mac hmacMd5 = Mac.getInstance("HMACMD5"); - SecretKeySpec key = new SecretKeySpec(md4Hash, 0, md4Hash.length, "MD5"); - - hmacMd5.init( key); - - // Build the data to be encrypted - - StringBuilder str = new StringBuilder(); - - str.append(userName.toUpperCase()); - str.append(domain); - - String dataStr = str.toString(); - byte[] dataByts = null; - - try - { - dataByts = dataStr.getBytes("UnicodeLittleUnmarked"); - } - catch ( UnsupportedEncodingException ex) - { - } - - // Encrypt the data - - return hmacMd5.doFinal( dataByts); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/ACLParseException.java b/source/java/org/alfresco/filesys/server/auth/acl/ACLParseException.java deleted file mode 100644 index 622d29f06c..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/ACLParseException.java +++ /dev/null @@ -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.server.auth.acl; - -/** - * Access Control Parse Exception Class - */ -public class ACLParseException extends Exception -{ - private static final long serialVersionUID = 3978983284405776688L; - - /** - * Default constructor. - */ - public ACLParseException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public ACLParseException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/AccessControl.java b/source/java/org/alfresco/filesys/server/auth/acl/AccessControl.java deleted file mode 100644 index ca6c86787c..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/AccessControl.java +++ /dev/null @@ -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.server.auth.acl; - -import java.util.StringTokenizer; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - * Access Control Base Class - *

- * Controls access to a shared filesystem. - */ -public abstract class AccessControl -{ - - // Access control type/status - - public final static int NoAccess = 0; - public final static int ReadOnly = 1; - public final static int ReadWrite = 2; - - public final static int MaxLevel = 2; - - // Default access status, indicates that the access conrol did not apply - - public final static int Default = -1; - - // Access type strings - - private final static String[] _accessType = { "None", "Read", "Write" }; - - // Access control name and type - - private String m_name; - private String m_type; - - // Access type - - private int m_access; - - /** - * Class constructor - * - * @param name String - * @param type String - * @param access int - */ - protected AccessControl(String name, String type, int access) - { - setName(name); - setType(type); - - m_access = access; - } - - /** - * Return the access control name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the access control type - * - * @return String - */ - public final String getType() - { - return m_type; - } - - /** - * Return the access control check type - * - * @return int - */ - public final int getAccess() - { - return m_access; - } - - /** - * Return the access control check type as a string - * - * @return String - */ - public final String getAccessString() - { - return _accessType[m_access]; - } - - /** - * Check if the specified session has access to the shared device. - * - * @param sess SrvSession - * @param share SharedDevice - * @param mgr AccessControlManager - * @return int - */ - public abstract int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr); - - /** - * Return the index of a value from a list of valid values, or 01 if not valid - * - * @param val String - * @param list String[] - * @param caseSensitive boolean - * @return int - */ - protected final static int indexFromList(String val, String[] valid, boolean caseSensitive) - { - - // Check if the value is valid - - if (val == null || val.length() == 0) - return -1; - - // Search for the matching value in the valid list - - for (int i = 0; i < valid.length; i++) - { - - // Check the current value in the valid list - - if (caseSensitive) - { - if (valid[i].equals(val)) - return i; - } - else if (valid[i].equalsIgnoreCase(val)) - return i; - } - - // Value does not match any of the valid values - - return -1; - } - - /** - * Create a list of valid strings from a comma delimeted list - * - * @param str String - * @return String[] - */ - protected final static String[] listFromString(String str) - { - - // Check if the string is valid - - if (str == null || str.length() == 0) - return null; - - // Split the comma delimeted string into an array of strings - - StringTokenizer token = new StringTokenizer(str, ","); - int numStrs = token.countTokens(); - if (numStrs == 0) - return null; - - String[] list = new String[numStrs]; - - // Parse the string into a list of strings - - int i = 0; - - while (token.hasMoreTokens()) - list[i++] = token.nextToken(); - - // Return the string list - - return list; - } - - /** - * Set the access control type - * - * @param typ String - */ - protected final void setType(String typ) - { - m_type = typ; - } - - /** - * Set the access control name - * - * @param name String - */ - protected final void setName(String name) - { - m_name = name; - } - - /** - * Return the access control type as a string - * - * @param access int - * @return String - */ - public static final String asAccessString(int access) - { - if (access == Default) - return "Default"; - return _accessType[access]; - } - - /** - * Return the access control as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getType()); - str.append(":"); - str.append(getName()); - str.append(","); - str.append(getAccessString()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlFactory.java b/source/java/org/alfresco/filesys/server/auth/acl/AccessControlFactory.java deleted file mode 100644 index 7abc5054d6..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlFactory.java +++ /dev/null @@ -1,99 +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.server.auth.acl; - -import java.util.Hashtable; - -import org.alfresco.config.ConfigElement; - -/** - * Access Control Factoy Class - *

- * The AccessControlFactory class holds a table of available AccessControlParsers that are used to - * generate AccessControl instances. - *

- * An AccessControlParser has an associated unique type name that is used to call the appropriate - * parser. - */ -public class AccessControlFactory -{ - - // Access control parsers - - private Hashtable m_parsers; - - /** - * Class constructor - */ - public AccessControlFactory() - { - m_parsers = new Hashtable(); - } - - /** - * Create an access control using the specified parameters - * - * @param type String - * @param params ConfigElement - * @return AccessControl - * @exception ACLParseException - * @exception InvalidACLTypeException - */ - public final AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException, - InvalidACLTypeException - { - - // Find the access control parser - - AccessControlParser parser = m_parsers.get(type); - if (parser == null) - throw new InvalidACLTypeException(type); - - // Parse the parameters and create a new AccessControl instance - - return parser.createAccessControl(params); - } - - /** - * Add a parser to the list of available parsers - * - * @param parser AccessControlParser - */ - public final void addParser(AccessControlParser parser) - { - m_parsers.put(parser.getType(), parser); - } - - /** - * Remove a parser from the available parser list - * - * @param type String - * @return AccessControlParser - */ - public final AccessControlParser removeParser(String type) - { - return (AccessControlParser) m_parsers.remove(type); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlList.java b/source/java/org/alfresco/filesys/server/auth/acl/AccessControlList.java deleted file mode 100644 index 76fbc719c3..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlList.java +++ /dev/null @@ -1,166 +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.server.auth.acl; - -import java.util.Vector; - -/** - * Access Control List Class - *

- * Contains a list of access controls for a shared filesystem. - */ -public class AccessControlList -{ - - // Access control list - - private Vector m_list; - - // Default access level applied when rules return a default status - - private int m_defaultAccess = AccessControl.ReadWrite; - - /** - * Create an access control list. - */ - public AccessControlList() - { - m_list = new Vector(); - } - - /** - * Get the default access level - * - * @return int - */ - public final int getDefaultAccessLevel() - { - return m_defaultAccess; - } - - /** - * Set the default access level - * - * @param level int - * @exception InvalidACLTypeException If the access level is invalid - */ - public final void setDefaultAccessLevel(int level) throws InvalidACLTypeException - { - - // Check the default access level - - if (level < AccessControl.NoAccess || level > AccessControl.MaxLevel) - throw new InvalidACLTypeException(); - - // Set the default access level for the access control list - - m_defaultAccess = level; - } - - /** - * Add an access control to the list - * - * @param accCtrl AccessControl - */ - public final void addControl(AccessControl accCtrl) - { - - // Add the access control to the list - - m_list.add(accCtrl); - } - - /** - * Return the specified access control - * - * @param idx int - * @return AccessControl - */ - public final AccessControl getControlAt(int idx) - { - if (idx < 0 || idx >= m_list.size()) - return null; - return m_list.get(idx); - } - - /** - * Return the number of access controls in the list - * - * @return int - */ - public final int numberOfControls() - { - return m_list.size(); - } - - /** - * Remove all access controls from the list - */ - public final void removeAllControls() - { - m_list.removeAllElements(); - } - - /** - * Remove the specified access control from the list. - * - * @param idx int - * @return AccessControl - */ - public final AccessControl removeControl(int idx) - { - if (idx < 0 || idx >= m_list.size()) - return null; - return m_list.remove(idx); - } - - /** - * Return the access control list as a string. - * - * @return java.lang.String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(m_list.size()); - str.append(":"); - - str.append(":"); - str.append(AccessControl.asAccessString(getDefaultAccessLevel())); - str.append(":"); - - for (int i = 0; i < m_list.size(); i++) - { - AccessControl ctrl = m_list.get(i); - str.append(ctrl.toString()); - str.append(","); - } - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlManager.java b/source/java/org/alfresco/filesys/server/auth/acl/AccessControlManager.java deleted file mode 100644 index 81c19ba2c7..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlManager.java +++ /dev/null @@ -1,88 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; - -/** - * Access Control Manager Interface - *

- * Used to control access to shared filesystems. - * - * @author Gary K. Spencer - */ -public interface AccessControlManager -{ - - /** - * Initialize the access control manager - * - * @param config ServerConfiguration - * @param params ConfigElement - */ - public void initialize(ServerConfiguration config, ConfigElement params); - - /** - * Check access to the shared filesystem for the specified session - * - * @param sess SrvSession - * @param share SharedDevice - * @return int - */ - public int checkAccessControl(SrvSession sess, SharedDevice share); - - /** - * Filter a shared device list to remove shares that are not visible or the session does not - * have access to. - * - * @param sess SrvSession - * @param shares SharedDeviceList - * @return SharedDeviceList - */ - public SharedDeviceList filterShareList(SrvSession sess, SharedDeviceList shares); - - /** - * Create an access control - * - * @param type String - * @param params ConfigElement - * @return AccessControl - * @exception ACLParseException - * @exception InvalidACLTypeException - */ - public AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException, - InvalidACLTypeException; - - /** - * Add an access control parser to the list of available access control types. - * - * @param parser AccessControlParser - */ - public void addAccessControlType(AccessControlParser parser); -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlParser.java b/source/java/org/alfresco/filesys/server/auth/acl/AccessControlParser.java deleted file mode 100644 index 202f59f0b6..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/AccessControlParser.java +++ /dev/null @@ -1,143 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; - -/** - * Access Control Parser Class - *

- * Creates an AccessControl instance by parsing a set of name/value parameters. - */ -public abstract class AccessControlParser -{ - - // Constants - // - // Standard parameter names - - public final static String ParameterAccess = "access"; - - // Access control type names - - private final static String[] _accessTypes = { "None", "Read", "Write" }; - - /** - * Return the access control type name that uniquely identifies this type of access control. - * - * @return String - */ - public abstract String getType(); - - /** - * Create an AccessControl instance by parsing the set of name/value parameters - * - * @param params ConfigElement - * @return AccessControl - * @exception ACLParseException - */ - public abstract AccessControl createAccessControl(ConfigElement params) throws ACLParseException; - - /** - * Find the access parameter and parse the value - * - * @param params ConfigElement - * @return int - * @exception ACLParseException - */ - protected final int parseAccessType(ConfigElement params) throws ACLParseException - { - - // Check if the parameter list is valid - - if (params == null) - throw new ACLParseException("Empty parameter list"); - - // Find the access type parameter - - String accessType = params.getAttribute(ParameterAccess); - - if (accessType == null || accessType.length() == 0) - throw new ACLParseException("Required parameter 'access' missing"); - - // Parse the access type value - - return parseAccessTypeString(accessType); - } - - /** - * Parse the access level type and validate - * - * @param accessType String - * @return int - * @exception ACLParseException - */ - public static final int parseAccessTypeString(String accessType) throws ACLParseException - { - - // Check if the access type is valid - - if (accessType == null || accessType.length() == 0) - throw new ACLParseException("Empty access type string"); - - // Parse the access type value - - int access = -1; - - for (int i = 0; i < _accessTypes.length; i++) - { - - // Check if the access type matches the current type - - if (accessType.equalsIgnoreCase(_accessTypes[i])) - access = i; - } - - // Check if we found a valid access type - - if (access == -1) - throw new ACLParseException("Invalid access type, " + accessType); - - // Return the access type - - return access; - } - - /** - * Return the parser details as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getType()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/DefaultAccessControlManager.java b/source/java/org/alfresco/filesys/server/auth/acl/DefaultAccessControlManager.java deleted file mode 100644 index e93d83587d..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/DefaultAccessControlManager.java +++ /dev/null @@ -1,289 +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.server.auth.acl; - -import java.util.Enumeration; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Default Access Control Manager Class - *

- * Default access control manager implementation. - * - * @author Gary K. Spencer - */ -public class DefaultAccessControlManager implements AccessControlManager -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Access control factory - - private AccessControlFactory m_factory; - - // Debug enable flag - - private boolean m_debug; - - /** - * Class constructor - */ - public DefaultAccessControlManager() - { - - // Create the access control factory - - m_factory = new AccessControlFactory(); - } - - /** - * Check if the session has access to the shared device. - * - * @param sess SrvSession - * @param share SharedDevice - * @return int - */ - public int checkAccessControl(SrvSession sess, SharedDevice share) - { - - // Check if the shared device has any access control configured - - if (share.hasAccessControls() == false) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Check access control for " + share.getName() + ", no ACLs"); - - // Allow full access to the share - - return AccessControl.ReadWrite; - } - - // Process the access control list - - AccessControlList acls = share.getAccessControls(); - int access = AccessControl.Default; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Check access control for " + share.getName() + ", ACLs=" + acls.numberOfControls()); - - for (int i = 0; i < acls.numberOfControls(); i++) - { - - // Get the current access control and run - - AccessControl acl = acls.getControlAt(i); - int curAccess = acl.allowsAccess(sess, share, this); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" Check access ACL=" + acl + ", access=" + AccessControl.asAccessString(curAccess)); - - // Update the allowed access - - if (curAccess != AccessControl.Default) - access = curAccess; - } - - // Check if the default access level is still selected, if so then get the default level - // from the - // access control list - - if (access == AccessControl.Default) - { - - // Use the default access level - - access = acls.getDefaultAccessLevel(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Access defaulted=" + AccessControl.asAccessString(access) + ", share=" + share); - } - else if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Access allowed=" + AccessControl.asAccessString(access) + ", share=" + share); - - // Return the access type - - return access; - } - - /** - * Filter the list of shared devices to return a list that contains only the shares that are - * visible or accessible by the session. - * - * @param sess SrvSession - * @param shares SharedDeviceList - * @return SharedDeviceList - */ - public SharedDeviceList filterShareList(SrvSession sess, SharedDeviceList shares) - { - - // Check if the share list is valid or empty - - if (shares == null || shares.numberOfShares() == 0) - return shares; - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Filter share list for " + sess + ", shares=" + shares); - - // For each share in the list check the access, remove any shares that the session does not - // have access to. - - SharedDeviceList filterList = new SharedDeviceList(); - Enumeration enm = shares.enumerateShares(); - - while (enm.hasMoreElements()) - { - - // Get the current share - - SharedDevice share = enm.nextElement(); - - // Check if the share has any access controls - - if (share.hasAccessControls()) - { - - // Check if the session has access to this share - - int access = checkAccessControl(sess, share); - if (access != AccessControl.NoAccess) - filterList.addShare(share); - } - else - { - - // Add the share to the filtered list - - filterList.addShare(share); - } - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Filtered share list " + filterList); - - // Return the filtered share list - - return filterList; - } - - /** - * Initialize the access control manager - * - * @param config ServerConfiguration - * @param params ConfigElement - */ - public void initialize(ServerConfiguration config, ConfigElement params) - { - - // Check if debug output is enabled - - if (params != null && params.getChild("debug") != null) - setDebug(true); - - // Add the default access control types - - addAccessControlType(new UserAccessControlParser()); - addAccessControlType(new ProtocolAccessControlParser()); - addAccessControlType(new DomainAccessControlParser()); - addAccessControlType(new IpAddressAccessControlParser()); - } - - /** - * Create an access control. - * - * @param type String - * @param params ConfigElement - * @return AccessControl - * @throws ACLParseException - * @throws InvalidACLTypeException - */ - public AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException, - InvalidACLTypeException - { - - // Use the access control factory to create the access control instance - - return m_factory.createAccessControl(type, params); - } - - /** - * Add an access control parser to the list of available access control types. - * - * @param parser AccessControlParser - */ - public void addAccessControlType(AccessControlParser parser) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("AccessControlManager Add rule type " + parser.getType()); - - // Add the new access control type to the factory - - m_factory.addParser(parser); - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Enable/disable debug output - * - * @param dbg boolean - */ - public final void setDebug(boolean dbg) - { - m_debug = dbg; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControl.java b/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControl.java deleted file mode 100644 index 5b0510eb1b..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControl.java +++ /dev/null @@ -1,77 +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.server.auth.acl; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - * Domain Name Access Control Class - *

- * Allow/disallow access based on the SMB/CIFS session callers domain name. - */ -public class DomainAccessControl extends AccessControl -{ - - /** - * Class constructor - * - * @param domainName String - * @param type String - * @param access int - */ - protected DomainAccessControl(String domainName, String type, int access) - { - super(domainName, type, access); - } - - /** - * Check if the domain name matches the access control domain name and return the allowed - * access. - * - * @param sess SrvSession - * @param share SharedDevice - * @param mgr AccessControlManager - * @return int - */ - public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr) - { - - // Check if the session has client information - - if (sess.hasClientInformation() == false - || sess instanceof org.alfresco.filesys.smb.server.SMBSrvSession == false) - return Default; - - // Check if the domain name matches the access control name - - ClientInfo cInfo = sess.getClientInformation(); - - if (cInfo.getDomain() != null && cInfo.getDomain().equalsIgnoreCase(getName())) - return getAccess(); - return Default; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControlParser.java b/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControlParser.java deleted file mode 100644 index 35ecaa63b7..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/DomainAccessControlParser.java +++ /dev/null @@ -1,76 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; - -/** - * Domain Name Access Control Parser Class - */ -public class DomainAccessControlParser extends AccessControlParser -{ - - /** - * Default constructor - */ - public DomainAccessControlParser() - { - } - - /** - * Return the parser type - * - * @return String - */ - public String getType() - { - return "domain"; - } - - /** - * Validate the parameters and create a user access control - * - * @param params ConfigElement - * @return AccessControl - * @throws ACLParseException - */ - public AccessControl createAccessControl(ConfigElement params) throws ACLParseException - { - - // Get the access type - - int access = parseAccessType(params); - - // Get the domain name to check for - - String domainName = params.getAttribute("name"); - if (domainName == null || domainName.length() == 0) - throw new ACLParseException("Domain name not specified"); - - // Create the domain access control - - return new DomainAccessControl(domainName, getType(), access); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/InvalidACLTypeException.java b/source/java/org/alfresco/filesys/server/auth/acl/InvalidACLTypeException.java deleted file mode 100644 index 1a2d68909f..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/InvalidACLTypeException.java +++ /dev/null @@ -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.server.auth.acl; - -/** - * Invalid ACL Type Exception Class - */ -public class InvalidACLTypeException extends Exception -{ - private static final long serialVersionUID = 3257844398418310708L; - - /** - * Default constructor. - */ - public InvalidACLTypeException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public InvalidACLTypeException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControl.java b/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControl.java deleted file mode 100644 index 878027dd72..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControl.java +++ /dev/null @@ -1,117 +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.server.auth.acl; - -import java.net.InetAddress; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.util.IPAddress; - -/** - * Ip Address Access Control Class - *

- * Allow/disallow access by checking for a particular TCP/IP address or checking that the address is - * within a specified subnet. - */ -public class IpAddressAccessControl extends AccessControl -{ - - // Subnet and network mask if the address specifies the subnet - - private String m_subnet; - private String m_netMask; - - /** - * Class constructor - * - * @param address String - * @param mask String - * @param type String - * @param access int - */ - protected IpAddressAccessControl(String address, String mask, String type, int access) - { - super(address, type, access); - - // Save the subnet and network mask, if specified - - m_subnet = address; - m_netMask = mask; - - // Change the rule name if a network mask has been specified - - if (m_netMask != null) - setName(m_subnet + "/" + m_netMask); - } - - /** - * Check if the TCP/IP address matches the specifed address or is within the subnet. - * - * @param sess SrvSession - * @param share SharedDevice - * @param mgr AccessControlManager - * @return int - */ - public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr) - { - - // Check if the remote address is set for the session - - InetAddress remoteAddr = sess.getRemoteAddress(); - - if (remoteAddr == null) - return Default; - - // Get the remote address as a numeric IP address string - - String ipAddr = remoteAddr.getHostAddress(); - - // Check if the access control is a single TCP/IP address check - - int sts = Default; - - if (m_netMask == null) - { - - // Check if the TCP/IP address matches the check address - - if (IPAddress.parseNumericAddress(ipAddr) == IPAddress.parseNumericAddress(getName())) - sts = getAccess(); - } - else - { - - // Check if the address is within the subnet range - - if (IPAddress.isInSubnet(ipAddr, m_subnet, m_netMask) == true) - sts = getAccess(); - } - - // Return the access status - - return sts; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControlParser.java b/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControlParser.java deleted file mode 100644 index f5bab22a36..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/IpAddressAccessControlParser.java +++ /dev/null @@ -1,116 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.util.IPAddress; - -/** - * Ip Address Access Control Parser Class - */ -public class IpAddressAccessControlParser extends AccessControlParser -{ - - /** - * Default constructor - */ - public IpAddressAccessControlParser() - { - } - - /** - * Return the parser type - * - * @return String - */ - public String getType() - { - return "address"; - } - - /** - * Validate the parameters and create an address access control - * - * @param params ConfigElement - * @return AccessControl - * @throws ACLParseException - */ - public AccessControl createAccessControl(ConfigElement params) throws ACLParseException - { - - // Get the access type - - int access = parseAccessType(params); - - // Check if the single IP address format has been specified - - String ipAddr = params.getAttribute("ip"); - if (ipAddr != null) - { - - // Validate the parameters - - if (ipAddr.length() == 0 || IPAddress.isNumericAddress(ipAddr) == false) - throw new ACLParseException("Invalid IP address, " + ipAddr); - - if (params.getAttributeCount() != 2) - throw new ACLParseException("Invalid parameter(s) specified for address"); - - // Create a single TCP/IP address access control rule - - return new IpAddressAccessControl(ipAddr, null, getType(), access); - } - - // Check if a subnet address and mask have been specified - - String subnet = params.getAttribute("subnet"); - if (subnet != null) - { - - // Get the network mask parameter - - String netmask = params.getAttribute("mask"); - - // Validate the parameters - - if (subnet.length() == 0 || netmask == null || netmask.length() == 0) - throw new ACLParseException("Invalid subnet/mask parameter"); - - if (IPAddress.isNumericAddress(subnet) == false) - throw new ACLParseException("Invalid subnet parameter, " + subnet); - - if (IPAddress.isNumericAddress(netmask) == false) - throw new ACLParseException("Invalid mask parameter, " + netmask); - - // Create a subnet address access control rule - - return new IpAddressAccessControl(subnet, netmask, getType(), access); - } - - // Invalid parameters - - throw new ACLParseException("Unknown address parameter(s)"); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControl.java b/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControl.java deleted file mode 100644 index 69c7d96283..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControl.java +++ /dev/null @@ -1,126 +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.server.auth.acl; - -import java.util.StringTokenizer; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - * Protocol Access Control Class - *

- * Allow/disallow access to a share based on the protocol type. - */ -public class ProtocolAccessControl extends AccessControl -{ - - // Available protocol type names - - private static final String[] _protoTypes = { "SMB", "CIFS", "NFS", "FTP" }; - - // Parsed list of protocol types - - private String[] m_checkList; - - /** - * Class constructor - * - * @param protList String - * @param type String - * @param access int - */ - protected ProtocolAccessControl(String protList, String type, int access) - { - super(protList, type, access); - - // Parse the protocol list - - m_checkList = listFromString(protList); - } - - /** - * Check if the protocol matches the access control protocol list and return the allowed access. - * - * @param sess SrvSession - * @param share SharedDevice - * @param mgr AccessControlManager - * @return int - */ - public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr) - { - - // Determine the session protocol type - - String sessProto = null; - String sessName = sess.getClass().getName(); - - if (sessName.endsWith(".SMBSrvSession")) - sessProto = "CIFS"; - else if (sessName.endsWith(".FTPSrvSession")) - sessProto = "FTP"; - else if (sessName.endsWith(".NFSSrvSession")) - sessProto = "NFS"; - - // Check if the session protocol type is in the protocols to be checked - - if (sessProto != null && indexFromList(sessProto, m_checkList, false) != -1) - return getAccess(); - return Default; - } - - /** - * Validate the protocol list - * - * @param protList String - * @return boolean - */ - public static final boolean validateProtocolList(String protList) - { - - // Check if the protocol list string is valid - - if (protList == null || protList.length() == 0) - return false; - - // Split the protocol list and validate each protocol name - - StringTokenizer tokens = new StringTokenizer(protList, ","); - - while (tokens.hasMoreTokens()) - { - - // Get the current protocol name and validate - - String name = tokens.nextToken().toUpperCase(); - if (indexFromList(name, _protoTypes, false) == -1) - return false; - } - - // Protocol list is valid - - return true; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControlParser.java b/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControlParser.java deleted file mode 100644 index 451481b04a..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/ProtocolAccessControlParser.java +++ /dev/null @@ -1,80 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; - -/** - * Protocol Access Control Parser Class - */ -public class ProtocolAccessControlParser extends AccessControlParser -{ - /** - * Default constructor - */ - public ProtocolAccessControlParser() - { - } - - /** - * Return the parser type - * - * @return String - */ - public String getType() - { - return "protocol"; - } - - /** - * Validate the parameters and create a user access control - * - * @param params ConfigElement - * @return AccessControl - * @throws ACLParseException - */ - public AccessControl createAccessControl(ConfigElement params) throws ACLParseException - { - - // Get the access type - - int access = parseAccessType(params); - - // Get the list of protocols to check for - - String protos = params.getAttribute("type"); - if (protos == null || protos.length() == 0) - throw new ACLParseException("Protocol type not specified"); - - // Validate the protocol list - - if (ProtocolAccessControl.validateProtocolList(protos) == false) - throw new ACLParseException("Invalid protocol type"); - - // Create the protocol access control - - return new ProtocolAccessControl(protos, getType(), access); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControl.java b/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControl.java deleted file mode 100644 index a3d618cd22..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControl.java +++ /dev/null @@ -1,74 +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.server.auth.acl; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - * User Access Control Class - *

- * Allow/disallow access to a shared device by checking the user name. - */ -public class UserAccessControl extends AccessControl -{ - /** - * Class constructor - * - * @param userName String - * @param type String - * @param access int - */ - protected UserAccessControl(String userName, String type, int access) - { - super(userName, type, access); - } - - /** - * Check if the user name matches the access control user name and return the allowed access. - * - * @param sess SrvSession - * @param share SharedDevice - * @param mgr AccessControlManager - * @return int - */ - public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr) - { - - // Check if the session has client information - - if (sess.hasClientInformation() == false) - return Default; - - // Check if the user name matches the access control name - - ClientInfo cInfo = sess.getClientInformation(); - - if (cInfo.getUserName() != null && cInfo.getUserName().equalsIgnoreCase(getName())) - return getAccess(); - return Default; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControlParser.java b/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControlParser.java deleted file mode 100644 index f38b693aaa..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/acl/UserAccessControlParser.java +++ /dev/null @@ -1,75 +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.server.auth.acl; - -import org.alfresco.config.ConfigElement; - -/** - * User Access Control Parser Class - */ -public class UserAccessControlParser extends AccessControlParser -{ - /** - * Default constructor - */ - public UserAccessControlParser() - { - } - - /** - * Return the parser type - * - * @return String - */ - public String getType() - { - return "user"; - } - - /** - * Validate the parameters and create a user access control - * - * @param params ConfigElement - * @return AccessControl - * @throws ACLParseException - */ - public AccessControl createAccessControl(ConfigElement params) throws ACLParseException - { - - // Get the access type - - int access = parseAccessType(params); - - // Get the user name to check for - - String userName = params.getAttribute("name"); - if (userName == null || userName.length() == 0) - throw new ACLParseException("User name not specified"); - - // Create the user access control - - return new UserAccessControl(userName, getType(), access); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/kerberos/KerberosDetails.java b/source/java/org/alfresco/filesys/server/auth/kerberos/KerberosDetails.java deleted file mode 100644 index e5f55152a5..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/kerberos/KerberosDetails.java +++ /dev/null @@ -1,142 +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.server.auth.kerberos; - -import org.ietf.jgss.GSSName; - -/** - * Kerberos Details Class - * - *

Holds the Kerberos response token and session details about the user. - * - * @author gkspencer - */ -public class KerberosDetails -{ - // Source and target details - - private String m_krbSource; - private String m_krbTarget; - - // Kerberos response token - - private byte[] m_krbResponse; - - /** - * Class constructor - * - * @param source GSSName - * @param target GSSName - * @param response byte[] - */ - public KerberosDetails(GSSName source, GSSName target, byte[] response) - { - m_krbSource = source.toString(); - m_krbTarget = target.toString(); - - m_krbResponse = response; - } - - /** - * Return the context initiator for the Kerberos authentication - * - * @return String - */ - public final String getSourceName() - { - return m_krbSource; - } - - /** - * Return the context acceptor for the Kerberos authentication - * - * @return String - */ - public final String getTargetName() - { - return m_krbTarget; - } - - /** - * Return the Kerberos response token - * - * @return byte[] - */ - public final byte[] getResponseToken() - { - return m_krbResponse; - } - - /** - * Parse the source name to return the user name part only - * - * @return String - */ - public final String getUserName() - { - String userName = m_krbSource; - - if ( m_krbSource != null) - { - int pos = m_krbSource.indexOf( '@'); - if ( pos != -1) - { - userName = m_krbSource.substring(0, pos); - } - } - - return userName; - } - - /** - * Return the response token length - * - * @return int - */ - public final int getResponseLength() - { - return m_krbResponse != null ? m_krbResponse.length : 0; - } - - /** - * Return the Kerberos authentication details as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[Source="); - str.append(getSourceName()); - str.append(",Target="); - str.append(getTargetName()); - str.append(":Response="); - str.append(getResponseLength()); - str.append(" bytes]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/kerberos/SessionSetupPrivilegedAction.java b/source/java/org/alfresco/filesys/server/auth/kerberos/SessionSetupPrivilegedAction.java deleted file mode 100644 index 9a5277a66b..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/kerberos/SessionSetupPrivilegedAction.java +++ /dev/null @@ -1,121 +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.server.auth.kerberos; - -import java.security.PrivilegedAction; - -import org.alfresco.filesys.server.auth.spnego.OID; -import org.ietf.jgss.GSSContext; -import org.ietf.jgss.GSSCredential; -import org.ietf.jgss.GSSException; -import org.ietf.jgss.GSSManager; -import org.ietf.jgss.GSSName; - -/** - * Session Setup Privileged Action Class - * - *

Handle the processing of a received SPNEGO packet in the context of the CIFS server. - * - * @author gkspencer - */ -public class SessionSetupPrivilegedAction implements PrivilegedAction -{ - // Received security blob details - - private byte[] m_secBlob; - private int m_secOffset; - private int m_secLen; - - // CIFS server account name - - private String m_accountName; - - /** - * Class constructor - * - * @param accountName String - * @param secBlob byte[] - */ - public SessionSetupPrivilegedAction ( String accountName, byte[] secBlob) - { - m_accountName = accountName; - - m_secBlob = secBlob; - m_secOffset = 0; - m_secLen = secBlob.length; - } - - /** - * Class constructor - * - * @param accountName String - * @param secBlob byte[] - * @param secOffset int - * @param secLen int - */ - public SessionSetupPrivilegedAction ( String accountName, byte[] secBlob, int secOffset, int secLen) - { - m_accountName = accountName; - - m_secBlob = secBlob; - m_secOffset = secOffset; - m_secLen = secLen; - } - - /** - * Run the privileged action - */ - public Object run() - { - KerberosDetails krbDetails = null; - - try - { - GSSManager gssManager = GSSManager.getInstance(); - GSSName serverGSSName = gssManager.createName(m_accountName, GSSName.NT_USER_NAME); - GSSCredential serverGSSCreds = gssManager.createCredential( serverGSSName, GSSCredential.INDEFINITE_LIFETIME, - OID.KERBEROS5, GSSCredential.ACCEPT_ONLY); - - GSSContext serverGSSContext = gssManager.createContext( serverGSSCreds); - - // Accept the incoming security blob and generate the response blob - - byte[] respBlob = serverGSSContext.acceptSecContext( m_secBlob, m_secOffset, m_secLen); - - // Create the Kerberos response details - - krbDetails = new KerberosDetails( serverGSSContext.getSrcName(), serverGSSContext.getTargName(), respBlob); - } - catch (GSSException ex) - { - System.out.println("GSSException: " + ex.getMajorString()); - System.out.println(" " + ex.getMessage()); - } - - // Return the Kerberos response - - return krbDetails; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLM.java b/source/java/org/alfresco/filesys/server/auth/ntlm/NTLM.java deleted file mode 100644 index 00b3866e29..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLM.java +++ /dev/null @@ -1,74 +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.server.auth.ntlm; - -/** - * NTLM Constants Class - * - * @author GKSpencer - */ -public class NTLM -{ - // Signature - - public static final byte[] Signature = "NTLMSSP\u0000".getBytes(); - - // Message types - - public static final int Type1 = 1; - public static final int Type2 = 2; - public static final int Type3 = 3; - - // NTLM flags - - public static final int FlagNegotiateUnicode = 0x00000001; - public static final int FlagNegotiateOEM = 0x00000002; - public static final int FlagRequestTarget = 0x00000004; - public static final int FlagNegotiateSign = 0x00000010; - public static final int FlagNegotiateSeal = 0x00000020; - public static final int FlagDatagramStyle = 0x00000040; - public static final int FlagLanManKey = 0x00000080; - public static final int FlagNegotiateNetware = 0x00000100; - public static final int FlagNegotiateNTLM = 0x00000200; - public static final int FlagDomainSupplied = 0x00001000; - public static final int FlagWorkstationSupplied = 0x00002000; - public static final int FlagLocalCall = 0x00004000; - public static final int FlagAlwaysSign = 0x00008000; - public static final int FlagChallengeInit = 0x00010000; - public static final int FlagChallengeAccept = 0x00020000; - public static final int FlagChallengeNonNT = 0x00040000; - public static final int FlagNTLM2Key = 0x00080000; - public static final int FlagTargetInfo = 0x00800000; - public static final int Flag128Bit = 0x20000000; - public static final int FlagKeyExchange = 0x40000000; - public static final int Flag56Bit = 0x80000000; - - // Target information types - - public static final int TargetServer = 0x0001; - public static final int TargetDomain = 0x0002; - public static final int TargetFullDNS = 0x0003; - public static final int TargetDNSDomain = 0x0004; -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMLogonDetails.java b/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMLogonDetails.java deleted file mode 100644 index affa544151..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMLogonDetails.java +++ /dev/null @@ -1,319 +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.server.auth.ntlm; - -import java.util.Date; - -import net.sf.acegisecurity.Authentication; - -/** - * NTLM Logon Details Class - * - *

Contains the details from the NTLM authentication session that was used to authenticate a user. - * - * @author GKSpencer - */ -public class NTLMLogonDetails -{ - // User name, workstation name and domain - - private String m_user; - private String m_workstation; - private String m_domain; - - // Authentication server name/address - - private String m_authSrvAddr; - - // Date/time authentication was started - - private long m_createTime; - - // Date/time the user was authenticated - - private long m_authTime; - - // User logged on via guest access - - private boolean m_guestAccess; - - // Cached type 2 NTLM message and copy of the NTLM hash used to successfully logon - - private Type2NTLMMessage m_type2Msg; - private byte[] m_ntlmHash; - - // Authentication token, used for passthru mode - - private Authentication m_authToken; - - /** - * Default constructor - */ - public NTLMLogonDetails() - { - m_createTime = System.currentTimeMillis(); - } - - /** - * Class constructor - * - * @param user String - * @param wks String - * @param domain String - * @param guest boolean - * @param authSrv String - */ - public NTLMLogonDetails(String user, String wks, String domain, boolean guest, String authSrv) - { - m_createTime = System.currentTimeMillis(); - - setDetails(user, wks, domain, guest, authSrv); - } - - /** - * Return the user name - * - * @return String - */ - public final String getUserName() - { - return m_user; - } - - /** - * Return the workstation name - * - * @return String - */ - public final String getWorkstation() - { - return m_workstation; - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Return the authentication server name/address - * - * @return String - */ - public final String getAuthenticationServer() - { - return m_authSrvAddr; - } - - /** - * Return the date/time the authentication was started - * - * @return long - */ - public final long createdAt() - { - return m_createTime; - } - - /** - * Return the date/time the user was authenticated - * - * @return long - */ - public final long authenticatedAt() - { - return m_authTime; - } - - /** - * Determine if the type 2 NTLM message has been cached - * - * @return boolean - */ - public final boolean hasType2Message() - { - return m_type2Msg != null ? true : false; - } - - /** - * Return the cached type 2 NTLM message - * - * @return Type2NTLMMessage - */ - public final Type2NTLMMessage getType2Message() - { - return m_type2Msg; - } - - /** - * Determine if there is a cached NTLM hashed password - * - * @return boolean - */ - public final boolean hasNTLMHashedPassword() - { - return m_ntlmHash != null ? true : false; - } - - /** - * Return the cached NTLM hashed password - * - * @return byte[] - */ - public final byte[] getNTLMHashedPassword() - { - return m_ntlmHash; - } - - /** - * Return the challenge key from the type2 message - * - * @return byte[] - */ - public final byte[] getChallengeKey() - { - if ( m_type2Msg != null) - return m_type2Msg.getChallenge(); - return null; - } - - /** - * Determine if the passthru authentication token is valid - * - * @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; - } - - /** - * Set the authentication date/time - * - * @param authTime long - */ - public final void setAuthenticatedAt(long authTime) - { - m_authTime = authTime; - } - - /** - * Set the client details - * - * @param user String - * @param wks String - * @param domain String - * @param guest boolean - * @param authSrv String - */ - public final void setDetails(String user, String wks, String domain, boolean guest, String authSrv) - { - m_user = user; - m_workstation = wks; - m_domain = domain; - - m_authSrvAddr = authSrv; - - m_guestAccess = guest; - - m_authTime = System.currentTimeMillis(); - } - - /** - * Set the type 2 NTLM message - * - * @param type2 Type2NTLMMessage - */ - public final void setType2Message(Type2NTLMMessage type2) - { - m_type2Msg = type2; - } - - /** - * Set the cached NTLM hashed password - * - * @param ntlmHash byte[] - */ - public final void setNTLMHashedPassword(byte[] ntlmHash) - { - m_ntlmHash = ntlmHash; - } - - /** - * Set the passthru authentication token - * - * @param token Authentication - */ - public final void setAuthenticationToken(Authentication token) - { - m_authToken = token; - } - - /** - * Return the NTLM logon details as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - str.append(getUserName()); - str.append(",Wks:"); - str.append(getWorkstation()); - str.append(",Dom:"); - str.append(getDomain()); - str.append(",AuthSrv:"); - str.append(getAuthenticationServer()); - str.append(","); - str.append(new Date(authenticatedAt())); - - if ( hasAuthenticationToken()) - { - str.append(",token="); - str.append(getAuthenticationToken()); - } - - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessage.java b/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessage.java deleted file mode 100644 index 9de12330f5..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessage.java +++ /dev/null @@ -1,536 +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.server.auth.ntlm; - -import java.io.UnsupportedEncodingException; - -import org.alfresco.filesys.util.DataPacker; - -/** - * NTLM Message Types Base Class - * - * @author GKSpencer - */ -public abstract class NTLMMessage -{ - // Default buffer size to allocate - - private static final int DefaultBlobSize = 256; - - // Field offsets - - public static final int OffsetSignature = 0; - public static final int OffsetType = 8; - - // Buffer header length - - public static final int BufferHeaderLen = 8; - - // Buffer, offset and lenght of the NTLM blob - - private byte[] m_buf; - private int m_offset; - - private int m_len; - - /** - * Default constructor - */ - protected NTLMMessage() - { - // Allocate a buffer - - m_buf = new byte[DefaultBlobSize]; - m_len = DefaultBlobSize; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - */ - protected NTLMMessage(byte[] buf, int offset, int len) - { - m_buf = buf; - m_offset = offset; - - m_len = len; - } - - /** - * Return the message type - * - * @return int - */ - public final int isMessageType() - { - return DataPacker.getIntelInt(m_buf, m_offset + OffsetType); - } - - /** - * Return the message flags - * - * @return int - */ - public abstract int getFlags(); - - /** - * Return the state of the specified flag - * - * @param flag int - * @return boolean - */ - public final boolean hasFlag(int flag) - { - return (getFlags() & flag) != 0 ? true : false; - } - /** - * Return the message length - * - * @return int - */ - public int getLength() - { - return m_len; - } - - /** - * Set the message type - * - * @param typ int - */ - public final void setMessageType(int typ) - { - DataPacker.putIntelInt(typ, m_buf, m_offset + OffsetType); - } - - /** - * Copy the NTLM blob data from the specified buffer - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public final void copyFrom(byte[] buf, int offset, int len) - { - // Allocate a new buffer, if required - - if ( m_buf == null || m_offset != 0 || m_buf.length < len) - m_buf = new byte[len]; - - // Copy the security blob data - - System.arraycopy(buf, offset, m_buf, 0, len); - } - - /** - * Return the NTLM message as a byte array - * - * @return byte[] - */ - public final byte[] getBytes() - { - byte[] byts = new byte[getLength()]; - System.arraycopy(m_buf, m_offset, byts, 0, getLength()); - return byts; - } - - /** - * Set the message flags - * - * @param flags int - */ - protected abstract void setFlags(int flags); - - /** - * Initialize the blob - * - * @param typ int - * @param flags int - */ - protected void initializeHeader(int typ, int flags) - { - // Set the signature - - System.arraycopy( NTLM.Signature, 0, m_buf, m_offset, NTLM.Signature.length); - - setMessageType(typ); - setFlags(flags); - } - - /** - * Return a short/16bit value - * - * @param offset int - * @return int - */ - protected final int getShortValue(int offset) - { - return DataPacker.getIntelShort(m_buf, m_offset + offset); - } - - /** - * Return an int/32bit value - * - * @param offset int - * @return int - */ - protected final int getIntValue(int offset) - { - return DataPacker.getIntelInt(m_buf, m_offset + offset); - } - - /** - * Return the offset for a byte value - * - * @param offset int - * @return int - */ - protected final int getByteOffset(int offset) - { - return getIntValue(offset + 4); - } - - /** - * Return a byte value that has a header - * - * @param offset int - * @return byte[] - */ - protected final byte[] getByteValue(int offset) - { - // Get the byte block length - - int bLen = getShortValue(offset); - if ( bLen == 0) - return null; - - int bOff = getIntValue(offset + 4); - return getRawBytes(bOff, bLen); - } - - /** - * Return a block of byte data - * - * @param offset int - * @param len int - * @return byte[] - */ - protected final byte[] getRawBytes(int offset, int len) - { - byte[] byts = new byte[len]; - System.arraycopy(m_buf, m_offset + offset, byts, 0, len); - - return byts; - } - - /** - * Return the length of a string - * - * @param offset int - * @return int - */ - protected final int getStringLength(int offset) - { - int bufpos = m_offset + offset; - - if ( bufpos + 2 > m_len) - return -1; - return DataPacker.getIntelShort(m_buf, bufpos); - } - - /** - * Return the allocated length of a string - * - * @param offset int - * @return int - */ - protected final int getStringAllocatedLength(int offset) - { - int bufpos = m_offset + offset; - - if ( bufpos + 8 > m_len) - return -1; - return DataPacker.getIntelShort(m_buf, bufpos + 2); - } - - /** - * Return the string data offset - * - * @param offset int - * @return int - */ - protected final int getStringOffset(int offset) - { - int bufpos = m_offset + offset; - - if ( bufpos + 8 > m_len) - return -1; - return DataPacker.getIntelInt(m_buf, bufpos + 4); - } - - /** - * Return a string value - * - * @param offset int - * @param isuni boolean - * @return String - */ - protected final String getStringValue(int offset, boolean isuni) - { - int bufpos = m_offset + offset; - - if ( offset + 8 > m_len) - return null; - - // Get the offset to the string - - int len = DataPacker.getIntelShort(m_buf, bufpos); - int pos = DataPacker.getIntelInt(m_buf, bufpos + 4); - - // Get the string value - - if ( pos + len > m_len) - return null; -// if ( isuni) -// len = len / 2; - - // Unpack the string - - String str = null; - try - { - str = new String(m_buf, m_offset + pos, len, isuni ? "UnicodeLittle" : "US-ASCII"); - } - catch (UnsupportedEncodingException ex) - { - ex.printStackTrace(); - } - - return str; - } - - /** - * Return a raw string - * - * @param offset int - * @param len int - * @param isuni boolean - * @return String - */ - protected final String getRawString(int offset, int len, boolean isuni) - { - return DataPacker.getString(m_buf, m_offset + offset, len, isuni); - } - - /** - * Set a short/16bit value - * - * @param offset int - * @param sval int - */ - protected final void setShortValue(int offset, int sval) - { - DataPacker.putIntelShort(sval, m_buf, m_offset + offset); - } - - /** - * Set an int/32bit value - * - * @param offset int - * @param val int - */ - protected final void setIntValue(int offset, int val) - { - DataPacker.putIntelInt(val, m_buf, m_offset + offset); - } - - /** - * Set a raw byte value - * - * @param offset int - * @param byts byte[] - */ - protected final void setRawBytes(int offset, byte[] byts) - { - System.arraycopy(byts, 0, m_buf, m_offset + offset, byts.length); - } - - /** - * Set raw int values - * - * @param offset int - * @param ints int[] - */ - protected final void setRawInts(int offset, int[] ints) - { - int bufpos = m_offset + offset; - - for ( int i = 0; i < ints.length; i++) - { - DataPacker.putIntelInt( ints[i], m_buf, bufpos); - bufpos += 4; - } - } - - /** - * Pack a raw string - * - * @param offset int - * @param str String - * @param isuni boolean - * @return int - */ - protected final int setRawString(int offset, String str, boolean isuni) - { - return DataPacker.putString(str, m_buf, m_offset + offset, false, isuni); - } - - /** - * Zero out an area of bytes - * - * @param offset int - * @param len int - */ - protected final void zeroBytes(int offset, int len) - { - int bufpos = m_offset + offset; - for ( int i = 0; i < len; i++) - m_buf[bufpos++] = (byte) 0; - } - - /** - * Set a byte array value - * - * @param offset int - * @param byts byte[] - * @param dataOffset int - * @return int - */ - protected final int setByteValue(int offset, byte[] byts, int dataOffset) - { - int bytsLen = byts != null ? byts.length : 0; - - if ( m_offset + offset + 12 > m_buf.length || - m_offset + dataOffset + bytsLen > m_buf.length) - throw new ArrayIndexOutOfBoundsException(); - - // Pack the byte pointer block - - DataPacker.putIntelShort(bytsLen, m_buf, m_offset + offset); - DataPacker.putIntelShort(bytsLen, m_buf, m_offset + offset + 2); - DataPacker.putIntelInt(dataOffset, m_buf, m_offset + offset + 4); - - // Pack the bytes - - if ( bytsLen > 0) - System.arraycopy(byts, 0, m_buf, m_offset + dataOffset, bytsLen); - - // Return the new data buffer offset - - return dataOffset + DataPacker.wordAlign(bytsLen); - } - - /** - * Set a string value - * - * @param offset int - * @param val String - * @param strOffset int - * @param isuni boolean - * @return int - */ - protected final int setStringValue(int offset, String val, int strOffset, boolean isuni) - { - // Get the length in bytes - - int len = val.length(); - if ( isuni) - len *= 2; - - if ( m_offset + offset + 8 > m_buf.length || - m_offset + strOffset + len > m_buf.length) - throw new ArrayIndexOutOfBoundsException(); - - // Pack the string pointer block - - - DataPacker.putIntelShort(len, m_buf, m_offset + offset); - DataPacker.putIntelShort(len, m_buf, m_offset + offset + 2); - DataPacker.putIntelInt(strOffset, m_buf, m_offset + offset + 4); - - // Pack the string - - return DataPacker.putString(val, m_buf, m_offset + strOffset, false, isuni) - m_offset; - } - - /** - * Set the message length - * - * @param len int - */ - protected final void setLength(int len) - { - m_len = len; - } - - /** - * Validate and determine the NTLM message type - * - * @param buf byte[] - * @return int - */ - public final static int isNTLMType(byte[] buf) - { - return isNTLMType(buf, 0); - } - - /** - * Validate and determine the NTLM message type - * - * @param buf byte[] - * @param offset int - * @return int - */ - public final static int isNTLMType(byte[] buf, int offset) - { - // Validate the buffer - - if ( buf == null || buf.length < BufferHeaderLen) - return -1; - - for ( int i = 0; i < NTLM.Signature.length; i++) - { - if ( buf[offset + i] != NTLM.Signature[i]) - return -1; - } - - // Get the NTLM message type - - return DataPacker.getIntelInt(buf, offset + OffsetType); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessageTest.java b/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessageTest.java deleted file mode 100644 index ea75f9ffe6..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMMessageTest.java +++ /dev/null @@ -1,165 +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.server.auth.ntlm; - -import junit.framework.TestCase; - -/** - * NTLM Message Test Class - * - * @author GKSpencer - */ -public class NTLMMessageTest extends TestCase -{ - /** - * Test type 1 message packing/unpacking - */ - public void testType1Message() - { - // Create a minimal type 1 message - - Type1NTLMMessage ntlmMsg = new Type1NTLMMessage(); - ntlmMsg.buildType1(0, null, null); - - assertEquals("Minimal type 1 message length wrong", 16, ntlmMsg.getLength()); - assertFalse("Minimal type 1 message domain supplied flag set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertFalse("Minimal type 1 message workstation supplied flag set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertFalse("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertNull("Minimal type 1 domain not null", ntlmMsg.getDomain()); - assertFalse("Minimal type 1 has workstation", ntlmMsg.hasWorkstation()); - assertNull("Minimal type 1 workstation not null", ntlmMsg.getWorkstation()); - - // Use a buffer to build a type 1 message - - byte[] buf = new byte[256]; - ntlmMsg = new Type1NTLMMessage(buf, 128, 128); - ntlmMsg.buildType1(0, null, null); - - assertEquals("Minimal type 1 message length wrong", 16, ntlmMsg.getLength()); - assertFalse("Minimal type 1 message domain supplied flag set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertFalse("Minimal type 1 message workstation supplied flag set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertFalse("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertNull("Minimal type 1 domain not null", ntlmMsg.getDomain()); - assertFalse("Minimal type 1 has workstation", ntlmMsg.hasWorkstation()); - assertNull("Minimal type 1 workstation not null", ntlmMsg.getWorkstation()); - - // Test type 1 with domain name only - - String testDomain = "TESTDOMAIN"; - String testWks = "TESTPC"; - - ntlmMsg = new Type1NTLMMessage(); - ntlmMsg.buildType1(0, testDomain, null); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertTrue("Minimal type 1 message domain supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertFalse("Minimal type 1 message workstation supplied flag set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertTrue("Minimal type 1 no domain", ntlmMsg.hasDomain()); - assertEquals("Minimal type 1 domain not correct", testDomain, ntlmMsg.getDomain()); - assertFalse("Minimal type 1 has workstation", ntlmMsg.hasWorkstation()); - assertNull("Minimal type 1 workstation not null", ntlmMsg.getWorkstation()); - - // Test type 1 with domain name only with buffer - - ntlmMsg = new Type1NTLMMessage(buf, 128, 128); - ntlmMsg.buildType1(0, testDomain, null); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertTrue("Minimal type 1 message domain supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertFalse("Minimal type 1 message workstation supplied flag set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertTrue("Minimal type 1 no domain", ntlmMsg.hasDomain()); - assertEquals("Minimal type 1 domain not correct", testDomain, ntlmMsg.getDomain()); - assertFalse("Minimal type 1 has workstation", ntlmMsg.hasWorkstation()); - assertNull("Minimal type 1 workstation not null", ntlmMsg.getWorkstation()); - - // Test type 1 with workstation name only - - ntlmMsg = new Type1NTLMMessage(); - ntlmMsg.buildType1(0, null, testWks); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertFalse("Minimal type 1 message domain supplied flag set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertTrue("Minimal type 1 message workstation supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertFalse("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertNull("Minimal type 1 domain not null", ntlmMsg.getDomain()); - assertTrue("Minimal type 1 no workstation", ntlmMsg.hasWorkstation()); - assertEquals("Minimal type 1 workstation not correct", testWks, ntlmMsg.getWorkstation()); - - // Test type 1 with domain name only with buffer - - ntlmMsg = new Type1NTLMMessage(buf, 128, 128); - ntlmMsg.buildType1(0, null, testWks); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertFalse("Minimal type 1 message domain supplied flag set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertTrue("Minimal type 1 message workstation supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertFalse("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertNull("Minimal type 1 domain not null", ntlmMsg.getDomain()); - assertTrue("Minimal type 1 no workstation", ntlmMsg.hasWorkstation()); - assertEquals("Minimal type 1 workstation not correct", testWks, ntlmMsg.getWorkstation()); - - // Test type 1 with domain and workstation names - - ntlmMsg = new Type1NTLMMessage(); - ntlmMsg.buildType1(0, testDomain, testWks); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertTrue("Minimal type 1 message domain supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertTrue("Minimal type 1 message workstation supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertTrue("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertEquals("Minimal type 1 domain not correct", testDomain, ntlmMsg.getDomain()); - assertTrue("Minimal type 1 no workstation", ntlmMsg.hasWorkstation()); - assertEquals("Minimal type 1 workstation not correct", testWks, ntlmMsg.getWorkstation()); - - // Test type 1 with domain and workstation names, with buffer - - ntlmMsg = new Type1NTLMMessage(buf, 128, 128); - ntlmMsg.buildType1(0, testDomain, testWks); - - assertTrue("Minimal type 1 message length wrong", ntlmMsg.getLength() > 16); - assertTrue("Minimal type 1 message domain supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagDomainSupplied)); - assertTrue("Minimal type 1 message workstation supplied flag not set", ntlmMsg.hasFlag(NTLM.FlagWorkstationSupplied)); - assertTrue("Minimal type 1 has domain", ntlmMsg.hasDomain()); - assertEquals("Minimal type 1 domain not correct", testDomain, ntlmMsg.getDomain()); - assertTrue("Minimal type 1 no workstation", ntlmMsg.hasWorkstation()); - assertEquals("Minimal type 1 workstation not correct", testWks, ntlmMsg.getWorkstation()); - } - - /** - * Test type 2 message packing/unpacking - */ - public void testType2Message() - { - // No tests yet, only receive type 2 from the server - } - - /** - * Test type 3 message packing/unpacking - */ - public void testType3Message() - { - - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMv2Blob.java b/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMv2Blob.java deleted file mode 100644 index a86dc4d606..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/NTLMv2Blob.java +++ /dev/null @@ -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.server.auth.ntlm; - -import java.util.Date; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; - -/** - * NTLMv2 Blob Class - * - *

Contains methods to pack/unpack and calculate the hash of an NTLMv2 blob. - * - * @author gkspencer - */ -public class NTLMv2Blob -{ - // Constants - - public static final int HMAC_LEN = 16; - public static final int CHALLENGE_LEN = 8; - - // Offsets - - public static final int OFFSET_HMAC = 0; - public static final int OFFSET_HEADER = 16; - public static final int OFFSET_RESERVED = 20; - public static final int OFFSET_TIMESTAMP = 24; - public static final int OFFSET_CHALLENGE = 32; - public static final int OFFSET_UNKNOWN = 36; - public static final int OFFSET_TARGETINFO = 40; - - // NTLMv2 blob - - private byte[] m_blob; - private int m_offset; - private int m_len; - - /** - * Class constructor - * - * @param buf byte[] - */ - public NTLMv2Blob(byte[] buf) - { - m_blob = buf; - m_offset = 0; - m_len = m_blob.length; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public NTLMv2Blob(byte[] buf, int offset, int len) - { - m_blob = buf; - m_offset = offset; - m_len = len; - } - - /** - * Return the buffer - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_blob; - } - - /** - * Return the offset - * - * @return int - */ - public final int getOffset() - { - return m_offset; - } - - /** - * Return the blob length - * - * @return int - */ - public final int getLength() - { - return m_len; - } - - /** - * Return the HMAC from the buffer - * - * @return byte[] - */ - public final byte[] getHMAC() - { - byte[] hmac = new byte[HMAC_LEN]; - System.arraycopy(m_blob, m_offset, hmac, 0, HMAC_LEN); - - return hmac; - } - - /** - * Return the timestamp from the buffer, in NT 64bit time format - * - * @return long - */ - public final long getTimeStamp() - { - return DataPacker.getIntelLong(m_blob, m_offset + OFFSET_TIMESTAMP); - } - - /** - * Return the client challenge - * - * @return byte[] - */ - public final byte[] getClientChallenge() - { - byte[] challenge = new byte[CHALLENGE_LEN]; - System.arraycopy( m_blob, m_offset + OFFSET_CHALLENGE, challenge, 0, CHALLENGE_LEN); - - return challenge; - } - - /** - * Calculate the HMAC of the blob using the specified NTLMv2 hash and challenge - * - * @param challenge byte[] - * @param v2hash byte[] - * @return byte[] - * @exception Exception - */ - public final byte[] calculateHMAC( byte[] challenge, byte[] v2hash) - throws Exception - { - // Create a copy of the NTLMv2 blob with room for the challenge - - byte[] blob = new byte[(m_len - HMAC_LEN) + CHALLENGE_LEN]; - System.arraycopy( challenge, 0, blob, 0, CHALLENGE_LEN); - System.arraycopy( m_blob, m_offset + OFFSET_HEADER, blob, CHALLENGE_LEN, m_len - HMAC_LEN); - - // Generate the HMAC of the blob using the v2 hash as the key - - Mac hmacMd5 = Mac.getInstance( "HMACMD5"); - SecretKeySpec blobKey = new SecretKeySpec( v2hash, 0, v2hash.length, "MD5"); - - hmacMd5.init( blobKey); - return hmacMd5.doFinal( blob); - } - - /** - * Dump the NTLMv2 blob details - */ - public final void Dump() - { - System.out.println("NTLMv2 blob :"); - System.out.println(" HMAC : " + HexDump.hexString( getHMAC())); - System.out.println(" Header : 0x" + Integer.toHexString(DataPacker.getIntelInt( m_blob, m_offset + OFFSET_HEADER))); - System.out.println(" Timestamp : " + new Date(NTTime.toJavaDate( getTimeStamp()))); - System.out.println(" Challenge : " + HexDump.hexString( getClientChallenge())); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/TargetInfo.java b/source/java/org/alfresco/filesys/server/auth/ntlm/TargetInfo.java deleted file mode 100644 index 6f7887820e..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/TargetInfo.java +++ /dev/null @@ -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.server.auth.ntlm; - -/** - * Target Information Class - * - *

Contains the target information from an NTLM message. - * - * @author GKSpencer - */ -public class TargetInfo -{ - // Target type and name - - private int m_type; - private String m_name; - - /** - * Class constructor - * - * @param type int - * @param name String - */ - public TargetInfo(int type, String name) - { - m_type = type; - m_name = name; - } - - /** - * Return the target type - * - * @return int - */ - public final int isType() - { - return m_type; - } - - /** - * Return the target name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the target information as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - str.append(getTypeAsString(isType())); - str.append(":"); - str.append(getName()); - str.append("]"); - - return str.toString(); - } - - /** - * Return the target type as a string - * - * @param typ int - * @return String - */ - public final static String getTypeAsString(int typ) - { - String typStr = null; - - switch ( typ) - { - case NTLM.TargetServer: - typStr = "Server"; - break; - case NTLM.TargetDomain: - typStr = "Domain"; - break; - case NTLM.TargetFullDNS: - typStr = "DNS"; - break; - case NTLM.TargetDNSDomain: - typStr = "DNS Domain"; - break; - default: - typStr = "Unknown 0x" + Integer.toHexString(typ); - break; - } - - return typStr; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/Type1NTLMMessage.java b/source/java/org/alfresco/filesys/server/auth/ntlm/Type1NTLMMessage.java deleted file mode 100644 index db2b576e35..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/Type1NTLMMessage.java +++ /dev/null @@ -1,216 +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.server.auth.ntlm; - -/** - * Type1 NTLM Message Class - * - * @author GKSpencer - */ -public class Type1NTLMMessage extends NTLMMessage -{ - // Minimal type 1 message length - - public static final int MinimalMessageLength = 16; - - // Type 1 field offsets - - public static final int OffsetFlags = 12; - public static final int OffsetData = 16; - - /** - * Default constructor - */ - public Type1NTLMMessage() - { - super(); - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public Type1NTLMMessage(byte[] buf) - { - super(buf, 0, buf.length); - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public Type1NTLMMessage(byte[] buf, int offset, int len) - { - super(buf, offset, len); - } - - /** - * Return the flags value - * - * @return int - */ - public int getFlags() - { - return getIntValue(OffsetFlags); - } - - /** - * Check if the domain security buffer is included - * - * @return boolean - */ - public final boolean hasDomain() - { - if ( getLength() == MinimalMessageLength || hasFlag(NTLM.FlagDomainSupplied) == false) - return false; - return true; - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - if ( hasFlag(NTLM.FlagDomainSupplied) == false) - return null; - - return getStringValue(OffsetData, false); - } - - /** - * Check if the workstation security buffer is included - * - * @return boolean - */ - public final boolean hasWorkstation() - { - if ( getLength() == MinimalMessageLength || hasFlag(NTLM.FlagWorkstationSupplied) == false) - return false; - return true; - } - - /** - * Return the workstation name - * - * @return String - */ - public final String getWorkstation() - { - if ( hasFlag(NTLM.FlagWorkstationSupplied) == false) - return null; - - int bufPos = OffsetData; - if ( hasFlag(NTLM.FlagDomainSupplied)) - bufPos += BufferHeaderLen; - - return getStringValue(bufPos, false); - } - - /** - * Build a type 1 message - * - * @param flags int - * @param domain String - * @param workstation String - */ - public final void buildType1(int flags, String domain, String workstation) - { - int bufPos = OffsetData; - int strOff = OffsetData; - - if ( domain != null) - strOff += BufferHeaderLen; - if ( workstation != null) - strOff += BufferHeaderLen; - - // Pack the domain name - - if ( domain != null) - { - strOff = setStringValue(bufPos, domain, strOff, false); - flags |= NTLM.FlagDomainSupplied; - bufPos += BufferHeaderLen; - } - - // Pack the workstation name - - if ( workstation != null) - { - strOff = setStringValue(bufPos, workstation, strOff, false); - flags |= NTLM.FlagWorkstationSupplied; - } - - // Initialize the header/flags - - initializeHeader(NTLM.Type1, flags); - - // Set the message length - - setLength(strOff); - } - - /** - * Set the message flags - * - * @param flags int - */ - protected void setFlags(int flags) - { - setIntValue( OffsetFlags, flags); - } - - /** - * Return the type 1 message as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[Type1:0x"); - str.append(Integer.toHexString(getFlags())); - str.append(",Domain:"); - if ( hasDomain()) - str.append(getDomain()); - else - str.append(""); - str.append(",Wks:"); - - if ( hasWorkstation()) - str.append(getWorkstation()); - else - str.append(""); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/Type2NTLMMessage.java b/source/java/org/alfresco/filesys/server/auth/ntlm/Type2NTLMMessage.java deleted file mode 100644 index f68f543ed3..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/Type2NTLMMessage.java +++ /dev/null @@ -1,332 +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.server.auth.ntlm; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.filesys.util.HexDump; - -/** - * Type 2 NTLM Message Class - * - * @author GKSpencer - */ -public class Type2NTLMMessage extends NTLMMessage -{ - // Minimal type 2 message length - - public static final int MinimalMessageLength = 32; - - // Type 2 field offsets - - public static final int OffsetTarget = 12; - public static final int OffsetFlags = 20; - public static final int OffsetChallenge = 24; - public static final int OffsetContext = 32; - public static final int OffsetTargetInfo = 40; // optional - - /** - * Default constructor - */ - public Type2NTLMMessage() - { - super(); - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public Type2NTLMMessage(byte[] buf) - { - super(buf, 0, buf.length); - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public Type2NTLMMessage(byte[] buf, int offset, int len) - { - super(buf, offset, len); - } - - /** - * Return the flags value - * - * @return int - */ - public int getFlags() - { - return getIntValue(OffsetFlags); - } - - /** - * Check if the target name has been set - * - * @return boolean - */ - public final boolean hasTarget() - { - return hasFlag(NTLM.FlagRequestTarget); - } - - /** - * Return the target name - * - * @return String - */ - public final String getTarget() - { - return getStringValue(OffsetTarget, hasFlag(NTLM.FlagNegotiateUnicode)); - } - - /** - * Return the challenge - * - * @return byte[] - */ - public final byte[] getChallenge() - { - return getRawBytes(OffsetChallenge, 8); - } - - /** - * Check if the optional context field is present - * - * @return boolean - */ - public final boolean hasContext() - { - return hasFlag(NTLM.FlagLocalCall); - } - - /** - * Return the context values - * - * @return int[] - */ - public final int[] getContext() - { - if ( hasContext() == false) - return null; - - int[] ctx = new int[2]; - - ctx[0] = getIntValue(OffsetContext); - ctx[1] = getIntValue(OffsetContext + 4); - - return ctx; - } - - /** - * Check if target information is present - * - * @return boolean - */ - public final boolean hasTargetInformation() - { - return hasFlag(NTLM.FlagTargetInfo); - } - - /** - * Return the target information - * - * @return List - */ - public final List getTargetInformation() - { - if ( hasTargetInformation() == false) - return null; - - // Get the target information block length and offset - - int tLen = getStringLength(OffsetTargetInfo); - int tOff = getStringOffset(OffsetTargetInfo); - - List tList = new ArrayList(); - if ( tLen == 0) - return tList; - - // Unpack the target information structures - - int typ = -1; - int slen = -1; - String name = null; - - while ( typ != 0) - { - // Unpack the details for the current target - - typ = getShortValue(tOff); - slen = getShortValue(tOff + 2); - - if ( slen > 0) - name = getRawString(tOff + 4, slen/2, true); - else - name = null; - - // Add the details to the list - - if ( typ != 0) - tList.add( new TargetInfo(typ, name)); - - // Update the data offset - - tOff += slen + 4; - } - - // Return the target list - - return tList; - } - - /** - * Build a type 2 message - * - * @param flags int - * @param target String - * @param challenge byte[] - * @param ctx byte[] - * @param tList List - */ - public final void buildType2(int flags, String target, byte[] challenge, int[] ctx, List tList) - { - // Initialize the header/flags - - initializeHeader(NTLM.Type2, flags); - - // Determine if strings are ASCII or Unicode - - boolean isUni = hasFlag(NTLM.FlagNegotiateUnicode); - - int strOff = OffsetTargetInfo; - if ( tList != null) - strOff += 8; - - // Pack the target name - - strOff = setStringValue(OffsetTarget, target, strOff, isUni); - - // Pack the challenge and context - - if ( challenge != null) - setRawBytes(OffsetChallenge, challenge); - else - zeroBytes(OffsetChallenge, 8); - - if ( ctx != null) - setRawInts(OffsetContext, ctx); - else - zeroBytes(OffsetContext, 8); - - // Pack the target information, if specified - - if ( tList != null) - { - // Clear the target information length and set the data offset - - setIntValue(OffsetTargetInfo, 0); - setIntValue(OffsetTargetInfo+4, strOff); - - int startOff = strOff; - - // Pack the target information structures - - for ( TargetInfo tInfo : tList) - { - // Pack the target information structure - - setShortValue(strOff, tInfo.isType()); - - int tLen = tInfo.getName().length(); - if ( isUni) - tLen *= 2; - setShortValue(strOff+2, tLen); - strOff = setRawString(strOff+4, tInfo.getName(), isUni); - } - - // Add the list terminator - - zeroBytes(strOff, 4); - strOff += 4; - - // Set the target information block length - - setShortValue(OffsetTargetInfo, strOff - startOff); - setShortValue(OffsetTargetInfo+2, strOff - startOff); - } - - // Set the message length - - setLength(strOff); - } - - /** - * Set the message flags - * - * @param flags int - */ - protected void setFlags(int flags) - { - setIntValue( OffsetFlags, flags); - } - - /** - * Return the type 2 message as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[Type2:0x"); - str.append(Integer.toHexString(getFlags())); - str.append(",Target:"); - str.append(getTarget()); - str.append(",Ch:"); - str.append(HexDump.hexString(getChallenge())); - - if ( hasTargetInformation()) - { - List targets = getTargetInformation(); - - str.append(",TargInf:"); - for ( TargetInfo target : targets) - { - str.append(target); - } - } - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/ntlm/Type3NTLMMessage.java b/source/java/org/alfresco/filesys/server/auth/ntlm/Type3NTLMMessage.java deleted file mode 100644 index ba015bc87f..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/ntlm/Type3NTLMMessage.java +++ /dev/null @@ -1,345 +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.server.auth.ntlm; - -import org.alfresco.filesys.util.HexDump; - -/** - * Type 3 NTLM Message Class - * - * @author GKSpencer - */ -public class Type3NTLMMessage extends NTLMMessage -{ - // Minimal type 3 message length - - public static final int MinimalMessageLength = 52; - - // Type 2 field offsets - - public static final int OffsetLMResponse = 12; - public static final int OffsetNTLMResponse = 20; - public static final int OffsetDomain = 28; - public static final int OffsetUserName = 36; - public static final int OffsetWorkstationName = 44; - public static final int OffsetDataMinimum = 52; - public static final int OffsetSessionKey = 52; // optional - public static final int OffsetFlags = 60; // optional - public static final int OffsetData = 64; - - // Flag to indicate if Unicode strings have been negotiated - - private boolean m_unicode; - - // Data block offset, used to indicate if session key and flags have been specified - - private int m_dataOffset = -1; - - /** - * Default constructor - */ - public Type3NTLMMessage() - { - super(); - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public Type3NTLMMessage(byte[] buf) - { - super(buf, 0, buf.length); - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - * @param unicode boolean - */ - public Type3NTLMMessage(byte[] buf, int offset, int len, boolean unicode) - { - super(buf, offset, len); - - m_unicode = unicode; - } - - /** - * Return the flags value - * - * @return int - */ - public int getFlags() - { - return getIntValue(OffsetFlags); - } - - /** - * Return the length of the LM hash - * - * @return int - */ - public final int getLMHashLength() - { - return getShortValue(OffsetLMResponse); - } - - /** - * Return the LM password hash - * - * @return byte[] - */ - public final byte[] getLMHash() - { - return getByteValue(OffsetLMResponse); - } - - /** - * Return the length of the NTLM hash - * - * @return int - */ - public final int getNTLMHashLength() - { - return getShortValue(OffsetNTLMResponse); - } - - /** - * Return the NTLM password hash - * - * @return byte[] - */ - public final byte[] getNTLMHash() - { - return getByteValue(OffsetNTLMResponse); - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - return getStringValue(OffsetDomain, hasFlag(NTLM.FlagNegotiateUnicode)); - } - - /** - * Return the user name - * - * @return String - */ - public final String getUserName() - { - return getStringValue(OffsetUserName, hasFlag(NTLM.FlagNegotiateUnicode)); - } - - /** - * Return the workstation name - * - * @return String - */ - public final String getWorkstation() - { - return getStringValue(OffsetWorkstationName, hasFlag(NTLM.FlagNegotiateUnicode)); - } - - /** - * Determine if the session key has been specified - * - * @return boolean - */ - public final boolean hasSessionKey() - { - return getShortValue(OffsetSessionKey) > 0; - } - - /** - * Return the session key, or null if the session key is not present - * - * @return byte[] - */ - public final byte[] getSessionKey() - { - if ( hasSessionKey() == false) - return null; - - // Get the session key bytes - - return getByteValue(OffsetSessionKey); - } - - /** - * Build a type 3 message - * - * @param lmHash byte[] - * @param ntlmHash byte[] - * @param domain String - * @param username String - * @param wksname String - * @param sessKey byte[] - * @param flags int - */ - public final void buildType3(byte[] lmHash, byte[] ntlmHash, String domain, String username, String wksname, - byte[] sessKey, int flags) - { - initializeHeader(NTLM.Type3, 0); - - // Set the data offset - - int dataOff = OffsetData; - - // Pack the domain, user and workstation names - - dataOff = setStringValue(OffsetDomain, domain, dataOff, m_unicode); - dataOff = setStringValue(OffsetUserName, username, dataOff, m_unicode); - dataOff = setStringValue(OffsetWorkstationName, wksname, dataOff, m_unicode); - - // Pack the LM and NTLM password hashes - - dataOff = setByteValue(OffsetLMResponse, lmHash, dataOff); - dataOff = setByteValue(OffsetNTLMResponse, ntlmHash, dataOff); - - // Pack the session key - - dataOff = setByteValue(OffsetSessionKey, sessKey, dataOff); - - // Make sure various flags are set - - int typ3flags = NTLM.FlagNegotiateNTLM + NTLM.FlagRequestTarget; - if ( m_unicode) - flags += NTLM.FlagNegotiateUnicode; - - // Pack the flags - - setIntValue(OffsetFlags, typ3flags); - - // Set the message length - - setLength(dataOff); - } - - /** - * Set the message flags - * - * @param flags int - */ - protected void setFlags(int flags) - { - setIntValue(OffsetFlags, flags); - } - - /** - * Find the data block offset - * - * @return int - */ - private final int findDataBlockOffset() - { - // Find the lowest data offset - // - // Check the LM hash - - int offset = getByteOffset(OffsetLMResponse); - - if ( m_dataOffset == -1 || offset < m_dataOffset) - m_dataOffset = offset; - - // Check the NTLM hash - - offset = getByteOffset(OffsetNTLMResponse); - if ( offset < m_dataOffset) - m_dataOffset = offset; - - // Check the domain name - - offset = getStringOffset(OffsetDomain); - if ( offset < m_dataOffset) - m_dataOffset = offset; - - // Check the user name - - offset = getStringOffset(OffsetUserName); - if ( offset < m_dataOffset) - m_dataOffset = offset; - - // Check the workstation - - offset = getStringOffset(OffsetWorkstationName); - if ( offset < m_dataOffset) - m_dataOffset = offset; - - // Return the new data offset - - return m_dataOffset; - } - - - /** - * Return the type 3 message as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[Type3:"); - - str.append(",LM:"); - if ( getLMHash() != null) - str.append(HexDump.hexString(getLMHash())); - else - str.append(""); - - str.append(",NTLM:"); - if ( getNTLMHash() != null) - str.append(HexDump.hexString(getNTLMHash())); - else - str.append(""); - - str.append(",Dom:"); - str.append(getDomain()); - str.append(",User:"); - str.append(getUserName()); - str.append(",Wks:"); - str.append(getWorkstation()); - - if ( hasSessionKey()) - { - str.append(",SessKey:"); - str.append(HexDump.hexString(getSessionKey())); - str.append(",Flags:0x"); - str.append(Integer.toHexString(getFlags())); - } - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java b/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java deleted file mode 100644 index 93b912749d..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/AuthSessionFactory.java +++ /dev/null @@ -1,930 +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.server.auth.passthru; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetBIOSNameList; -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.auth.PasswordEncryptor; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.Dialect; -import org.alfresco.filesys.smb.DialectSelector; -import org.alfresco.filesys.smb.NetworkSession; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.Protocol; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.util.IPAddress; -import org.alfresco.filesys.util.StringList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - *

- * The AuthSessionFactory static class is used to create sessions to remote shared resources using - * the SMB/CIFS protocol. A PCShare object is used to specify the remote node and share details, as - * well as required access control details. - */ -public final class AuthSessionFactory -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth"); - - // Constants - - private static final int BROADCAST_LOOKUP_TIMEOUT = 4000; // ms - - // Default SMB dialect list - - private static DialectSelector m_defDialects; - - // Session index, used to make each session request call id unique - - private static int m_sessIdx = 1; - - // Local domain name, if known - - private static String m_localDomain = null; - - // Local domains browse master, if known - - private static String m_localBrowseMaster = null; - - // Default session packet buffer size - - private static int m_defPktSize = 4096 + RFCNetBIOSProtocol.HEADER_LEN; - - // List of local TCP/IP addresses - - private static InetAddress[] m_localAddrList; - - // Password encryptor - - private static PasswordEncryptor m_encryptor = new PasswordEncryptor(); - - static - { - - // Initialize the default dialect list - - m_defDialects = new DialectSelector(); - m_defDialects.AddDialect(Dialect.Core); - m_defDialects.AddDialect(Dialect.CorePlus); - m_defDialects.AddDialect(Dialect.DOSLanMan1); - m_defDialects.AddDialect(Dialect.DOSLanMan2); - m_defDialects.AddDialect(Dialect.LanMan1); - m_defDialects.AddDialect(Dialect.LanMan2); - m_defDialects.AddDialect(Dialect.LanMan2_1); - m_defDialects.AddDialect(Dialect.NT); - } - - // Default user name, password and domain used by methods that create their own connections. - - private static String m_defUserName = ""; - private static String m_defPassword = ""; - private static String m_defDomain = "?"; - - // Primary and secondary protocols to connect with - - private static int m_primaryProto = Protocol.TCPNetBIOS; - private static int m_secondaryProto = Protocol.NativeSMB; - - // NetBIOS port to connect to when setting up a new session. The default port is 139. - - private static int m_netbiosPort = RFCNetBIOSProtocol.PORT; - - // NetBIOS name scope - - private static String m_netBIOSScopeId = null; - - // Flag to enable extended security exchanges in the session setup - - private static boolean m_useExtendedSec = true; - - /** - * Build an SMB negotiate dialect packet. - * - * @param pkt SMBPacket to build the negotiate request - * @param dlct SMB dialects to negotiate - * @param pid Process id to be used by this new session - * @param extSec Enable/disable extended security negotiation - * @return StringList - */ - - private final static StringList BuildNegotiatePacket(SMBPacket pkt, DialectSelector dlct, int pid, boolean extSec) - { - - // Initialize the SMB packet header fields - - pkt.setCommand(PacketType.Negotiate); - pkt.setProcessId(pid); - - // If the NT dialect is enabled set the Unicode flag - - int flags2 = 0; - - if (dlct.hasDialect(Dialect.NT)) - flags2 += SMBPacket.FLG2_UNICODE; - - if ( useExtendedSecurity() && extSec == true) - flags2 += SMBPacket.FLG2_EXTENDEDSECURITY; - - pkt.setFlags2(flags2); - - // Build the SMB dialect list - - StringBuilder dia = new StringBuilder(); - StringList diaList = new StringList(); - - // Loop through all SMB dialect types and add the appropriate dialect strings - // to the negotiate packet. - - int d = Dialect.Core; - - while (d < Dialect.Max) - { - - // Check if the current dialect is selected - - if (dlct.hasDialect(d)) - { - - // Search the SMB dialect type string list and add all strings for the - // current dialect - - for (int i = 0; i < Dialect.NumberOfDialects(); i++) - { - - // Check if the current dialect string should be added to the list - - if (Dialect.DialectType(i) == d) - { - - // Get the current SMB dialect string - - String curDialect = Dialect.DialectString(i); - diaList.addString(curDialect); - - // Add the current SMB dialect type string to the negotiate packet - - dia.append(DataType.Dialect); - dia.append(curDialect); - dia.append((char) 0x00); - } - } - } - - // Update the current dialect type - - d++; - } - - // Copy the dialect strings to the SMB packet - - pkt.setBytes(dia.toString().getBytes()); - - // Return the dialect strings - - return diaList; - } - - /** - * Return the default SMB packet size - * - * @return Default SMB packet size to allocate. - */ - protected final static int DefaultPacketSize() - { - return m_defPktSize; - } - - /** - * Return the list of SMB dialects that will be negotiated when a new session is created. - * - * @return DialectSelector List of enabled SMB dialects. - */ - public final static DialectSelector getDefaultDialects() - { - return m_defDialects; - } - - /** - * Return the default domain name - * - * @return String - */ - public static String getDefaultDomain() - { - return m_defDomain; - } - - /** - * Return the default password. - * - * @return java.lang.String - */ - public static String getDefaultPassword() - { - return m_defPassword; - } - - /** - * Return the default user name. - * - * @return java.lang.String - */ - public static String getDefaultUserName() - { - return m_defUserName; - } - - /** - * Return the NetBIOS scope id, or null if not set - * - * @return String - */ - public static String getNetBIOSNameScope() - { - return m_netBIOSScopeId; - } - - /** - * Return the NetBIOS socket number that new sessions are connected to. - * - * @return int NetBIOS session socket number. - */ - public static int getNetBIOSPort() - { - return m_netbiosPort; - } - - /** - * Return the primary connection protocol (either Protocol.TCPNetBIOS or Protocol.NativeSMB) - * - * @return int - */ - public static final int getPrimaryProtocol() - { - return m_primaryProto; - } - - /** - * Return the secondary connection protocol (Protocol.TCPNetBIOS, Protocol.NativeSMB or - * Protocol.None) - * - * @return int - */ - public static final int getSecondaryProtocol() - { - return m_secondaryProto; - } - - /** - * Return the next session id - * - * @return int - */ - private static synchronized int getSessionId() - { - int sessId = m_sessIdx++ + (NetBIOSSession.getJVMIndex() * 100); - return sessId; - } - - /** - * Get the list of local TCP/IP addresses - * - * @return InetAddress[] - */ - private static synchronized InetAddress[] getLocalTcpipAddresses() - { - - // Get the list of local TCP/IP addresses - - if (m_localAddrList == null) - { - try - { - m_localAddrList = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); - } - catch (UnknownHostException ex) - { - } - } - - // Return the address list - - return m_localAddrList; - } - - /** - * Determine if the NetBIOS name scope is set - * - * @return boolean - */ - public final static boolean hasNetBIOSNameScope() - { - return m_netBIOSScopeId != null ? true : false; - } - - /** - * Determine if extended security exchanges are enabled - * - * @return boolean - */ - public static final boolean useExtendedSecurity() - { - return m_useExtendedSec; - } - - /** - * Open a session to a remote server, negotiate an SMB dialect and get the returned challenge - * key. Returns an AuthenticateSession which can then be used to provide passthru - * authentication. - * - * @param shr Remote server share and access control details. - * @param tmo Timeout value in milliseconds - * @return AuthenticateSession for the new session, else null. - * @exception java.io.IOException If an I/O error occurs. - * @exception java.net.UnknownHostException Remote node is unknown. - * @exception SMBException Failed to setup a new session. - */ - public static AuthenticateSession OpenAuthenticateSession(PCShare shr, int tmo) throws java.io.IOException, - java.net.UnknownHostException, SMBException - { - - // Open an authentication session - - return OpenAuthenticateSession(shr, tmo, null); - } - - /** - * Open a session to a remote server, negotiate an SMB dialect and get the returned challenge - * key. Returns an AuthenticateSession which can then be used to provide passthru - * authentication. - * - * @param shr Remote server share and access control details. - * @param tmo Timeout value in milliseconds - * @param dia SMB dialects to negotiate for this session. - * @return AuthenticateSession for the new session, else null. - * @exception java.io.IOException If an I/O error occurs. - * @exception java.net.UnknownHostException Remote node is unknown. - * @exception SMBException Failed to setup a new session. - */ - public static AuthenticateSession OpenAuthenticateSession(PCShare shr, int tmo, DialectSelector dia) - throws java.io.IOException, java.net.UnknownHostException, SMBException - { - - // Build a unique caller name - - int pid = getSessionId(); - - StringBuilder nameBuf = new StringBuilder(InetAddress.getLocalHost().getHostName() + "_" + pid); - String localName = nameBuf.toString(); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("New auth session from " + localName + " to " + shr.toString()); - - // Connect to the requested server - - NetworkSession netSession = null; - - switch (getPrimaryProtocol()) - { - - // NetBIOS connection - - case Protocol.TCPNetBIOS: - netSession = connectNetBIOSSession(shr.getNodeName(), localName, tmo); - break; - - // Native SMB connection - - case Protocol.NativeSMB: - netSession = connectNativeSMBSession(shr.getNodeName(), localName, tmo); - break; - } - - // If the connection was not made using the primary protocol try the secondary protocol, if - // configured - - if (netSession == null) - { - - // Try the secondary protocol - - switch (getSecondaryProtocol()) - { - - // NetBIOS connection - - case Protocol.TCPNetBIOS: - netSession = connectNetBIOSSession(shr.getNodeName(), localName, tmo); - break; - - // Native SMB connection - - case Protocol.NativeSMB: - netSession = connectNativeSMBSession(shr.getNodeName(), localName, tmo); - break; - } - } - - // Check if we connected to the remote host - - if (netSession == null) - throw new IOException("Failed to connect to host, " + shr.getNodeName()); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("Connected session, protocol : " + netSession.getProtocolName()); - - // Build a protocol negotiation SMB packet, and send it to the remote - // file server. - - SMBPacket pkt = new SMBPacket(); - DialectSelector selDialect = dia; - - if (selDialect == null) - { - - // Use the default SMB dialect list - - selDialect = new DialectSelector(); - selDialect.copyFrom(m_defDialects); - } - - // Build the negotiate SMB dialect packet and exchange with the remote server - - StringList diaList = BuildNegotiatePacket(pkt, selDialect, pid, shr.hasExtendedSecurityFlags()); - pkt.ExchangeLowLevelSMB(netSession, pkt, true); - - // Determine the selected SMB dialect - - String diaStr = diaList.getStringAt(pkt.getParameter(0)); - int dialectId = Dialect.DialectType(diaStr); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("SessionFactory: Negotiated SMB dialect " + diaStr); - - if (dialectId == Dialect.Unknown) - throw new java.io.IOException("Unknown SMB dialect"); - - // Create the authenticate session - - AuthenticateSession authSess = new AuthenticateSession(shr, netSession, dialectId, pkt); - return authSess; - } - - /** - * Set the default domain. - * - * @param domain String - */ - public static void setDefaultDomain(String domain) - { - m_defDomain = domain; - } - - /** - * Set the default password. - * - * @param pwd java.lang.String - */ - public static void setDefaultPassword(String pwd) - { - m_defPassword = pwd; - } - - /** - * Set the default user name. - * - * @param user java.lang.String - */ - public static void setDefaultUserName(String user) - { - m_defUserName = user; - } - - /** - * Enable/disable the use of extended security exchanges - * - * @param ena boolean - */ - public static final void setExtendedSecurity(boolean ena) - { - m_useExtendedSec = ena; - } - - /** - * Set the NetBIOS socket number to be used when setting up new sessions. The default socket is - * 139. - * - * @param port int - */ - public static void setNetBIOSPort(int port) - { - m_netbiosPort = port; - } - - /** - * Set the NetBIOS scope id - * - * @param scope String - */ - public static void setNetBIOSNameScope(String scope) - { - if (scope != null && scope.startsWith(".")) - m_netBIOSScopeId = scope.substring(1); - else - m_netBIOSScopeId = scope; - } - - /** - * Set the protocol connection order - * - * @param pri Primary connection protocol - * @param sec Secondary connection protocol, or none - * @return boolean - */ - public static final boolean setProtocolOrder(int pri, int sec) - { - - // Primary protocol must be specified - - if (pri != Protocol.TCPNetBIOS && pri != Protocol.NativeSMB) - return false; - - // Primary and secondary must be different - - if (pri == sec) - return false; - - // Save the settings - - m_primaryProto = pri; - m_secondaryProto = sec; - - return true; - } - - /** - * Set the subnet mask string for network broadcast requests If the subnet mask is not set a - * default broadcast mask for the TCP/IP address class will be used. - * - * @param subnet Subnet mask string, in 'nnn.nnn.nnn.nnn' format. - */ - public final static void setSubnetMask(String subnet) - { - NetBIOSSession.setSubnetMask(subnet); - } - - /** - * Setup the default SMB dialects to be negotiated when creating new sessions. - */ - private static void SetupDefaultDialects() - { - - // Initialize the default dialect list - - if (m_defDialects != null) - m_defDialects = new DialectSelector(); - else - m_defDialects.ClearAll(); - - // Always enable core protocol - - m_defDialects.AddDialect(Dialect.Core); - m_defDialects.AddDialect(Dialect.CorePlus); - m_defDialects.AddDialect(Dialect.DOSLanMan1); - m_defDialects.AddDialect(Dialect.DOSLanMan2); - m_defDialects.AddDialect(Dialect.LanMan1); - m_defDialects.AddDialect(Dialect.LanMan2); - m_defDialects.AddDialect(Dialect.LanMan2_1); - m_defDialects.AddDialect(Dialect.NT); - } - - /** - * Connect a NetBIOS network session - * - * @param toName Host name/address to connect to - * @param fromName Local host name/address - * @param tmo Timeout in seconds - * @return NetworkSession - * @exception IOException If a network error occurs - */ - private static final NetworkSession connectNetBIOSSession(String toName, String fromName, int tmo) - throws IOException - { - - // Connect to the requested server - - NetBIOSSession nbSession = new NetBIOSSession(tmo, getNetBIOSPort()); - - // Check if the remote host is specified as a TCP/IP address - - String toAddr = null; - NetBIOSName nbName = null; - - if (IPAddress.isNumericAddress(toName)) - { - - try - { - - // Get a list of NetBIOS names from the remote host - - toAddr = toName; - NetBIOSNameList nameList = NetBIOSSession.FindNamesForAddress(toAddr, 3); - - // Find the server service - - nbName = nameList.findName(NetBIOSName.FileServer, false); - if (nbName == null) - throw new IOException("Failed to convert server address to NetBIOS name"); - - // Set the remote name - - toName = nbName.getName(); - } - catch (UnknownHostException ex) - { - return null; - } - } - else - { - IOException savedException = null; - - try - { - - // Find the remote host and get a list of the network addresses it is using - - nbName = NetBIOSSession.FindName(toName, NetBIOSName.FileServer, 500); - } - catch (IOException ex) - { - savedException = ex; - } - - // If the NetBIOS name was not found then check if the local system has the name - - if (nbName == null) - { - - // Get a list of NetBIOS names for the local system - - NetBIOSNameList localList = NetBIOSSession.FindNamesForAddress(InetAddress.getLocalHost().getHostAddress()); - if (localList != null) - { - nbName = localList.findName(toName, NetBIOSName.FileServer, false); - if (nbName != null) - nbName.addIPAddress(InetAddress.getLocalHost().getAddress()); - else - throw savedException; - } - } - } - - // Check if the NetBIOS name scope has been set, if so then update the names to add the - // scope id - - if (hasNetBIOSNameScope()) - { - - // Add the NetBIOS scope id to the to/from NetBIOS names - - toName = toName + "." + getNetBIOSNameScope(); - fromName = fromName + "." + getNetBIOSNameScope(); - } - - // If the NetBIOS name has more than one TCP/IP address then find the best match for the - // client and - // try to connect on that address first, if that fails then we will have to try each address - // in turn. - - if (nbName.numberOfAddresses() > 1) - { - - // Get the local TCP/IP address list and search for a best match address to connect to - // the server on - - InetAddress[] addrList = getLocalTcpipAddresses(); - int addrIdx = nbName.findBestMatchAddress(addrList); - - if (addrIdx != -1) - { - - try - { - - // Get the server IP address - - String ipAddr = nbName.getIPAddressString(addrIdx); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Server is multi-homed, trying to connect to " + ipAddr); - - // Open the session to the remote host - - nbSession.Open(toName, fromName, ipAddr); - - // Check if the session is connected - - if (nbSession.isConnected() == false) - { - - // Close the session - - try - { - nbSession.Close(); - } - catch (Exception ex) - { - } - } - else if (logger.isDebugEnabled() && nbSession.isConnected()) - logger.debug("Connected to address " + ipAddr); - } - catch (IOException ex) - { - } - } - } - - // DEBUG - - if (logger.isDebugEnabled() && nbSession.isConnected() == false - && nbName.numberOfAddresses() > 1) - logger.debug("Server is multi-homed, trying all addresses"); - - // Loop through the available addresses for the remote file server until we get a successful - // connection, or all addresses have been used - - IOException lastException = null; - int addrIdx = 0; - - while (nbSession.isConnected() == false && addrIdx < nbName.numberOfAddresses()) - { - - try - { - - // Get the server IP address - - String ipAddr = nbName.getIPAddressString(addrIdx++); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Trying address " + ipAddr); - - // Open the session to the remote host - - nbSession.Open(toName, fromName, ipAddr); - - // Check if the session is connected - - if (nbSession.isConnected() == false) - { - - // Close the session - - try - { - nbSession.Close(); - } - catch (Exception ex) - { - } - } - else if (logger.isDebugEnabled() && nbSession.isConnected()) - logger.debug("Connected to address " + ipAddr); - } - catch (IOException ex) - { - - // Save the last exception - - lastException = ex; - } - } - - // Check if the session is connected - - if (nbSession.isConnected() == false) - { - - // If there is a saved exception rethrow it - - if (lastException != null) - throw lastException; - - // Indicate that the session was not connected - - return null; - } - - // Return the network session - - return nbSession; - } - - /** - * Connect a native SMB network session - * - * @param toName Host name/address to connect to - * @param fromName Local host name/address - * @param tmo Timeout in seconds - * @return NetworkSession - * @exception IOException If a network error occurs - */ - private static final NetworkSession connectNativeSMBSession(String toName, String fromName, int tmo) - throws IOException - { - - // Connect to the requested server - - TcpipSMBNetworkSession tcpSession = new TcpipSMBNetworkSession(tmo); - - try - { - - // Open the session - - tcpSession.Open(toName, fromName, null); - - // Check if the session is connected - - if (tcpSession.isConnected() == false) - { - - // Close the session - - try - { - tcpSession.Close(); - } - catch (Exception ex) - { - } - - // Return a null session - - return null; - } - } - catch (Exception ex) - { - try - { - tcpSession.Close(); - } - catch (Exception ex2) - { - } - tcpSession = null; - } - - // Return the network session - - return tcpSession; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/AuthenticateSession.java b/source/java/org/alfresco/filesys/server/auth/passthru/AuthenticateSession.java deleted file mode 100644 index f2b392c526..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/AuthenticateSession.java +++ /dev/null @@ -1,1653 +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.server.auth.passthru; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.auth.PasswordEncryptor; -import org.alfresco.filesys.server.auth.ntlm.NTLM; -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.smb.Capability; -import org.alfresco.filesys.smb.Dialect; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.NetworkSession; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Authenticate Session Class - *

- * Used for passthru authentication mechanisms. - */ -public class AuthenticateSession -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth"); - - // Default packet size - - private static final int DefaultPacketSize = 1024; - - // Session security mode - - public static final int SecurityModeUser = 1; - public static final int SecurityModeShare = 2; - - // Tree identifier that indicates that the disk session has been closed - - protected final static int Closed = -1; - - // Default SMB packet size to allocate - - public static final int DEFAULT_BUFSIZE = 4096; - - // SMB dialect id and string for this session - - private int m_dialect; - private String m_diaStr; - - // Network session - - private NetworkSession m_netSession; - - // SMB packet for protocol exhanges - - protected SMBPacket m_pkt; - - // Default packet flags - - private int m_defFlags = SMBPacket.FLG_CASELESS; - private int m_defFlags2 = SMBPacket.FLG2_LONGFILENAMES; - - // Server connection details - - private PCShare m_remoteShr; - - // Domain name - - private String m_domain; - - // Remote operating system and LAN manager type - - private String m_srvOS; - private String m_srvLM; - - // Security mode (user or share) - - private int m_secMode; - - // Challenge encryption key - - private byte[] m_encryptKey; - - // SMB session information - - private int m_sessIdx; - private int m_userId; - private int m_processId; - - // Tree identifier for this connection - - protected int m_treeid; - - // Device type that this session is connected to - - private int m_devtype; - - // Maximum transmit buffer size allowed - - private int m_maxPktSize; - - // Session capabilities - - private int m_sessCaps; - - // Maximum virtual circuits allowed on this session, and maximum multiplxed read/writes - - private int m_maxVCs; - private int m_maxMPX; - - // Indicate if the session was created as a guest rather than using the supplied - // username/password - - private boolean m_guest; - - // Flag to indicate extended security exchange is being used - - private boolean m_extendedSec; - - // Server GUID, if using extended security - - private byte[] m_serverGUID; - - // Type 2 security blob from the server - - private Type2NTLMMessage m_type2Msg; - - // Global session id - - private static int m_sessionIdx = 1; - - // Multiplex id - - private static int m_multiplexId = 1; - - /** - * Class constructor - * - * @param shr PCShare - * @param sess NetworkSession - * @param dialect int - * @param pkt SMBPacket - * @exception IOException If a network error occurs - * @eception SMBException If a CIFS error occurs - */ - protected AuthenticateSession(PCShare shr, NetworkSession sess, int dialect, SMBPacket pkt) throws IOException, SMBException - { - - // Set the SMB dialect for this session - - m_dialect = dialect; - - // Save the remote share details - - m_remoteShr = shr; - - // Allocate a unique session index - - m_sessIdx = getNextSessionId(); - - // Allocate an SMB protocol packet - - m_pkt = pkt; - if (pkt == null) - m_pkt = new SMBPacket(DEFAULT_BUFSIZE); - - // Save the session and packet - - setSession(sess); - - // Extract the details from the negotiate response packet - - processNegotiateResponse(); - } - - /** - * Allocate an SMB packet for this session. The preferred packet size is specified, if a smaller - * buffer size has been negotiated a smaller SMB packet will be returned. - * - * @param pref Preferred SMB packet size - * @return Allocated SMB packet - */ - protected final SMBPacket allocatePacket(int pref) - { - - // Check if the preferred size is larger than the maximum allowed packet - // size for this session. - - if (pref > m_maxPktSize) - return new SMBPacket(m_maxPktSize + RFCNetBIOSProtocol.HEADER_LEN); - - // Return the preferred SMB packet size - - return new SMBPacket(pref + RFCNetBIOSProtocol.HEADER_LEN); - } - - /** - * Determine if the session supports extended security - * - * @return true if this session supports extended security, else false - */ - public final boolean supportsExtendedSecurity() - { - return (m_sessCaps & Capability.ExtendedSecurity) != 0 ? true : false; - } - - /** - * Determine if the session supports raw mode read/writes - * - * @return true if this session supports raw mode, else false - */ - public final boolean supportsRawMode() - { - return (m_sessCaps & Capability.RawMode) != 0 ? true : false; - } - - /** - * Determine if the session supports Unicode - * - * @return boolean - */ - public final boolean supportsUnicode() - { - return (m_sessCaps & Capability.Unicode) != 0 ? true : false; - } - - /** - * Determine if the session supports large files (ie. 64 bit file offsets) - * - * @return boolean - */ - public final boolean supportsLargeFiles() - { - return (m_sessCaps & Capability.LargeFiles) != 0 ? true : false; - } - - /** - * Determine if the session supports NT specific SMBs - * - * @return boolean - */ - public final boolean supportsNTSmbs() - { - return (m_sessCaps & Capability.NTSMBs) != 0 ? true : false; - } - - /** - * Determine if the session supports RPC API requests - * - * @return boolean - */ - public final boolean supportsRPCAPIs() - { - return (m_sessCaps & Capability.RemoteAPIs) != 0 ? true : false; - } - - /** - * Determine if the session supports NT status codes - * - * @return boolean - */ - public final boolean supportsNTStatusCodes() - { - return (m_sessCaps & Capability.NTStatus) != 0 ? true : false; - } - - /** - * Determine if the session supports level 2 oplocks - * - * @return boolean - */ - public final boolean supportsLevel2Oplocks() - { - return (m_sessCaps & Capability.Level2Oplocks) != 0 ? true : false; - } - - /** - * Determine if the session supports lock and read - * - * @return boolean - */ - public final boolean supportsLockAndRead() - { - return (m_sessCaps & Capability.LockAndRead) != 0 ? true : false; - } - - /** - * Determine if the session supports NT find - * - * @return boolean - */ - public final boolean supportsNTFind() - { - return (m_sessCaps & Capability.NTFind) != 0 ? true : false; - } - - /** - * Close this connection with the remote server. - * - * @exception java.io.IOException If an I/O error occurs. - * @exception SMBException If an SMB level error occurs - */ - public void CloseSession() throws java.io.IOException, SMBException - { - - // If the session is valid then hangup the session - - if (isActive()) - { - - // Close the network session - - m_netSession.Close(); - - // Clear the session - - m_netSession = null; - } - } - - /** - * Return the default flags settings for this session - * - * @return int - */ - public final int getDefaultFlags() - { - return m_defFlags; - } - - /** - * Return the default flags2 settings for this session - * - * @return int - */ - public final int getDefaultFlags2() - { - return m_defFlags2; - } - - /** - * Get the device type that this session is connected to. - * - * @return Device type for this session. - */ - public final int getDeviceType() - { - return m_devtype; - } - - /** - * Get the SMB dialect property - * - * @return SMB dialect that this session has negotiated. - */ - public final int getDialect() - { - return m_dialect; - } - - /** - * Get the SMB dialect string - * - * @return SMB dialect string for this session. - */ - public final String getDialectString() - { - return m_diaStr; - } - - /** - * Get the servers primary domain name - * - * @return Servers primary domain name, if knwon, else null. - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Determine if there is a challenge encryption key - * - * @return boolean - */ - public final boolean hasEncryptionKey() - { - return m_encryptKey != null ? true : false; - } - - /** - * Return the cahllenge encryption key - * - * @return byte[] - */ - public final byte[] getEncryptionKey() - { - return m_encryptKey; - } - - /** - * Get the servers LAN manager type - * - * @return Servers LAN manager type, if known, else null. - */ - public final String getLANManagerType() - { - return m_srvLM; - } - - /** - * Get the maximum number of multiplxed requests that are allowed - * - * @return int - */ - public final int getMaximumMultiplexedRequests() - { - return m_maxMPX; - } - - /** - * Get the maximum packet size allowed for this session - * - * @return Maximum packet size, in bytes. - */ - public final int getMaximumPacketSize() - { - return m_maxPktSize; - } - - /** - * Get the maximum virtual circuits allowed on this session - * - * @return int - */ - public final int getMaximumVirtualCircuits() - { - return m_maxVCs; - } - - /** - * Get the next multiplex id to uniquely identify a transaction - * - * @return Unique multiplex id for a transaction - */ - public final synchronized int getNextMultiplexId() - { - return m_multiplexId++; - } - - /** - * Get the next session id - * - * @return int - */ - protected final synchronized int getNextSessionId() - { - return m_sessionIdx++; - } - - /** - * Get the servers operating system type - * - * @return Servers operating system, if known, else null. - */ - public final String getOperatingSystem() - { - return m_srvOS; - } - - /** - * Get the remote share password string - * - * @return Remote share password string - */ - public final String getPassword() - { - return m_remoteShr.getPassword(); - } - - /** - * Get the remote share details for this session - * - * @return PCShare information for this session - */ - public final PCShare getPCShare() - { - return m_remoteShr; - } - - /** - * Return the security mode of the session (user or share) - * - * @return int - */ - public final int getSecurityMode() - { - return m_secMode; - } - - /** - * Get the remote server name - * - * @return Remote server name - */ - public final String getServer() - { - return m_remoteShr.getNodeName(); - } - - /** - * Access the associated network session - * - * @return NetworkSession that the SMB session is using - */ - public final NetworkSession getSession() - { - return m_netSession; - } - - /** - * Determine if the session has an associated type2 NTLM security blob - * - * @return boolean - */ - public final boolean hasType2NTLMMessage() - { - return m_type2Msg != null ? true : false; - } - - /** - * Return the type2 NTLM security blob that was received from the authentication server - * - * @return Type2NTLMMessage - */ - public final Type2NTLMMessage getType2NTLMMessage() - { - return m_type2Msg; - } - - /** - * Return the session capability flags. - * - * @return int - */ - public final int getCapabilities() - { - return m_sessCaps; - } - - /** - * Get the process id for this session - * - * @return int - */ - public final int getProcessId() - { - return m_processId; - } - - /** - * Get the session identifier property - * - * @return Session identifier - */ - public final int getSessionId() - { - return m_sessIdx; - } - - /** - * Get the remote share name - * - * @return Remote share name string - */ - public final String getShareName() - { - return m_remoteShr.getShareName(); - } - - /** - * Get the connected tree identifier. - * - * @return Tree identifier. - */ - public final int getTreeId() - { - return m_treeid; - } - - /** - * Return the assigned use id for this SMB session - * - * @return Assigned user id - */ - public final int getUserId() - { - return m_userId; - } - - /** - * Get the remote share user name string - * - * @return Remote share user name string - */ - public final String getUserName() - { - return m_remoteShr.getUserName(); - } - - /** - * Check if there is data available in the network receive buffer - * - * @return boolean - * @exception IOException - */ - public final boolean hasDataAvailable() throws IOException - { - return m_netSession.hasData(); - } - - /** - * Determine if the session is valid, ie. still open. - * - * @return true if the session is still active, else false. - */ - public final boolean isActive() - { - return (m_netSession == null) ? false : true; - } - - /** - * Determine if the session has been created as a guest logon - * - * @return boolean - */ - public final boolean isGuest() - { - return m_guest; - } - - /** - * Determine if the Unicode flag is enabled - * - * @return boolean - */ - public final boolean isUnicode() - { - return (m_defFlags2 & SMBPacket.FLG2_UNICODE) != 0 ? true : false; - } - - /** - * Determine if extended security exchanges are being used - * - * @return boolean - */ - public final boolean isUsingExtendedSecurity() - { - return m_extendedSec; - } - - /** - * Send a single echo request to the server - * - * @throws java.io.IOException - * @throws SMBException - */ - public final void pingServer() throws java.io.IOException, SMBException - { - - // Send a single echo request to the server - - pingServer(1); - } - - /** - * Send an echo request to the server - * - * @param cnt Number of packets to echo from the remote server - * @exception java.io.IOException If an I/O error occurs - * @exception SMBException SMB error occurred - */ - public final void pingServer(int cnt) throws java.io.IOException, SMBException - { - - // Build a server ping SMB packet - - m_pkt.setCommand(PacketType.Echo); - m_pkt.setFlags(0); - m_pkt.setTreeId(getTreeId()); - m_pkt.setUserId(getUserId()); - m_pkt.setProcessId(getProcessId()); - m_pkt.setMultiplexId(1); - - // Set the parameter words - - m_pkt.setParameterCount(1); - m_pkt.setParameter(0, cnt); // number of packets that the server should return - String echoStr = "ECHO"; - m_pkt.setBytes(echoStr.getBytes()); - - // Send the echo request - - m_pkt.SendSMB(this); - - // Receive the reply packets, if any - - while (cnt > 0) - { - - // Receive a reply packet - - m_pkt.ReceiveSMB(this); - - // Decrement the reply counter - - cnt--; - } - } - - /** - * Set the default SMB packet flags for this session - * - * @param flg int - */ - protected final void setDefaultFlags(int flg) - { - m_defFlags = flg; - } - - /** - * Set the SMB packet default flags2 for this session - * - * @param flg2 int - */ - protected final void setDefaultFlags2(int flg2) - { - m_defFlags2 = flg2; - } - - /** - * Set the device type for this session. - * - * @param dev Device type for this session. - */ - protected final void setDeviceType(int dev) - { - m_devtype = dev; - } - - /** - * Set the dialect for this session - * - * @param dia SMB dialect that this session is using. - */ - protected final void setDialect(int dia) - { - m_dialect = dia; - } - - /** - * Set the dialect string for this session - * - * @param dia SMB dialect string - */ - protected final void setDialectString(String dia) - { - m_diaStr = dia; - } - - /** - * Set the remote servers primary domain name - * - * @param dom Servers primary domain name. - */ - protected final void setDomain(String dom) - { - m_domain = dom; - } - - /** - * Set the encryption key - * - * @param key byte[] - */ - public final void setEncryptionKey(byte[] key) - { - - // Set the challenge response encryption key - - m_encryptKey = key; - } - - /** - * Set the guest status for the session - * - * @param sts boolean - */ - protected final void setGuest(boolean sts) - { - m_guest = sts; - } - - /** - * Set the remote servers LAN manager type - * - * @param lm Servers LAN manager type string. - */ - protected final void setLANManagerType(String lm) - { - m_srvLM = lm; - } - - /** - * Set the maximum number of multiplexed requests allowed - * - * @param maxMulti int - */ - protected final void setMaximumMultiplexedRequests(int maxMulti) - { - m_maxMPX = maxMulti; - } - - /** - * Set the maximum packet size allowed on this session - * - * @param siz Maximum allowed packet size. - */ - protected final void setMaximumPacketSize(int siz) - { - m_maxPktSize = siz; - } - - /** - * Set the maximum number of virtual circuits allowed on this session - * - * @param maxVC int - */ - protected final void setMaximumVirtualCircuits(int maxVC) - { - m_maxVCs = maxVC; - } - - /** - * Set the remote servers operating system type - * - * @param os Servers operating system type string. - */ - protected final void setOperatingSystem(String os) - { - m_srvOS = os; - } - - /** - * Set the remote share password - * - * @param pwd Remtoe share password string. - */ - protected final void setPassword(String pwd) - { - m_remoteShr.setPassword(pwd); - } - - /** - * Set the session security mode (user or share) - * - * @param secMode int - */ - public final void setSecurityMode(int secMode) - { - m_secMode = secMode; - } - - /** - * Set the remote server name - * - * @param srv Server name string - */ - protected final void setServer(String srv) - { - m_remoteShr.setNodeName(srv); - } - - /** - * Set the network session that this SMB session is associated with - * - * @param netSess Network session that this SMB session is to be associated with. - */ - protected final void setSession(NetworkSession netSess) - { - m_netSession = netSess; - } - - /** - * Set the session capability flags - * - * @param flg Capability flags. - */ - protected final void setCapabilities(int caps) - { - m_sessCaps = caps; - } - - /** - * Set the remote share name - * - * @param shr Remote share name string - */ - protected final void setShareName(String shr) - { - m_remoteShr.setShareName(shr); - } - - /** - * Set the process id for this session - * - * @param id - */ - protected final void setProcessId(int id) - { - m_processId = id; - } - - /** - * Set the connected tree identifier for this session. - * - * @param id Tree identifier for this session. - */ - protected final void setTreeId(int id) - { - m_treeid = id; - } - - /** - * Set the user identifier for this session - * - * @param uid User identifier - */ - protected final void setUserId(int uid) - { - m_userId = uid; - } - - /** - * Set the remote share user name - * - * @param user Remote share user name string - */ - protected final void setUserName(String user) - { - m_remoteShr.setUserName(user); - } - - /** - * Output the session details as a string - * - * @return Session details string - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("[\\\\"); - str.append(getServer()); - str.append("\\"); - str.append(getShareName()); - str.append(":"); - str.append(Dialect.DialectTypeString(m_dialect)); - str.append(",UserId="); - str.append(getUserId()); - str.append("]"); - - return str.toString(); - } - - /** - * Perform a session setup to create a session on the remote server validating the user. - * - * @param userName String - * @param ascPwd ASCII password hash - * @param uniPwd Unicode password hash - * @exception IOException If a network error occurs - * @exception SMBException If a CIFS error occurs - */ - public final void doSessionSetup(String userName, byte[] ascPwd, byte[] uniPwd) throws IOException, SMBException - { - doSessionSetup(null, userName, null, ascPwd, uniPwd, 0); - } - - /** - * Perform a session using the type3 NTLM response received from the client - * - * @param type3 Type3NTLMMessage - * @exception IOException If a network error occurs - * @exception SMBException If a CIFS error occurs - */ - public final void doSessionSetup(Type3NTLMMessage type3Msg) throws IOException, SMBException - { - doSessionSetup(type3Msg.getDomain(), type3Msg.getUserName(), type3Msg.getWorkstation(), - type3Msg.getLMHash(), type3Msg.getNTLMHash(), 0); - } - - /** - * Perform a session setup to create a session on the remote server validating the user. - * - * @param domain String - * @param userName String - * @param wksName String - * @param ascPwd ASCII password hash - * @param uniPwd Unicode password hash - * @param vcNum Virtual circuit number - * @exception IOException If a network error occurs - * @exception SMBException If a CIFS error occurs - */ - public final void doSessionSetup(String domain, String userName, String wksName, - byte[] ascPwd, byte[] uniPwd, int vcNum) - throws IOException, SMBException - { - // Check if we are using extended security - - if ( isUsingExtendedSecurity()) - { - // Run the second phase of the extended security session setup - - doExtendedSessionSetupPhase2(domain, userName, wksName, ascPwd, uniPwd, vcNum); - return; - } - - // Create a session setup packet - - SMBPacket pkt = new SMBPacket(); - - pkt.setCommand(PacketType.SessionSetupAndX); - - // Check if the negotiated SMB dialect is NT LM 1.2 or an earlier dialect - - if (getDialect() == Dialect.NT) - { - - // NT LM 1.2 SMB dialect - - pkt.setParameterCount(13); - pkt.setAndXCommand(0xFF); // no secondary command - pkt.setParameter(1, 0); // offset to next command - pkt.setParameter(2, DefaultPacketSize); - pkt.setParameter(3, 1); - pkt.setParameter(4, vcNum); - pkt.setParameterLong(5, 0); // session key - - // Set the share password length(s) - - pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0); // ANSI password length - pkt.setParameter(8, uniPwd != null ? uniPwd.length : 0); // Unicode password length - - pkt.setParameter(9, 0); // reserved, must be zero - pkt.setParameter(10, 0); // reserved, must be zero - - // Send the client capabilities - - int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus - + Capability.RemoteAPIs; - - // Set the client capabilities - - pkt.setParameterLong(11, caps); - - // Get the offset to the session setup request byte data - - int pos = pkt.getByteOffset(); - pkt.setPosition(pos); - - // Store the ASCII password hash, if specified - - if (ascPwd != null) - pkt.packBytes(ascPwd, ascPwd.length); - - // Store the Unicode password hash, if specified - - if (uniPwd != null) - pkt.packBytes(uniPwd, uniPwd.length); - - // Pack the account/client details - - pkt.packString(userName, false); - - // Check if the share has a domain, if not then use the default domain string - - if (getPCShare().hasDomain()) - pkt.packString(getPCShare().getDomain(), false); - else if ( domain != null) - pkt.packString( domain, false); - else - pkt.packString("?", false); - - pkt.packString("Java VM", false); - pkt.packString("Alfresco CIFS", false); - - // Set the packet length - - pkt.setByteCount(pkt.getPosition() - pos); - } - else - { - - // Earlier SMB dialect - - pkt.setUserId(1); - - pkt.setParameterCount(10); - pkt.setAndXCommand(0xFF); - pkt.setParameter(1, 0); - pkt.setParameter(2, DefaultPacketSize); - pkt.setParameter(3, 1); - pkt.setParameter(4, 0); - pkt.setParameter(5, 0); - pkt.setParameter(6, 0); - pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0); - pkt.setParameter(8, 0); - pkt.setParameter(9, 0); - - // Put the password into the SMB packet - - byte[] buf = pkt.getBuffer(); - int pos = pkt.getByteOffset(); - - if (ascPwd != null) - { - for (int i = 0; i < ascPwd.length; i++) - buf[pos++] = ascPwd[i]; - } - - // Build the account/client details - - StringBuffer clbuf = new StringBuffer(); - - clbuf.append(getPCShare().getUserName()); - clbuf.append((char) 0x00); - - // Check if the share has a domain, if not then use the unknown domain string - - if (getPCShare().hasDomain()) - clbuf.append(getPCShare().getDomain()); - else - clbuf.append("?"); - clbuf.append((char) 0x00); - - clbuf.append("Java VM"); - clbuf.append((char) 0x00); - - clbuf.append("Alfresco CIFS"); - clbuf.append((char) 0x00); - - // Copy the remaining data to the SMB packet - - byte[] byts = clbuf.toString().getBytes(); - for (int i = 0; i < byts.length; i++) - buf[pos++] = byts[i]; - - int pwdLen = ascPwd != null ? ascPwd.length : 0; - pkt.setByteCount(pwdLen + byts.length); - } - - // Exchange an SMB session setup packet with the remote file server - - pkt.ExchangeSMB(this, pkt, true); - - // Save the session user id - - setUserId(pkt.getUserId()); - - // Check if the session was created as a guest - - if (pkt.getParameterCount() >= 3) - { - - // Set the guest status for the session - - setGuest(pkt.getParameter(2) != 0 ? true : false); - } - - // The response packet should also have the server OS, LAN Manager type - // and primary domain name. - - if (pkt.getByteCount() > 0) - { - - // Get the packet buffer and byte offset - - byte[] buf = pkt.getBuffer(); - int offset = pkt.getByteOffset(); - int maxlen = offset + pkt.getByteCount(); - - // Get the server OS - - String srvOS = DataPacker.getString(buf, offset, maxlen); - setOperatingSystem(srvOS); - - offset += srvOS.length() + 1; - maxlen -= srvOS.length() + 1; - - // Get the LAN Manager type - - String lanman = DataPacker.getString(buf, offset, maxlen); - setLANManagerType(lanman); - - // Check if we have the primary domain for this session - - if (getDomain() == null || getDomain().length() == 0) - { - - // Get the domain name string - - offset += lanman.length() + 1; - maxlen += lanman.length() + 1; - - String dom = DataPacker.getString(buf, offset, maxlen); - setDomain(dom); - } - } - - // Check for a core protocol session, set the maximum packet size - - if (getDialect() == Dialect.Core || getDialect() == Dialect.CorePlus) - { - - // Set the maximum packet size to be used on this session - - setMaximumPacketSize(pkt.getParameter(2)); - } - } - - /** - * Process the negotiate response SMB packet - * - * @exception IOException If a network error occurs - * @eception SMBException If a CIFS error occurs - */ - private void processNegotiateResponse() throws IOException, SMBException - { - - // Set the security mode flags - - int keyLen = 0; - boolean unicodeStr = false; - int encAlgorithm = PasswordEncryptor.LANMAN; - int defFlags2 = 0; - - if (getDialect() == Dialect.NT) - { - // Read the returned negotiate parameters, for NT dialect the parameters are not aligned - - m_pkt.resetParameterPointer(); - m_pkt.skipBytes(2); // skip the dialect index - - setSecurityMode(m_pkt.unpackByte()); - - // Set the maximum virtual circuits and multiplxed requests allowed by the server - - setMaximumMultiplexedRequests(m_pkt.unpackWord()); - setMaximumVirtualCircuits(m_pkt.unpackWord()); - - // Set the maximum buffer size - - setMaximumPacketSize(m_pkt.unpackInt()); - - // Skip the maximum raw buffer size and session key - - m_pkt.skipBytes(8); - - // Set the server capabailities - - setCapabilities(m_pkt.unpackInt()); - - // Check if extended security is enabled - - if ( supportsExtendedSecurity()) - m_extendedSec = true; - - // Get the server system time and timezone - - SMBDate srvTime = NTTime.toSMBDate(m_pkt.unpackLong()); - int tzone = m_pkt.unpackWord(); - - // Get the encryption key length - - keyLen = m_pkt.unpackByte(); - - // Indicate that strings are UniCode - - unicodeStr = true; - - // Use NTLMv1 password encryption - - encAlgorithm = PasswordEncryptor.NTLM1; - - // Set the default flags for subsequent SMB requests - - defFlags2 = SMBPacket.FLG2_LONGFILENAMES + SMBPacket.FLG2_UNICODE + SMBPacket.FLG2_LONGERRORCODE + SMBPacket.FLG2_SECURITYSIG; - - if ( isUsingExtendedSecurity()) - defFlags2 += SMBPacket.FLG2_EXTENDEDSECURITY; - } - else if (getDialect() > Dialect.CorePlus) - { - - // Set the security mode and encrypted password mode - - int secMode = m_pkt.getParameter(1); - setSecurityMode((secMode & 0x01) != 0 ? SecurityModeUser : SecurityModeShare); - - if (m_pkt.getParameterCount() >= 11) - keyLen = m_pkt.getParameter(11) & 0xFF; // should always be 8 - - // Set the maximum virtual circuits and multiplxed requests allowed by the server - - setMaximumMultiplexedRequests(m_pkt.getParameter(3)); - setMaximumVirtualCircuits(m_pkt.getParameter(4)); - - // Check if Unicode strings are being used - - if (m_pkt.isUnicode()) - unicodeStr = true; - - // Set the default flags for subsequent SMB requests - - defFlags2 = SMBPacket.FLG2_LONGFILENAMES; - } - - // Set the default packet flags for this session - - setDefaultFlags2(defFlags2); - - // Get the server details from the negotiate SMB packet - - if (m_pkt.getByteCount() > 0) - { - - // Get the returned byte area length and offset - - int bytsiz = m_pkt.getByteCount(); - int bytpos = m_pkt.getByteOffset(); - byte[] buf = m_pkt.getBuffer(); - - // Original format response - - if ( isUsingExtendedSecurity() == false) - { - // Extract the challenge response key, if specified - - if (keyLen > 0) - { - - // Allocate a buffer for the challenge response key - - byte[] encryptKey = new byte[keyLen]; - - // Copy the challenge response key - - for (int keyIdx = 0; keyIdx < keyLen; keyIdx++) - encryptKey[keyIdx] = buf[bytpos++]; - - // Set the sessions encryption key - - setEncryptionKey(encryptKey); - } - - // Extract the domain name - - String dom; - - if (unicodeStr == false) - dom = DataPacker.getString(buf, bytpos, bytsiz); - else - dom = DataPacker.getUnicodeString(buf, bytpos, bytsiz / 2); - setDomain(dom); - } - else - { - // Extract the server GUID - - m_serverGUID = new byte[16]; - System.arraycopy(buf, bytpos, m_serverGUID, 0, 16); - - // Run the first phase of the extended security session setup to get the challenge - // from the server - - doExtendedSessionSetupPhase1(); - } - } - } - - /** - * Send the first stage of the extended security session setup - * - * @exception IOException If a network error occurs - * @eception SMBException If a CIFS error occurs - */ - private final void doExtendedSessionSetupPhase1() throws IOException, SMBException - { - // Create a session setup packet - - SMBPacket pkt = new SMBPacket(); - - pkt.setCommand(PacketType.SessionSetupAndX); - - pkt.setFlags(getDefaultFlags()); - pkt.setFlags2(getDefaultFlags2()); - - // Build the extended session setup phase 1 request - - pkt.setParameterCount(12); - pkt.setAndXCommand(0xFF); // no secondary command - pkt.setParameter(1, 0); // offset to next command - pkt.setParameter(2, DefaultPacketSize); - pkt.setParameter(3, 1); - pkt.setParameter(4, 0); // virtual circuit number - pkt.setParameterLong(5, 0); // session key - - // Clear the security blob length and reserved area - - pkt.setParameter(7, 0); // security blob length - pkt.setParameterLong(8, 0); // reserved - - // Send the client capabilities - - int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus - + Capability.RemoteAPIs + Capability.ExtendedSecurity; - - // Set the client capabilities - - pkt.setParameterLong(10, caps); - - // Get the offset to the session setup request byte data - - int pos = pkt.getByteOffset(); - pkt.setPosition(pos); - - // Create a type 1 NTLM message using the session setup request buffer - - Type1NTLMMessage type1Msg = new Type1NTLMMessage(pkt.getBuffer(), pos, 0); - - int type1Flags = getPCShare().getExtendedSecurityFlags(); - if ( type1Flags == 0) - type1Flags = NTLM.FlagNegotiateUnicode + NTLM.FlagNegotiateNTLM + NTLM.FlagRequestTarget; - - type1Msg.buildType1(type1Flags, null, null); - - // Update the request buffer position - - pkt.setPosition(pos + type1Msg.getLength()); - - // Set the security blob length - - pkt.setParameter(7, type1Msg.getLength()); - - // Pack the OS details - - pkt.packString("Java VM", true); - pkt.packString("Alfresco CIFS", true); - - pkt.packString("", true); - - // Set the packet length - - pkt.setByteCount(pkt.getPosition() - pos); - - // Exchange an SMB session setup packet with the remote file server - - pkt.ExchangeSMB(this, pkt, false); - - // Check the error status, should be a warning status to indicate more processing required - - if ( pkt.isLongErrorCode() == false || pkt.getLongErrorCode() != SMBStatus.NTMoreProcessingRequired) - pkt.checkForError(); - - // Save the session user id - - setUserId(pkt.getUserId()); - - // The response packet should also have the type 2 security blob - - int type2Len = pkt.getParameter(3); - if (pkt.getByteCount() > 0) - { - - // Get the packet buffer and byte offset - - byte[] buf = pkt.getBuffer(); - int offset = pkt.getByteOffset(); - int maxlen = offset + pkt.getByteCount(); - - // Take a copy of the type 2 security blob - - m_type2Msg = new Type2NTLMMessage(); - m_type2Msg.copyFrom(buf, offset, type2Len); - - // Get the encryption key from the security blob - - m_encryptKey = m_type2Msg.getChallenge(); - - // Update the byte area offset and align - - offset = DataPacker.wordAlign(offset + type2Len); - maxlen -= type2Len; - - // Get the server OS - - String srvOS = DataPacker.getString(buf, offset, maxlen); - setOperatingSystem(srvOS); - - offset += srvOS.length() + 1; - maxlen -= srvOS.length() + 1; - - // Get the LAN Manager type - - String lanman = DataPacker.getString(buf, offset, maxlen); - setLANManagerType(lanman); - } - } - - /** - * Send the second stage of the extended security session setup - * - * @param domain String - * @param userName String - * @param wksName String - * @param lmPwd byte[] - * @param ntlmPwd byte[] - * @param vcNum int - * @exception IOException If a network error occurs - * @eception SMBException If a CIFS error occurs - */ - private final void doExtendedSessionSetupPhase2(String domain, String userName, String wksName, - byte[] lmPwd, byte[] ntlmPwd, int vcNum) throws IOException, SMBException - { - // Check if the domain name has been specified, if not then use the domain name from the - // original connection details or the servers domain name - - if ( domain == null) - { - if ( getPCShare().hasDomain() && getPCShare().getDomain().length() > 0) - domain = getPCShare().getDomain(); - else - domain = m_type2Msg.getTarget(); - } - - // Create a session setup packet - - SMBPacket pkt = new SMBPacket(); - - pkt.setCommand(PacketType.SessionSetupAndX); - - pkt.setFlags(getDefaultFlags()); - pkt.setFlags2(getDefaultFlags2()); - - pkt.setUserId(getUserId()); - - // Build the extended session setup phase 2 request - - pkt.setParameterCount(12); - pkt.setAndXCommand(0xFF); // no secondary command - pkt.setParameter(1, 0); // offset to next command - pkt.setParameter(2, DefaultPacketSize); - pkt.setParameter(3, 1); - pkt.setParameter(4, vcNum); - pkt.setParameterLong(5, 0); // session key - - // Clear the security blob length and reserved area - - pkt.setParameter(7, 0); // security blob length - pkt.setParameterLong(8, 0); // reserved - - // Send the client capabilities - - int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus - + Capability.RemoteAPIs + Capability.ExtendedSecurity; - - // Set the client capabilities - - pkt.setParameterLong(10, caps); - - // Get the offset to the session setup request byte data - - int pos = pkt.getByteOffset(); - pkt.setPosition(pos); - - // Create a type 3 NTLM message using the session setup request buffer - - Type3NTLMMessage type3Msg = new Type3NTLMMessage(pkt.getBuffer(), pos, 0, true); - - type3Msg.buildType3(lmPwd, ntlmPwd, domain, userName, wksName != null ? wksName : "", null, m_type2Msg.getFlags()); - - // Update the request buffer position - - pkt.setPosition(pos + type3Msg.getLength()); - - // Set the security blob length - - pkt.setParameter(7, type3Msg.getLength()); - - // Pack the OS details - - pkt.packString("Java VM", true); - pkt.packString("Alfresco CIFS", true); - - pkt.packString("", true); - - // Set the packet length - - pkt.setByteCount(pkt.getPosition() - pos); - - // Exchange an SMB session setup packet with the remote file server - - pkt.ExchangeSMB(this, pkt, true); - - // Set the guest status for the session - - setGuest(pkt.getParameter(2) != 0 ? true : false); - } - -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/DomainMapping.java b/source/java/org/alfresco/filesys/server/auth/passthru/DomainMapping.java deleted file mode 100644 index e890a354a6..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/DomainMapping.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2006 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -package org.alfresco.filesys.server.auth.passthru; - -/** - * Domain Mapping Class - * - * @author gkspencer - */ -public abstract class DomainMapping { - - // Domain name - - private String m_domain; - - /** - * Class consructor - * - * @param domain String - */ - public DomainMapping( String domain) - { - m_domain = domain; - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Check if the client address is a member of this domain - * - * @param clientIP int - * @return boolean - */ - public abstract boolean isMemberOfDomain( int clientIP); -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruDetails.java b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruDetails.java deleted file mode 100644 index 1fc9b5a6a2..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruDetails.java +++ /dev/null @@ -1,105 +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.server.auth.passthru; - -import org.alfresco.filesys.server.SrvSession; - -/** - * Passthru Details Class - *

- * Contains the details of a passthru connection to a remote server and the local session that the - * request originated from. - */ -class PassthruDetails -{ - // Server session - - private SrvSession m_sess; - - // Authentication session connected to the remote server - - private AuthenticateSession m_authSess; - - // Flag to indicate if session should be kept alive - - private boolean m_keepAlive; - - /** - * Class constructor - * - * @param sess SrvSession - * @param authSess AuthenticateSession - */ - public PassthruDetails(SrvSession sess, AuthenticateSession authSess) - { - m_sess = sess; - m_authSess = authSess; - } - - /** - * Class constructor - * - * @param sess SrvSession - * @param authSess AuthenticateSession - * @param keepAlive boolean - */ - public PassthruDetails(SrvSession sess, AuthenticateSession authSess, boolean keepAlive) - { - m_sess = sess; - m_authSess = authSess; - - m_keepAlive = keepAlive; - } - - /** - * Return the session details - * - * @return SrvSession - */ - public final SrvSession getSession() - { - return m_sess; - } - - /** - * Return the authentication session that is connected to the remote server - * - * @return AuthenticateSession - */ - public final AuthenticateSession getAuthenticateSession() - { - return m_authSess; - } - - /** - * Check if the authentication session should be kept alive - * - * @return boolean - */ - public final boolean hasKeepAlive() - { - return m_keepAlive; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServerDetails.java b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServerDetails.java deleted file mode 100644 index adbfdad738..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServerDetails.java +++ /dev/null @@ -1,198 +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.server.auth.passthru; - -import java.net.*; -import java.util.*; - -/** - *

Contains the details of a server used for passthru authentication, the current status of the server - * and count of authentications done via this server. - * - * @author GKSpencer - */ -public class PassthruServerDetails -{ - // Server details - - private String m_name; - private String m_domain; - private InetAddress m_address; - - // Server status - - private boolean m_online; - - // Authentication statistics - - private int m_authCount; - private long m_lastAuthTime; - - /** - * Class constructor - * - * @param name String - * @param domain String - * @param addr InetAddress - * @param online boolean - */ - PassthruServerDetails(String name, String domain, InetAddress addr, boolean online) - { - m_name = name; - m_domain = domain; - m_address = addr; - m_online = online; - } - - /** - * Return the server name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Return the server address - * - * @return InetAddress - */ - public final InetAddress getAddress() - { - return m_address; - } - - /** - * Return the online status of the server - * - * @return boolean - */ - public final boolean isOnline() - { - return m_online; - } - - /** - * Return the authentication count for the server - * - * @return int - */ - public final int getAuthenticationCount() - { - return m_authCount; - } - - /** - * Return the date/time of the last authentication by this server - * - * @return long - */ - public final long getAuthenticationDateTime() - { - return m_lastAuthTime; - } - - /** - * Set the domain that the offline server belongs to - * - * @param domain String - */ - public final void setDomain(String domain) - { - m_domain = domain; - } - - /** - * Set the online status for the server - * - * @param online boolean - */ - public final void setOnline(boolean online) - { - m_online = online; - } - - /** - * Update the authentication count and date/time - */ - public synchronized final void incrementAuthenticationCount() - { - m_authCount++; - m_lastAuthTime = System.currentTimeMillis(); - } - - /** - * Return the hash code for this object - * - * @return int - */ - public int hashCode() - { - return m_address.hashCode(); - } - - /** - * Return the passthru server details as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - if ( getDomain() != null) - { - str.append(getDomain()); - str.append("\\"); - } - str.append(getName()); - - str.append(":"); - str.append(getAddress().getHostAddress()); - - str.append(isOnline() ? ":Online" : ":Offline"); - - str.append(":"); - str.append(getAuthenticationCount()); - str.append(","); - str.append(getAuthenticationDateTime() != 0L ? new Date(getAuthenticationDateTime()) : "0"); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java b/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java deleted file mode 100644 index 0c583031ea..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/PassthruServers.java +++ /dev/null @@ -1,791 +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.server.auth.passthru; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetBIOSNameList; -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.util.IPAddress; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Passthru Servers Class - * - *

Contains a list of one or more servers that are used for passthru authentication. The status of the - * servers is tracked so that offline servers are not used but periodically monitored so that they can be - * returned to the online list of servers. - * - *

The server list may be initialized from a list of server names or addresses, or by specifying a domain - * name in which case the primary and backup domain controllers will be used. - * - * @author GKSpencer - * - */ -public class PassthruServers -{ - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth"); - - // Default timeout for setting up a new session - - private static final int DefaultConnectTimeout = 5000; // 5 seconds - - // Default interval to check if offline servers - - private static final long DefaultOfflineCheckInterval = 5 * 60000; // 5 minutes - - // List of online and offline authentication servers - - private List m_onlineList; - private List m_offlineList; - - // Timeout value when opening a session to an authentication server, in milliseconds - - private int m_tmo = DefaultConnectTimeout; - - // Domain name, if using domain controllers - - private String m_domain; - - // Offline server check interval - - private long m_offlineCheckInterval = DefaultOfflineCheckInterval; - - // Offline server checker thread - - PassthruOfflineChecker m_offlineChecker; - - /** - * Inner class used to periodically check offline servers to see if they are back online - */ - class PassthruOfflineChecker extends Thread - { - // Thread shutdown request flag - - private boolean m_ishutdown; - - /** - * Default constructor - */ - PassthruOfflineChecker() - { - setDaemon(true); - setName("PassthruOfflineChecker"); - start(); - } - - /** - * Main thread code - */ - public void run() - { - // Loop until shutdown - - m_ishutdown = false; - - while ( m_ishutdown == false) - { - // Sleep for a while - - try - { - sleep( m_offlineCheckInterval); - } - catch ( InterruptedException ex) - { - } - - // Check if shutdown has been requested - - if( m_ishutdown == true) - continue; - - // Check if there are any offline servers to check - - if ( getOfflineServerCount() > 0) - { - // Enumerate the offline server list - - int idx = 0; - PassthruServerDetails offlineServer = null; - PCShare authShare = new PCShare("", "IPC$", "", ""); - AuthenticateSession authSess = null; - - while ( idx < getOfflineServerCount()) - { - // Get an offline server from the list - - offlineServer = m_offlineList.get(idx); - - if ( offlineServer != null) - { - try - { - // Set the target host name - - authShare.setNodeName(offlineServer.getAddress().getHostAddress()); - - // Try and connect to the authentication server - - authSess = AuthSessionFactory.OpenAuthenticateSession( authShare, getConnectionTimeout()); - - // Close the session - - try - { - authSess.CloseSession(); - } - catch ( Exception ex) - { - } - - // Authentication server is online, move it to the online list - - serverOnline(offlineServer); - } - catch ( Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Passthru offline check failed for " + offlineServer.getName()); - } - - // Check if the server is now online - - if ( offlineServer.isOnline() == false) - idx++; - } - } - } - } - - // Debug - - if( logger.isDebugEnabled()) - logger.debug("Passthru offline checker thread closed"); - } - - /** - * Shutdown the checker thread - */ - public final void shutdownRequest() - { - m_ishutdown = true; - this.interrupt(); - } - - /** - * Wakeup the offline checker thread to process the offline server list - */ - public final void processOfflineServers() - { - this.interrupt(); - } - } - - /** - * Default constructor - */ - public PassthruServers() - { - // Create the server lists - - m_onlineList = new ArrayList(); - m_offlineList = new ArrayList(); - - // Create and start the offline server checker thread - - m_offlineChecker = new PassthruOfflineChecker(); - } - - /** - * Return the count of online authentication servers - * - * @return int - */ - public final int getOnlineServerCount() - { - return m_onlineList.size(); - } - - /** - * Return the count of offline authentication servers - * - * @return int - */ - public final int getOfflineServerCount() - { - return m_offlineList.size(); - } - - /** - * Return the total count of online and offline servers - * - * @return int - */ - public final int getTotalServerCount() - { - return m_onlineList.size() + m_offlineList.size(); - } - - /** - * Determine if there are online servers - * - * @return boolean - */ - public final boolean hasOnlineServers() - { - return m_onlineList.size() > 0 ? true : false; - } - - /** - * Return the connection timeout, in milliseconds - * - * @return int - */ - public final int getConnectionTimeout() - { - return m_tmo; - } - - /** - * Determine if the authentication servers are domain controllers - * - * @return boolean - */ - public final boolean isDomainAuthentication() - { - return m_domain != null ? true : false; - } - - /** - * Return the domain name - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Open a new session to an authentication server - * - * @return AuthenticateSession - */ - public final AuthenticateSession openSession() - { - return openSession( false, null); - } - - /** - * Open a new session to an authentication server - * - * @param useExtSec boolean - * @param clientDomain String - * @return AuthenticateSession - */ - public final AuthenticateSession openSession(boolean useExtSec, String clientDomain) - { - // Get the details of an authentication server to connect to - - PassthruServerDetails passthruServer = null; - - if ( clientDomain != null) - passthruServer = getAuthenticationServer( clientDomain); - else - passthruServer = getAuthenticationServer(); - - if ( passthruServer == null) - return null; - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Open authenticate session to " + passthruServer + ( clientDomain != null ? " (routed for client domain " + clientDomain + ")" : "")); - - // Open a new authentication session to the server - - PCShare authShare = new PCShare(passthruServer.getAddress().getHostAddress(), "IPC$", "", ""); - if ( useExtSec == true) - authShare.setExtendedSecurityFlags( SMBPacket.FLG2_EXTENDEDSECURITY); - - AuthenticateSession authSess = null; - - while ( authSess == null && passthruServer != null && hasOnlineServers()) { - - try - { - // Open a session to the current authentication server - - authSess = AuthSessionFactory.OpenAuthenticateSession( authShare, getConnectionTimeout()); - - // Update the passthru statistics - - passthruServer.incrementAuthenticationCount(); - } - catch ( Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Failed to connect to " + passthruServer, ex); - - // Failed to connect to the current authentication server, mark the server as offline - - serverOffline(passthruServer); - } - - // Check if we have a valid session - - if ( authSess == null) - { - // Try another authentication server - - passthruServer = getAuthenticationServer(); - - // Debug - - if(logger.isDebugEnabled()) - logger.debug("Trying authentication server " + passthruServer); - } - } - - // Return the authentication session - - return authSess; - } - - /** - * Return the details of an online server to use for authentication - * - * @return PassthruServerDetails - */ - protected PassthruServerDetails getAuthenticationServer() - { - // Rotate the head of the list and return the new head of list server details - - PassthruServerDetails passthruServer = null; - - synchronized ( m_onlineList) - { - if ( m_onlineList.size() > 1) - m_onlineList.add(m_onlineList.remove(0)); - if ( m_onlineList.size() > 0) - passthruServer = m_onlineList.get(0); - } - - return passthruServer; - } - - /** - * Return the details of an online server to use for authentication of the specified client - * domain - * - * @params clientDomain String - * @return PassthruServerDetails - */ - protected PassthruServerDetails getAuthenticationServer( String clientDomain) - { - // Rotate the head of the list and return the new head of list server details - - PassthruServerDetails passthruServer = null; - - synchronized ( m_onlineList) - { - int idx = 0; - - while ( idx < m_onlineList.size() && passthruServer == null) - { - // Get the current passthru server details - - PassthruServerDetails curServer = m_onlineList.get( idx); - - if ( curServer.getDomain() != null && curServer.getDomain().equals( clientDomain)) - { - // Use this passthru server - - passthruServer = curServer; - - // Move to the back of the list - - m_onlineList.add( m_onlineList.remove( idx)); - } - - // Update the server index - - idx++; - } - } - - return passthruServer; - } - - /** - * Move a server from the list of online servers to the offline list - * - * @param server PassthruServerDetails - */ - protected final void serverOffline(PassthruServerDetails server) - { - // Set the server status - - server.setOnline(false); - - // Remove the server from the online list - - synchronized( m_onlineList) - { - m_onlineList.remove(server); - } - - // Add it to the offline list - - synchronized( m_offlineList) - { - m_offlineList.add( server); - } - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Passthru server offline, " + server); - } - - /** - * Move a server from the list of offline servers to the online list - * - * @param server PassthruServerDetails - */ - protected final void serverOnline(PassthruServerDetails server) - { - // Set the server status - - server.setOnline(true); - - // Remove the server from the offline list - - synchronized( m_offlineList) - { - m_offlineList.remove(server); - } - - // Add it to the online list - - synchronized( m_onlineList) - { - m_onlineList.add( server); - } - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Passthru server online, " + server); - } - - /** - * Set the session connect timeout value, in milliseconds - * - * @param tmo int - */ - public final void setConnectionTimeout(int tmo) - { - m_tmo = tmo; - } - - /** - * Set the offline check interval, in seconds - * - * @param interval long - */ - public final void setOfflineCheckInterval(long interval) - { - m_offlineCheckInterval = interval * 1000L; - } - - /** - * Set the list of servers to use for passthru authentication using a comma delimeted list - * of server names/addresses - * - * @param servers String - */ - public final void setServerList(String servers) - { - // Split the server list into seperate name/address tokens - - StringTokenizer tokens = new StringTokenizer(servers, ","); - - while ( tokens.hasMoreTokens()) - { - // Get the current server name/address - - String srvName = tokens.nextToken().trim(); - - // Check if the server address also contains a domain name - - String domain = null; - int pos = srvName.indexOf( '\\'); - - if ( pos != -1) - { - domain = srvName.substring(0, pos); - srvName = srvName.substring( pos + 1); - } - - // If a name a has been specified convert it to an address, if an address has been specified - // then convert to a name. - - InetAddress srvAddr = null; - - if ( IPAddress.isNumericAddress(srvName)) - { - // Get the server name - - try - { - // Get the host address and name - - srvAddr = InetAddress.getByName(srvName); - srvName = srvAddr.getHostName(); - } - catch ( UnknownHostException ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Passthru failed to find name/address for " + srvName); - } - } - else - { - // Get the server address - - try - { - srvAddr = InetAddress.getByName(srvName); - } - catch ( UnknownHostException ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Passthru failed to find address for " + srvName); - } - } - - // Create the passthru server details and add to the list of offline servers - - if ( srvName != null && srvAddr != null) - { - // Create the passthru server details - - PassthruServerDetails passthruServer = new PassthruServerDetails(srvName, domain, srvAddr, false); - m_offlineList.add( passthruServer); - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Added passthru server " + passthruServer); - } - } - - // Wakeup the server checker thread to check each of the servers just added and move servers that are - // accessible to the online list - - m_offlineChecker.processOfflineServers(); - } - - /** - * Set the domain to use for passthru authentication - * - * @param domain String - */ - public final void setDomain(String domain) - { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Passthru finding domain controller for " + domain + " ..."); - - // Find a domain controller or the browse master - - NetBIOSName nbName = null; - - try - { - // Find a domain controller - - nbName = NetBIOSSession.FindName(domain, NetBIOSName.DomainControllers, getConnectionTimeout()); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug(" Found " + nbName.numberOfAddresses() + " domain controller(s)"); - } - catch (IOException ex) - { - } - - // If we did not find a domain controller look for the browse master - - if ( nbName == null) { - - try - { - // Try and find the browse master for the workgroup - - nbName = NetBIOSSession.FindName( domain, NetBIOSName.MasterBrowser, getConnectionTimeout()); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug(" Found browse master at " + nbName.getIPAddressString(0)); - } - catch (IOException ex) - { - throw new AlfrescoRuntimeException("Failed to find domain controller or browse master for " + domain); - } - } - - // Add the passthru server(s) - // - // Try and convert the address to a name for each domain controller - - for ( int i = 0; i < nbName.numberOfAddresses(); i++) - { - // Get the domain controller name - - InetAddress dcAddr = null; - String dcName = null; - - try - { - // Get the current domain controller address - - dcAddr = InetAddress.getByName(nbName.getIPAddressString(i)); - - // Get the list of NetBIOS names for the domain controller - - NetBIOSNameList nameList = NetBIOSSession.FindNamesForAddress(dcAddr.getHostAddress()); - NetBIOSName dcNBName = nameList.findName(NetBIOSName.FileServer, false); - - if ( dcNBName != null) - dcName = dcNBName.getName(); - } - catch (UnknownHostException ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Invalid address for server " + nbName.getIPAddressString(i)); - } - catch (Exception ex) - { - // Failed to get domain controller name, use the address - - dcName = dcAddr.getHostAddress(); - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Failed to get NetBIOS name for server " + dcAddr); - } - - // Create a passthru server entry for the domain controller - - if ( dcAddr != null) - { - // Create the passthru authentication server record - - PassthruServerDetails passthruServer = new PassthruServerDetails(dcName, domain, dcAddr, false); - m_offlineList.add(passthruServer); - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Added passthru server " + passthruServer); - } - } - - // Wakeup the server checker thread to check each of the servers just added and move servers that are - // accessible to the online list - - m_offlineChecker.processOfflineServers(); - } - - /** - * Shutdown passthru authentication - */ - public final void shutdown() - { - // Shutdown the offline server checker thread - - m_offlineChecker.shutdownRequest(); - - // Clear the online and offline server lists - - m_onlineList.clear(); - m_offlineList.clear(); - } - - /** - * Return the passthru server details as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - - if ( isDomainAuthentication()) - { - str.append("Domain:"); - str.append(getDomain()); - } - else - str.append("Servers:"); - - str.append(",Online="); - str.append(getOnlineServerCount()); - str.append(",Offline="); - str.append(getOfflineServerCount()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/RangeDomainMapping.java b/source/java/org/alfresco/filesys/server/auth/passthru/RangeDomainMapping.java deleted file mode 100644 index f97b0af926..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/RangeDomainMapping.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2006 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -package org.alfresco.filesys.server.auth.passthru; - -import org.alfresco.filesys.util.IPAddress; - -/** - * Address Range Domain Mapping Class - * - * @author gkspencer - */ -public class RangeDomainMapping extends DomainMapping { - - // Range from/to addresses - - private int m_rangeFrom; - private int m_rangeTo; - - /** - * class constructor - * - * @param domain String - * @param rangeFrom int - * @param rangeTo int - */ - public RangeDomainMapping( String domain, int rangeFrom, int rangeTo) - { - super( domain); - - m_rangeFrom = rangeFrom; - m_rangeTo = rangeTo; - } - - /** - * Return the from range address - * - * @return int - */ - public final int getRangeFrom() - { - return m_rangeFrom; - } - - /** - * Return the to range address - * - * @return int - */ - public final int getRangeTo() - { - return m_rangeTo; - } - - /** - * Check if the client address is a member of this domain - * - * @param clientIP int - * @return boolean - */ - public boolean isMemberOfDomain( int clientIP) - { - if (clientIP >= m_rangeFrom && clientIP <= m_rangeTo) - return true; - return false; - } - - /** - * Return the domain mapping as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - str.append(getDomain()); - str.append(","); - str.append(IPAddress.asString( getRangeFrom())); - str.append(":"); - str.append(IPAddress.asString( getRangeTo())); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/SMBPacket.java b/source/java/org/alfresco/filesys/server/auth/passthru/SMBPacket.java deleted file mode 100644 index df20e6f664..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/SMBPacket.java +++ /dev/null @@ -1,1432 +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.server.auth.passthru; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.NetworkSession; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataPacker; - -/** - * SMB packet type class - * - * @author GKSpencer - */ -public class SMBPacket -{ - - // SMB packet offsets, assuming an RFC NetBIOS transport - - public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN; - public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN; - - // SMB packet header length for a transaction type request - - public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN; - - // Minimum receive length for a valid SMB packet - - public static final int MIN_RXLEN = 32; - - // Default buffer size to allocate for SMB packets - - public static final int DEFAULT_BUFSIZE = 4096; - - // Flag bits - - public static final int FLG_SUBDIALECT = 0x01; - public static final int FLG_CASELESS = 0x08; - public static final int FLG_CANONICAL = 0x10; - public static final int FLG_OPLOCK = 0x20; - public static final int FLG_NOTIFY = 0x40; - public static final int FLG_RESPONSE = 0x80; - - // Flag2 bits - - public static final int FLG2_LONGFILENAMES = 0x0001; - public static final int FLG2_EXTENDEDATTRIB = 0x0002; - public static final int FLG2_SECURITYSIG = 0x0004; - public static final int FLG2_EXTENDEDSECURITY = 0x0800; - public static final int FLG2_READIFEXE = 0x2000; - public static final int FLG2_LONGERRORCODE = 0x4000; - public static final int FLG2_UNICODE = 0x8000; - - // Security mode bits - - public static final int SEC_USER = 0x0001; - public static final int SEC_ENCRYPT = 0x0002; - - // Raw mode bits - - public static final int RAW_READ = 0x0001; - public static final int RAW_WRITE = 0x0002; - - // SMB packet buffer - - private byte[] m_smbbuf; - - // Packet type - - private int m_pkttype; - - // Current byte area pack/unpack position - - protected int m_pos; - protected int m_endpos; - - // Time of last packet send - - protected long m_lastTxTime; - - /** - * Default constructor - */ - public SMBPacket() - { - m_smbbuf = new byte[DEFAULT_BUFSIZE]; - InitializeBuffer(); - } - - /** - * Construct an SMB packet using the specified packet buffer. - * - * @param buf SMB packet buffer. - */ - public SMBPacket(byte[] buf) - { - m_smbbuf = buf; - } - - /** - * Construct an SMB packet of the specified size. - * - * @param siz Size of SMB packet buffer to allocate. - */ - public SMBPacket(int siz) - { - m_smbbuf = new byte[siz]; - InitializeBuffer(); - } - - /** - * Check if a received SMB is valid, if not then throw an exception - * - * @exception SMBException - */ - public final void checkForError() throws SMBException - { - - // Check if a valid SMB response has been received - - if (isValidResponse() == false) - { - - // Check for NT error codes - - if (isLongErrorCode()) - throw new SMBException(SMBStatus.NTErr, getLongErrorCode()); - else - throw new SMBException(getErrorClass(), getErrorCode()); - } - } - - /** - * Clear the data byte count - */ - public final void clearBytes() - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(0, m_smbbuf, offset); - } - - /** - * Check if the error class/code match the specified error/class - * - * @param errClass int - * @param errCode int - * @return boolean - */ - public final boolean equalsError(int errClass, int errCode) - { - if (getErrorClass() == errClass && getErrorCode() == errCode) - return true; - return false; - } - - /** - * Send the SMB packet and receive the response packet - * - * @param sess Network session to send/receive the packet over. - * @param rxPkt SMB packet to receive the response into. - * @param throwerr If true then throw an I/O error if an invalid response is received. - * @exception java.io.IOException If a network error occurs. - * @exception SMBException If an SMB level error occurs - */ - protected final synchronized void ExchangeLowLevelSMB(NetworkSession sess, SMBPacket rxPkt, boolean throwerr) - throws java.io.IOException, SMBException - { - - // Set multiplex id - - if (getMultiplexId() == 0) - setMultiplexId(1); - - // Send the SMB request - - sess.Send(m_smbbuf, getLength()); - - // Receive a response - - if (sess.Receive(rxPkt.getBuffer(), 0) >= MIN_RXLEN) - { - - // Check if the response is for the current request - - if (rxPkt.getCommand() == m_pkttype) - { - - // Check if a valid SMB response has been received - - if (throwerr == true) - checkForError(); - - // Valid packet received, return to caller - - return; - } - } - - // Invalid receive packet - - throw new java.io.IOException("Invalid SMB Receive Packet"); - } - - /** - * Send/receive an SMB protocol packet to the remote server. - * - * @param sess SMB session to send/receive data on. - * @param rxPkt SMB packet to receive the response into. - * @exception java.io.IOException If an I/O error occurs. - * @exception SMBException If an SMB level error occurs. - */ - public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt) throws SMBException, - IOException - { - - // Call the main SMB exhchange method - - ExchangeSMB(sess, rxPkt, false); - } - - /** - * Send the SMB packet and receive the response packet - * - * @param sess SMB session to send/receive the packet over. - * @param rxPkt SMB packet to receive the response into. - * @param throwerr If true then throw an I/O error if an invalid response is received. - * @exception java.io.IOException If an I/O error occurs. - * @exception SMBException If an SMB level error occurs. - */ - public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt, boolean throwerr) - throws SMBException, IOException - { - - // Set the process id, user id and multiplex id - - setProcessId(sess.getProcessId()); - setUserId(sess.getUserId()); - - if (getMultiplexId() == 0) - setMultiplexId(1); - - // Get the network session - - NetworkSession netSess = sess.getSession(); - - // Send the SMB request - - netSess.Send(m_smbbuf, getLength()); - - // Receive the response, other asynchronous responses may be received before the response - // for this request - - boolean rxValid = false; - - while (rxValid == false) - { - - // Receive a response - - if (netSess.Receive(rxPkt.getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) - { - - // Check if the response is for the current request - - if (rxPkt.getCommand() == m_pkttype) - { - - // Check if a valid SMB response has been received - - if (throwerr == true) - checkForError(); - - // Valid packet received, return to caller - - return; - } - } - } - - // Invalid receive packet - - throw new java.io.IOException("Invalid SMB Receive Packet"); - } - - /** - * Get the secondary command code - * - * @return Secondary command code - */ - public final int getAndXCommand() - { - return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF); - } - - /** - * Return the byte array used for the SMB packet - * - * @return Byte array used for the SMB packet. - */ - public final byte[] getBuffer() - { - return m_smbbuf; - } - - /** - * Return the total buffer size available to the SMB request - * - * @return Total SMB buffer length available. - */ - public final int getBufferLength() - { - return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the available buffer space for data bytes - * - * @return int - */ - public final int getAvailableLength() - { - return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset()); - } - - /** - * Get the data byte count for the SMB packet - * - * @return Data byte count - */ - public final int getByteCount() - { - - // Calculate the offset of the byte count - - int pos = PARAMWORDS + (2 * getParameterCount()); - return (int) DataPacker.getIntelShort(m_smbbuf, pos); - } - - /** - * Get the data byte area offset within the SMB packet - * - * @return Data byte offset within the SMB packet. - */ - public final int getByteOffset() - { - - // Calculate the offset of the byte buffer - - int pCnt = getParameterCount(); - int pos = WORDCNT + (2 * pCnt) + 3; - return pos; - } - - /** - * Get the SMB command - * - * @return SMB command code. - */ - public final int getCommand() - { - return (int) (m_smbbuf[COMMAND] & 0xFF); - } - - /** - * Determine if normal or long error codes have been returned - * - * @return boolean - */ - public final boolean hasLongErrorCode() - { - if ((getFlags2() & FLG2_LONGERRORCODE) == 0) - return false; - return true; - } - - /** - * Return the saved packet type - * - * @return int - */ - public final int isType() - { - return m_pkttype; - } - - /** - * Check if the packet contains ASCII or Unicode strings - * - * @return boolean - */ - public final boolean isUnicode() - { - return (getFlags2() & FLG2_UNICODE) != 0 ? true : false; - } - - /** - * Check if the packet is using caseless filenames - * - * @return boolean - */ - public final boolean isCaseless() - { - return (getFlags() & FLG_CASELESS) != 0 ? true : false; - } - - /** - * Check if long file names are being used - * - * @return boolean - */ - public final boolean isLongFileNames() - { - return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false; - } - - /** - * Check if long error codes are being used - * - * @return boolean - */ - public final boolean isLongErrorCode() - { - return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false; - } - - /** - * Get the SMB error class - * - * @return SMB error class. - */ - public final int getErrorClass() - { - return (int) m_smbbuf[ERRORCLASS] & 0xFF; - } - - /** - * Get the SMB error code - * - * @return SMB error code. - */ - public final int getErrorCode() - { - return (int) m_smbbuf[ERROR] & 0xFF; - } - - /** - * Get the SMB flags value. - * - * @return SMB flags value. - */ - public final int getFlags() - { - return (int) m_smbbuf[FLAGS] & 0xFF; - } - - /** - * Get the SMB flags2 value. - * - * @return SMB flags2 value. - */ - public final int getFlags2() - { - return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2); - } - - /** - * Calculate the total used packet length. - * - * @return Total used packet length. - */ - public final int getLength() - { - return (getByteOffset() + getByteCount()) - SIGNATURE; - } - - /** - * Get the long SMB error code - * - * @return Long SMB error code. - */ - public final int getLongErrorCode() - { - return DataPacker.getIntelInt(m_smbbuf, ERRORCODE); - } - - /** - * Get the multiplex identifier. - * - * @return Multiplex identifier. - */ - public final int getMultiplexId() - { - return DataPacker.getIntelShort(m_smbbuf, MID); - } - - /** - * Get a parameter word from the SMB packet. - * - * @param idx Parameter index (zero based). - * @return Parameter word value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getParameterCount()) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = WORDCNT + (2 * idx) + 1; - return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); - } - - /** - * Get the specified parameter words, as an int value. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - public final int getParameterLong(int idx) - { - int pos = WORDCNT + (2 * idx) + 1; - return DataPacker.getIntelInt(m_smbbuf, pos); - } - - /** - * Get the parameter count - * - * @return Parameter word count. - */ - public final int getParameterCount() - { - return (int) m_smbbuf[WORDCNT]; - } - - /** - * Get the process indentifier (PID) - * - * @return Process identifier value. - */ - public final int getProcessId() - { - return DataPacker.getIntelShort(m_smbbuf, PID); - } - - /** - * Get the SMB signing value, as a long value - * - * @return long - */ - public final long getSignature() - { - return DataPacker.getIntelLong( m_smbbuf, SIGNATURE); - } - - /** - * Get the tree identifier (TID) - * - * @return Tree identifier (TID) - */ - public final int getTreeId() - { - return DataPacker.getIntelShort(m_smbbuf, TID); - } - - /** - * Get the user identifier (UID) - * - * @return User identifier (UID) - */ - public final int getUserId() - { - return DataPacker.getIntelShort(m_smbbuf, UID); - } - - /** - * Return the last sent packet time - * - * @return long - */ - public final long getLastPacketSendTime() - { - return m_lastTxTime; - } - - /** - * Initialize the SMB packet buffer. - */ - private final void InitializeBuffer() - { - - // Set the packet signature - - m_smbbuf[SIGNATURE] = (byte) 0xFF; - m_smbbuf[SIGNATURE + 1] = (byte) 'S'; - m_smbbuf[SIGNATURE + 2] = (byte) 'M'; - m_smbbuf[SIGNATURE + 3] = (byte) 'B'; - } - - /** - * Determine if this packet is an SMB response, or command packet - * - * @return true if this SMB packet is a response, else false - */ - public final boolean isResponse() - { - int resp = getFlags(); - if ((resp & FLG_RESPONSE) != 0) - return true; - return false; - } - - /** - * Check if the response packet is valid, ie. type and flags - * - * @return true if the SMB packet is a response packet and the response is valid, else false. - */ - public final boolean isValidResponse() - { - - // Check if this is a response packet, and the correct type of packet - - if (isResponse() && getCommand() == m_pkttype) - { - - // Check if standard error codes or NT 32-bit error codes are being used - - if ((getFlags2() & FLG2_LONGERRORCODE) == 0) - { - if (getErrorCode() == SMBStatus.Success) - return true; - } - else if (getLongErrorCode() == SMBStatus.NTSuccess) - return true; - } - return false; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val byte - */ - public final void packByte(byte val) - { - m_smbbuf[m_pos++] = val; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val int - */ - public final void packByte(int val) - { - m_smbbuf[m_pos++] = (byte) val; - } - - /** - * Pack the specified bytes into the byte area - * - * @param byts byte[] - * @param len int - */ - public final void packBytes(byte[] byts, int len) - { - System.arraycopy(byts, 0, m_smbbuf, m_pos, len); - m_pos += len; - } - - /** - * Pack a string using either ASCII or Unicode into the byte area - * - * @param str String - * @param uni boolean - */ - public final void packString(String str, boolean uni) - { - - // Check for Unicode or ASCII - - if (uni) - { - - // Word align the buffer position, pack the Unicode string - - m_pos = DataPacker.wordAlign(m_pos); - DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true); - m_pos += (str.length() * 2) + 2; - } - else - { - - // Pack the ASCII string - - DataPacker.putString(str, m_smbbuf, m_pos, true); - m_pos += str.length() + 1; - } - } - - /** - * Pack a word (16 bit) value into the byte area - * - * @param val int - */ - public final void packWord(int val) - { - DataPacker.putIntelShort(val, m_smbbuf, m_pos); - m_pos += 2; - } - - /** - * Pack a 32 bit integer value into the byte area - * - * @param val int - */ - public final void packInt(int val) - { - DataPacker.putIntelInt(val, m_smbbuf, m_pos); - m_pos += 4; - } - - /** - * Pack a long integer (64 bit) value into the byte area - * - * @param val long - */ - public final void packLong(long val) - { - DataPacker.putIntelLong(val, m_smbbuf, m_pos); - m_pos += 8; - } - - /** - * Return the current byte area buffer position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Set the byte area buffer position - * - * @param pos int - */ - public final void setPosition(int pos) - { - m_pos = pos; - } - - /** - * Unpack a byte value from the byte area - * - * @return int - */ - public final int unpackByte() - { - return (int) m_smbbuf[m_pos++]; - } - - /** - * Unpack a block of bytes from the byte area - * - * @param len int - * @return byte[] - */ - public final byte[] unpackBytes(int len) - { - if (len <= 0) - return null; - - byte[] buf = new byte[len]; - System.arraycopy(m_smbbuf, m_pos, buf, 0, len); - m_pos += len; - return buf; - } - - /** - * Unpack a word (16 bit) value from the byte area - * - * @return int - */ - public final int unpackWord() - { - int val = DataPacker.getIntelShort(m_smbbuf, m_pos); - m_pos += 2; - return val; - } - - /** - * Unpack an integer (32 bit) value from the byte/parameter area - * - * @return int - */ - public final int unpackInt() - { - int val = DataPacker.getIntelInt(m_smbbuf, m_pos); - m_pos += 4; - return val; - } - - /** - * Unpack a long integer (64 bit) value from the byte area - * - * @return long - */ - public final long unpackLong() - { - long val = DataPacker.getIntelLong(m_smbbuf, m_pos); - m_pos += 8; - return val; - } - - /** - * Unpack a string from the byte area - * - * @param uni boolean - * @return String - */ - public final String unpackString(boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - - if (uni) - { - - // Word align the current buffer position - - m_pos = DataPacker.wordAlign(m_pos); - ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += (ret.length() * 2) + 2; - } - else - { - - // Unpack the ASCII string - - ret = DataPacker.getString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += ret.length() + 1; - } - - // Return the string - - return ret; - } - - /** - * Unpack a string from the byte area - * - * @param len int - * @param uni boolean - * @return String - */ - public final String unpackString(int len, boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - - if (uni) - { - - // Word align the current buffer position - - m_pos = DataPacker.wordAlign(m_pos); - ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len); - if (ret != null) - m_pos += (ret.length() * 2); - } - else - { - - // Unpack the ASCII string - - ret = DataPacker.getString(m_smbbuf, m_pos, len); - if (ret != null) - m_pos += ret.length(); - } - - // Return the string - - return ret; - } - - /** - * Check if there is more data in the byte area - * - * @return boolean - */ - public final boolean hasMoreData() - { - if (m_pos < m_endpos) - return true; - return false; - } - - /** - * Receive an SMB response packet. - * - * @param sess NetBIOS session to receive the SMB packet on. - * @exception java.io.IOException If an I/O error occurs. - */ - private final void ReceiveSMB(NetBIOSSession sess) throws java.io.IOException - { - - if (sess.Receive(m_smbbuf, RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) - return; - - // Not enough data received for an SMB header - - throw new java.io.IOException("Short NetBIOS receive"); - } - - /** - * Receive an SMB packet on the spceified SMB session. - * - * @param sess SMB session to receive the packet on. - * @exception java.io.IOException If a network error occurs - * @exception SMBException If an SMB level error occurs - */ - protected final void ReceiveSMB(AuthenticateSession sess) throws java.io.IOException, SMBException - { - - // Call the main receive method - - ReceiveSMB(sess, true); - } - - /** - * Receive an SMB packet on the spceified SMB session. - * - * @param sess SMB session to receive the packet on. - * @param throwErr Flag to indicate if an error is thrown if an error response is received - * @exception java.io.IOException If a network error occurs - * @exception SMBException If an SMB level error occurs - */ - protected final void ReceiveSMB(AuthenticateSession sess, boolean throwErr) throws java.io.IOException, - SMBException - { - - // Get the network session - - NetworkSession netSess = sess.getSession(); - - // Receive the response, other asynchronous responses may be received before the response - // for this request - - boolean rxValid = false; - - while (rxValid == false) - { - - // Receive a response - - if (netSess.Receive(getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) - { - - // Check if the response is for the current request - - if (getCommand() == m_pkttype) - { - - // Check if a valid SMB response has been received - - if (throwErr == true) - checkForError(); - - // Valid packet received, return to caller - - return; - } - } - else - { - - // Not enough data received for an SMB header - - throw new java.io.IOException("Short NetBIOS receive"); - } - } - } - - /** - * Send the SMB packet on the specified SMB session. - * - * @param sess SMB session to send this packet over. - * @exception java.io.IOException If an I/O error occurs. - */ - protected final void SendSMB(AuthenticateSession sess) throws java.io.IOException - { - - // Update the last send time - - m_lastTxTime = System.currentTimeMillis(); - - // Send the SMB request - - sess.getSession().Send(m_smbbuf, getLength()); - } - - /** - * Set the secondary SMB command - * - * @param cmd Secondary SMB command code. - */ - public final void setAndXCommand(int cmd) - { - - // Set the chained command packet type - - m_smbbuf[ANDXCOMMAND] = (byte) cmd; - m_smbbuf[ANDXRESERVED] = (byte) 0; - - // If the AndX command is disabled clear the offset to the chained packet - - if (cmd == PacketType.NoChainedCommand) - setParameter(1, 0); - } - - /** - * Set the data byte count for this SMB packet - * - * @param cnt Data byte count. - */ - public final void setByteCount(int cnt) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(cnt, m_smbbuf, offset); - } - - /** - * Set the data byte count for this SMB packet - */ - - public final void setByteCount() - { - int offset = getByteOffset() - 2; - int len = m_pos - getByteOffset(); - DataPacker.putIntelShort(len, m_smbbuf, offset); - } - - /** - * Set the data byte area in the SMB packet - * - * @param byts Byte array containing the data to be copied to the SMB packet. - */ - public final void setBytes(byte[] byts) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(byts.length, m_smbbuf, offset); - - offset += 2; - - for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) - ; - } - - /** - * Set the SMB command - * - * @param cmd SMB command code - */ - public final void setCommand(int cmd) - { - m_pkttype = cmd; - m_smbbuf[COMMAND] = (byte) cmd; - } - - /** - * Set the SMB error class. - * - * @param cl SMB error class. - */ - public final void setErrorClass(int cl) - { - m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF); - } - - /** - * Set the SMB error code - * - * @param sts SMB error code. - */ - public final void setErrorCode(int sts) - { - m_smbbuf[ERROR] = (byte) (sts & 0xFF); - } - - /** - * Set a long error code (NT status code) - * - * @param sts int - */ - public final void setLongErrorCode(int lsts) - { - DataPacker.putIntelInt(lsts, m_smbbuf, ERRORCODE); - } - - /** - * Set the SMB flags value. - * - * @param flg SMB flags value. - */ - public final void setFlags(int flg) - { - m_smbbuf[FLAGS] = (byte) flg; - } - - /** - * Set the SMB flags2 value. - * - * @param flg SMB flags2 value. - */ - public final void setFlags2(int flg) - { - DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2); - } - - /** - * Set the multiplex identifier. - * - * @param mid Multiplex identifier - */ - public final void setMultiplexId(int mid) - { - DataPacker.putIntelShort(mid, m_smbbuf, MID); - } - - /** - * Set the specified parameter word. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - public final void setParameter(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelShort(val, m_smbbuf, pos); - } - - /** - * Set the specified parameter words. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final void setParameterLong(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelInt(val, m_smbbuf, pos); - } - - /** - * Set the parameter count - * - * @param cnt Parameter word count. - */ - public final void setParameterCount(int cnt) - { - m_smbbuf[WORDCNT] = (byte) cnt; - } - - /** - * Set the process identifier value (PID). - * - * @param pid Process identifier value. - */ - public final void setProcessId(int pid) - { - DataPacker.putIntelShort(pid, m_smbbuf, PID); - } - - /** - * Set the packet sequence number, for connectionless commands. - * - * @param seq Sequence number. - */ - public final void setSeqNo(int seq) - { - DataPacker.putIntelShort(seq, m_smbbuf, SEQNO); - } - - /** - * Set the session id. - * - * @param sid Session id. - */ - public final void setSID(int sid) - { - DataPacker.putIntelShort(sid, m_smbbuf, SID); - } - - /** - * Set the SMB signing signature - * - * @param ival int - */ - public final void setSignature( int ival) - { - DataPacker.putIntelInt( ival, m_smbbuf, SIGNATURE); - DataPacker.putZeros( m_smbbuf, SIGNATURE + 4, 4); - } - - /** - * Set the SMB signing signature - * - * @param lval long - */ - public final void setSignature( long lval) - { - DataPacker.putIntelLong( lval, m_smbbuf, SIGNATURE); - } - - /** - * Set the SMB signing signature - * - * @param byts byte[] - * @param offset int - */ - public final void setSignature( byte[] byts, int offset) - { - System.arraycopy( byts, offset, m_smbbuf, SIGNATURE, 8); - } - - /** - * Set the tree identifier (TID) - * - * @param tid Tree identifier value. - */ - public final void setTreeId(int tid) - { - DataPacker.putIntelShort(tid, m_smbbuf, TID); - } - - /** - * Set the user identifier (UID) - * - * @param uid User identifier value. - */ - public final void setUserId(int uid) - { - DataPacker.putIntelShort(uid, m_smbbuf, UID); - } - - /** - * Align the byte area pointer on an int (32bit) boundary - */ - public final void alignBytePointer() - { - m_pos = DataPacker.longwordAlign(m_pos); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking data items from the packet - */ - public final void resetBytePointer() - { - m_pos = getByteOffset(); - m_endpos = m_pos + getByteCount(); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and - * align the buffer on an int (32bit) boundary - */ - public final void resetBytePointerAlign() - { - m_pos = DataPacker.longwordAlign(getByteOffset()); - m_endpos = m_pos + getByteCount(); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking paramaters from the packet - */ - public final void resetParameterPointer() - { - m_pos = PARAMWORDS; - } - - /** - * Set the unpack pointer to the specified offset, for AndX processing - * - * @param off int - * @param len int - */ - public final void setBytePointer(int off, int len) - { - m_pos = off; - m_endpos = m_pos + len; - } - - /** - * Skip a number of bytes in the parameter/byte area - * - * @param cnt int - */ - public final void skipBytes(int cnt) - { - m_pos += cnt; - } - - /** - * Return the flags value as a string - * - * @return String - */ - protected final String getFlagsAsString() - { - - // Get the flags value - - int flags = getFlags(); - if (flags == 0) - return ""; - - StringBuffer str = new StringBuffer(); - if ((flags & FLG_SUBDIALECT) != 0) - str.append("SubDialect,"); - - if ((flags & FLG_CASELESS) != 0) - str.append("Caseless,"); - - if ((flags & FLG_CANONICAL) != 0) - str.append("Canonical,"); - - if ((flags & FLG_OPLOCK) != 0) - str.append("Oplock,"); - - if ((flags & FLG_NOTIFY) != 0) - str.append("Notify,"); - - if ((flags & FLG_RESPONSE) != 0) - str.append("Response,"); - - str.setLength(str.length() - 1); - - return str.toString(); - } - - /** - * Return the flags2 value as a string - * - * @return String - */ - protected final String getFlags2AsString() - { - - // Get the flags2 value - - int flags2 = getFlags2(); - - if (flags2 == 0) - return ""; - - StringBuffer str = new StringBuffer(); - - if ((flags2 & FLG2_LONGFILENAMES) != 0) - str.append("LongFilenames,"); - - if ((flags2 & FLG2_EXTENDEDATTRIB) != 0) - str.append("ExtAttributes,"); - - if ((flags2 & FLG2_READIFEXE) != 0) - str.append("ReadIfEXE,"); - - if ((flags2 & FLG2_LONGERRORCODE) != 0) - str.append("LongErrorCode,"); - - if ((flags2 & FLG2_UNICODE) != 0) - str.append("Unicode,"); - - str.setLength(str.length() - 1); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/SubnetDomainMapping.java b/source/java/org/alfresco/filesys/server/auth/passthru/SubnetDomainMapping.java deleted file mode 100644 index 10f7812d9c..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/SubnetDomainMapping.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2006 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -package org.alfresco.filesys.server.auth.passthru; - -import org.alfresco.filesys.util.IPAddress; - -/** - * Subnet Domain Mapping Class - * - * @author gkspencer - */ -public class SubnetDomainMapping extends DomainMapping { - - // Subnet and mask for the domain - - private int m_subnet; - private int m_mask; - - /** - * class constructor - * - * @param domain String - * @param subnet int - * @param mask int - */ - public SubnetDomainMapping( String domain, int subnet, int mask) - { - super( domain); - - m_subnet = subnet; - m_mask = mask; - } - - /** - * Return the subnet - * - * @return int - */ - public final int getSubnet() - { - return m_subnet; - } - - /** - * Return the subnet mask - * - * @return int - */ - public final int getSubnetMask() - { - return m_mask; - } - - /** - * Check if the client address is a member of this domain - * - * @param clientIP int - * @return boolean - */ - public boolean isMemberOfDomain( int clientIP) - { - if (( clientIP & m_mask) == m_subnet) - return true; - return false; - } - - /** - * Return the domain mapping as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - str.append(getDomain()); - str.append(","); - str.append(IPAddress.asString( getSubnet())); - str.append(":"); - str.append(IPAddress.asString( getSubnetMask())); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/passthru/TcpipSMBNetworkSession.java b/source/java/org/alfresco/filesys/server/auth/passthru/TcpipSMBNetworkSession.java deleted file mode 100644 index a995846eb0..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/passthru/TcpipSMBNetworkSession.java +++ /dev/null @@ -1,294 +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.server.auth.passthru; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.net.Socket; -import java.net.UnknownHostException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.NetworkSession; -import org.alfresco.filesys.smb.TcpipSMB; -import org.alfresco.filesys.util.DataPacker; - -/** - * Native TCP/IP SMB Network Session Class - */ -public class TcpipSMBNetworkSession implements NetworkSession -{ - - // Default socket timeout value - - private static int _defTimeout = 30000; // 30 seconds, in milliseconds - - // Socket used to connect and read/write to remote host - - private Socket m_socket; - - // Input and output data streams, from the socket network connection - - private DataInputStream m_in; - private DataOutputStream m_out; - - // Socket timeout - - private int m_tmo = _defTimeout; - - // Debug enable flag and debug output stream - - private static boolean m_debug = false; - private static PrintStream m_dbg = System.out; - - /** - * Default constructor - */ - public TcpipSMBNetworkSession() - { - } - - /** - * Class constructor - * - * @param tmo Socket timeout, in milliseconds - */ - public TcpipSMBNetworkSession(int tmo) - { - m_tmo = tmo; - } - - /** - * Return the protocol name - * - * @return String - */ - public String getProtocolName() - { - return "Native SMB (port 445)"; - } - - /** - * Open a connection to a remote host - * - * @param toName Host name/address being called - * @param fromName Local host name/address - * @param toAddr Optional address - * @exception IOException - */ - public void Open(String toName, String fromName, String toAddr) throws IOException, UnknownHostException - { - - // Create the socket - - m_socket = new Socket(toName, TcpipSMB.PORT); - - // Enable the timeout on the socket, disable the Nagle algorithm - - m_socket.setSoTimeout(m_tmo); - m_socket.setTcpNoDelay(true); - - // Attach input/output streams to the socket - - m_in = new DataInputStream(m_socket.getInputStream()); - m_out = new DataOutputStream(m_socket.getOutputStream()); - } - - /** - * Determine if the session is connected to a remote host - * - * @return boolean - */ - public boolean isConnected() - { - return m_socket != null ? true : false; - } - - /** - * Check if there is data available on this network session - * - * @return boolean - * @exception IOException - */ - public final boolean hasData() throws IOException - { - - // Check if the connection is active - - if (m_socket == null || m_in == null) - return false; - - // Check if there is data available - - return m_in.available() > 0 ? true : false; - } - - /** - * Receive a data packet from the remote host. - * - * @param buf Byte buffer to receive the data into. - * @param tmo Receive timeout in milliseconds, or zero for no timeout - * @return Length of the received data. - * @exception java.io.IOException I/O error occurred. - */ - public int Receive(byte[] buf, int tmo) throws IOException - { - - // Set the read timeout - - m_socket.setSoTimeout(tmo); - - // Read a data packet of data - - int rdlen = m_in.read(buf, 0, RFCNetBIOSProtocol.HEADER_LEN); - - // Check if a header was received - - if (rdlen < RFCNetBIOSProtocol.HEADER_LEN) - throw new java.io.IOException("TCP/IP SMB Short Read"); - - // Get the packet data length - - int pktlen = DataPacker.getInt(buf, 0); - - // Debug mode - - if (m_debug) - m_dbg.println("TcpSMB: Rx " + pktlen + " bytes"); - - // Read the data part of the packet into the users buffer, this may take - // several reads - - int totlen = 0; - int offset = RFCNetBIOSProtocol.HEADER_LEN; - - while (pktlen > 0) - { - - // Read the data - - rdlen = m_in.read(buf, offset, pktlen); - - // Update the received length and remaining data length - - totlen += rdlen; - pktlen -= rdlen; - - // Update the user buffer offset as more reads will be required - // to complete the data read - - offset += rdlen; - - } // end while reading data - - // Return the received data length, not including the header - - return totlen; - } - - /** - * Send a data packet to the remote host. - * - * @param data Byte array containing the data to be sent. - * @param siz Length of the data to send. - * @return true if the data was sent successfully, else false. - * @exception java.io.IOException I/O error occurred. - */ - public boolean Send(byte[] data, int siz) throws IOException - { - - // Pack the data length as the first four bytes of the packet - - DataPacker.putInt(siz, data, 0); - - // Send the packet to the remote host - - int len = siz + RFCNetBIOSProtocol.HEADER_LEN; - m_out.write(data, 0, len); - return true; - } - - /** - * Close the network session - * - * @exception java.io.IOException I/O error occurred - */ - public void Close() throws IOException - { - - // Close the input/output streams - - if (m_in != null) - { - m_in.close(); - m_in = null; - } - - if (m_out != null) - { - m_out.close(); - m_out = null; - } - - // Close the socket - - if (m_socket != null) - { - m_socket.close(); - m_socket = null; - } - } - - /** - * Enable/disable session debugging output - * - * @param dbg true to enable debugging, else false - */ - public static void setDebug(boolean dbg) - { - m_debug = dbg; - } - - /** - * Return the default socket timeout value - * - * @return int - */ - public static final int getDefaultTimeout() - { - return _defTimeout; - } - - /** - * Set the default socket timeout for new sessions - * - * @param tmo int - */ - public static final void setDefaultTimeout(int tmo) - { - _defTimeout = tmo; - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenInit.java b/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenInit.java deleted file mode 100644 index e36551037d..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenInit.java +++ /dev/null @@ -1,424 +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.server.auth.spnego; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Enumeration; -import java.util.Vector; - -import org.alfresco.filesys.util.HexDump; -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.DERApplicationSpecific; -import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERGeneralString; -import org.bouncycastle.asn1.DERObject; -import org.bouncycastle.asn1.DERObjectIdentifier; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DEROutputStream; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERTaggedObject; -import org.bouncycastle.asn1.DERTags; -import org.bouncycastle.asn1.DERUnknownTag; -import org.ietf.jgss.GSSException; -import org.ietf.jgss.Oid; - -/** - * NegTokenInit Class - * - *

Contains the details of an SPNEGO NegTokenInit blob for use with CIFS. - * - * @author gkspencer - */ -public class NegTokenInit -{ - // Mechtypes list - - private Oid[] m_mechTypes; - - // Context flags - - private int m_contextFlags = -1; - - // Mechtoken - - private byte[] m_mechToken; - - // MectListMIC principal - - private String m_mecListMICPrincipal; - - /** - * Class constructor for decoding - */ - public NegTokenInit() - { - } - - /** - * Class constructor for encoding - * - * @param mechTypes Oid[] - * @param mechPrinciple String - */ - public NegTokenInit( Oid[] mechTypes, String mechPrinciple) - { - m_mechTypes = mechTypes; - m_mecListMICPrincipal = mechPrinciple; - } - - /** - * Class constructor for encoding - * - * @param mechTypes Vector - * @param mechPrinciple String - */ - public NegTokenInit( Vector mechTypes, String mechPrinciple) - { - // Create the mechTypes array - - m_mechTypes = new Oid[ mechTypes.size()]; - for ( int i = 0; i < mechTypes.size(); i++) - m_mechTypes[i] = mechTypes.get(i); - - m_mecListMICPrincipal = mechPrinciple; - } - - /** - * Return the mechTypes OID list - * - * @return Oid[] - */ - public final Oid[] getOids() - { - return m_mechTypes; - } - - /** - * Return the context flags - * - * @return int - */ - public final int getContextFlags() - { - return m_contextFlags; - } - - /** - * Return the mechToken - * - * @return byte[] - */ - public final byte[] getMechtoken() - { - return m_mechToken; - } - - /** - * Return the mechListMIC principal - * - * @return String - */ - public final String getPrincipal() - { - return m_mecListMICPrincipal; - } - - /** - * Check if the OID list contains the specified OID - * - * @param oid Oid - * @return boolean - */ - public final boolean hasOid( Oid oid) - { - boolean foundOid = false; - - if ( m_mechTypes != null) - { - foundOid = oid.containedIn( m_mechTypes); - } - - return foundOid; - } - - /** - * Return the count of OIDs - * - * @return int - */ - public final int numberOfOids() - { - return m_mechTypes != null ? m_mechTypes.length : 0; - } - - /** - * Return the specified OID - * - * @param idx int - * @return OID - */ - public final Oid getOidAt(int idx) - { - if ( m_mechTypes != null && idx >= 0 && idx < m_mechTypes.length) - return m_mechTypes[idx]; - return null; - } - - /** - * Decode an SPNEGO NegTokenInit blob - * - * @param buf byte[] - * @param off int - * @param len int - * @exception IOException - */ - public void decode(byte[] buf, int off, int len) throws IOException - { - // Create a stream around the security blob - - ByteArrayInputStream bytStream = new ByteArrayInputStream( buf, off, len); - ASN1InputStream asnStream = new ASN1InputStream( bytStream); - - // Read the top level object from the security blob - - DERObject derObj = asnStream.readObject(); - - if ( derObj instanceof DERApplicationSpecific == false) - throw new IOException("Bad blob format (AppSpec)"); - - // Access the application specific contents - - DERApplicationSpecific derApp = (DERApplicationSpecific) derObj; - - ByteArrayInputStream appStream = new ByteArrayInputStream( derApp.getContents()); - ASN1InputStream asnAppStream = new ASN1InputStream( appStream); - - // First object should be an OID, make sure it is the SPNEGO OID - - derObj = asnAppStream.readObject(); - if ( derObj instanceof DERObjectIdentifier == false) - throw new IOException("Bad blob format (SPNEGO OID)"); - - DERObjectIdentifier derOid = (DERObjectIdentifier) derObj; - if ( derOid.getId().equals( OID.ID_SPNEGO) == false) - throw new IOException("Not an SPNEGO blob"); - - // Next object should be a tagged object with a sequence - - derObj = asnAppStream.readObject(); - if ( derObj instanceof DERTaggedObject == false) - throw new IOException("Bad blob format, tagged object missing"); - - DERTaggedObject derTagSeq = (DERTaggedObject) derObj; - if ( derTagSeq.getTagNo() != 0 || derTagSeq.getObject() instanceof DERSequence == false) - throw new IOException("Bad blob format, sequence missing"); - - // Enumerate the main NegTokenInit sequence - - DERSequence negTokInitSeq = (DERSequence) derTagSeq.getObject(); - Enumeration seqEnum = negTokInitSeq.getObjects(); - - while ( seqEnum.hasMoreElements()) - { - // Read an object from the sequence - - derObj = (DERObject) seqEnum.nextElement(); - if ( derObj instanceof DERTaggedObject) - { - // Tag 0 should be a sequence of object identifiers - - DERTaggedObject derTag = (DERTaggedObject) derObj; - if ( derTag.getTagNo() == 0 && derTag.getObject() instanceof DERSequence) - { - DERSequence derSeq = (DERSequence) derTag.getObject(); - Enumeration typesEnum = derSeq.getObjects(); - - // Allocate the OID list - - m_mechTypes = new Oid[derSeq.size()]; - int idx = 0; - - while( typesEnum.hasMoreElements()) - { - derObj = (DERObject) typesEnum.nextElement(); - if ( derObj instanceof DERObjectIdentifier) - { - derOid = (DERObjectIdentifier) derObj; - try - { - m_mechTypes[idx++] = new Oid( derOid.getId()); - } - catch (GSSException ex) - { - throw new IOException("Bad mechType OID"); - } - } - } - } - else if ( derTag.getTagNo() == 1 && derTag.getObject() instanceof DERBitString) - { - // Context flags - - } - else if ( derTag.getTagNo() == 2 && derTag.getObject() instanceof DEROctetString) - { - // Unpack the mechToken - - DEROctetString derStr = (DEROctetString) derTag.getObject(); - m_mechToken = derStr.getOctets(); - } - else if ( derTag.getTagNo() == 3 &&derTag.getObject() instanceof DEROctetString) - { - // mechListMIC - - } - else if ( derTag.getTagNo() == 3 && derTag.getObject() instanceof DERSequence) - { - // mechListMIC (Microsoft) - - DERSequence derSeq = (DERSequence) derTag.getObject(); - - Enumeration subEnum = derSeq.getObjects(); - while( subEnum.hasMoreElements()) - { - derObj = (DERObject) subEnum.nextElement(); - System.out.println("mechListMIC Seq: " + derObj); - } - } - else - throw new IOException("Bad format, unexpected type"); - } - else - throw new IOException("Bad format, untagged type"); - } - } - - /** - * Encode an SPNEGO NegTokenInit blob - * - * @return byte[] - * @exception IOException - */ - public byte[] encode() throws IOException - { - ByteArrayOutputStream tokStream = new ByteArrayOutputStream(); - - // Create an SPNEGO NegTokenInit token - - DEROutputStream derOut = new DEROutputStream( tokStream); - - derOut.writeObject( new DERObjectIdentifier( OID.ID_SPNEGO)); - ASN1EncodableVector asnList = new ASN1EncodableVector(); - - // Build the mechTypes sequence - - ASN1EncodableVector mechTypesList = new ASN1EncodableVector(); - - for ( Oid mechType : m_mechTypes) - { - mechTypesList.add( new DERObjectIdentifier( mechType.toString())); - } - - asnList.add( new DERTaggedObject( true, 0, new DERSequence( mechTypesList))); - - // Build the mechListMIC - // - // Note: This field is not as specified - - if ( m_mecListMICPrincipal != null) - { - ASN1EncodableVector micList = new ASN1EncodableVector(); - - micList.add( new DERTaggedObject( true, 0, new DERGeneralString( m_mecListMICPrincipal))); - asnList.add( new DERTaggedObject( true, 3, new DERSequence( micList))); - } - - // Generate the SPNEGO NegTokenInit blob - - derOut.writeObject( new DERTaggedObject( true, 0, new DERSequence( asnList))); - DERObject token = new DERUnknownTag( DERTags.CONSTRUCTED | DERTags.APPLICATION, tokStream.toByteArray()); - - tokStream = new ByteArrayOutputStream(); - derOut = new DEROutputStream( tokStream); - derOut.writeObject( token); - - return tokStream.toByteArray(); - } - - /** - * Return the NegTokenInit object as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[NegTokenInit "); - - if ( m_mechTypes != null) - { - str.append("mechTypes="); - for ( Oid oid : m_mechTypes) - { - str.append(oid.toString()); - str.append(","); - } - } - - if ( m_contextFlags != -1) - { - str.append(" context=0x"); - str.append(Integer.toHexString(m_contextFlags)); - } - - if ( m_mechToken != null) - { - str.append(" token="); - str.append(m_mechToken.length); - str.append(" bytes"); - - if ( m_mechToken.length > 16) - { - str.append(" ["); - str.append ( HexDump.hexString(m_mechToken, 0, 16, " ")); - str.append("]"); - } - - } - - if ( m_mecListMICPrincipal != null) - { - str.append(" principal="); - str.append(m_mecListMICPrincipal); - } - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenTarg.java b/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenTarg.java deleted file mode 100644 index c85718b424..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/spnego/NegTokenTarg.java +++ /dev/null @@ -1,270 +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.server.auth.spnego; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Enumeration; - -import org.bouncycastle.asn1.ASN1EncodableVector; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.DEREnumerated; -import org.bouncycastle.asn1.DERObject; -import org.bouncycastle.asn1.DERObjectIdentifier; -import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DEROutputStream; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERTaggedObject; -import org.ietf.jgss.GSSException; -import org.ietf.jgss.Oid; - -/** - * NegTokenTarg Class - * - *

Contains the details of an SPNEGO NegTokenTarg blob for use with CIFS. - * - * @author gkspencer - */ -public class NegTokenTarg -{ - // Result code - - private int m_result; - - // Supported mechanism - - private Oid m_supportedMech; - - // Response token - - private byte[] m_responseToken; - - /** - * Class constructor for decoding - */ - public NegTokenTarg() - { - } - - /** - * Class constructor - * - * @param result int - * @param mech Oid - * @param response byte[] - */ - public NegTokenTarg(int result, Oid mech, byte[] response) - { - m_result = result; - m_supportedMech = mech; - m_responseToken = response; - } - - /** - * Return the result - * - * @return int - */ - public final int getResult() - { - return m_result; - } - - /** - * Return the supported mech type Oid - * - * @return Oid - */ - public final Oid getSupportedMech() - { - return m_supportedMech; - } - - /** - * Determine if there is a valid response token - * - * @return boolean - */ - public final boolean hasResponseToken() - { - return m_responseToken != null ? true : false; - } - - /** - * Return the response token - * - * @return byte[] - */ - public final byte[] getResponseToken() - { - return m_responseToken; - } - - /** - * Decode an SPNEGO NegTokenTarg blob - * - * @param buf byte[] - * @param off int - * @param len int - * @exception IOException - */ - public void decode(byte[] buf, int off, int len) throws IOException - { - // Create a stream around the security blob - - ByteArrayInputStream bytStream = new ByteArrayInputStream( buf, off, len); - ASN1InputStream asnStream = new ASN1InputStream( bytStream); - - // Read the top level object from the security blob - - DERObject derObj = asnStream.readObject(); - - if ( derObj instanceof DERTaggedObject == false) - throw new IOException("Bad blob format (Tagged)"); - - // Access the sequence - - DERTaggedObject derTag = (DERTaggedObject) derObj; - if ( derTag.getObject() instanceof DERSequence == false) - throw new IOException("Bad blob format (Seq)"); - - DERSequence derSeq = (DERSequence) derTag.getObject(); - Enumeration seqEnum = derSeq.getObjects(); - - while ( seqEnum.hasMoreElements()) - { - // Read an object from the sequence - - derObj = (DERObject) seqEnum.nextElement(); - if ( derObj instanceof DERTaggedObject) - { - // Tag 0 should be a status - - derTag = (DERTaggedObject) derObj; - if ( derTag.getTagNo() == 0 && derTag.getObject() instanceof DEREnumerated) - { - // Result code - - DEREnumerated derEnum = (DEREnumerated) derTag.getObject(); - m_result = derEnum.getValue().intValue(); - } - else if ( derTag.getTagNo() == 1 && derTag.getObject() instanceof DERObjectIdentifier) - { - // Mech type - - DERObjectIdentifier derOid = (DERObjectIdentifier) derTag.getObject(); - try - { - m_supportedMech = new Oid(derOid.getId()); - } - catch (GSSException ex) - { - } - } - else if ( derTag.getTagNo() == 2 && derTag.getObject() instanceof DEROctetString) - { - // Unpack the response token - - DEROctetString derStr = (DEROctetString) derTag.getObject(); - m_responseToken = derStr.getOctets(); - } - else if ( derTag.getTagNo() == 3 &&derTag.getObject() instanceof DEROctetString) - { - // mechListMIC - - } - else - throw new IOException("Bad format, unexpected type"); - } - else - throw new IOException("Bad format, untagged type"); - } - } - - /** - * Encode an SPNEGO NegTokenTarg blob - * - * @return byte[] - * @exception IOException - */ - public byte[] encode() throws IOException - { - ByteArrayOutputStream tokStream = new ByteArrayOutputStream(); - - // Create an SPNEGO NegTokenTarg token - - DEROutputStream derOut = new DEROutputStream( tokStream); - - ASN1EncodableVector asnList = new ASN1EncodableVector(); - - // Pack the result code - - asnList.add( new DERTaggedObject( true, 0, new DEREnumerated(m_result))); - - // Pack the supportedMech field - - if ( m_supportedMech != null) - asnList.add( new DERTaggedObject( true, 1, new DERObjectIdentifier( m_supportedMech.toString()))); - - // Pack the response token - - if ( m_responseToken != null) - asnList.add( new DERTaggedObject( true, 2, new DEROctetString(m_responseToken))); - - // Generate the SPNEGO NegTokenTarg blob - - derOut.writeObject( new DERTaggedObject( true, SPNEGO.NegTokenTarg, new DERSequence( asnList))); - return tokStream.toByteArray(); - } - - /** - * Return the NegtokenTarg object as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("[NegtokenTarg result="); - str.append( SPNEGO.asResultString( getResult())); - - str.append(" oid="); - str.append( getSupportedMech()); - - str.append(" response="); - if ( hasResponseToken()) - { - str.append(getResponseToken().length); - str.append(" bytes"); - } - else - str.append("null"); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/spnego/OID.java b/source/java/org/alfresco/filesys/server/auth/spnego/OID.java deleted file mode 100644 index 07013ef1b8..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/spnego/OID.java +++ /dev/null @@ -1,82 +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.server.auth.spnego; - -import org.ietf.jgss.GSSException; -import org.ietf.jgss.Oid; - -/** - * OID Class - * - *

Contains Oids used by SPNEGO - * - * @author gkspencer - */ -public class OID -{ - // IDs - - public static final String ID_SPNEGO = "1.3.6.1.5.5.2"; - - // Kerberos providers - - public static final String ID_KERBEROS5 = "1.2.840.113554.1.2.2"; - public static final String ID_MSKERBEROS5 = "1.2.840.48018.1.2.2"; - - // Microsoft NTLM security support provider - - public static final String ID_NTLMSSP = "1.3.6.1.4.1.311.2.2.10"; - - // OIDs - - public static Oid SPNEGO; - - public static Oid KERBEROS5; - public static Oid MSKERBEROS5; - - public static Oid NTLMSSP; - - /** - * Static initializer - */ - - static { - - // Create the OIDs - - try - { - SPNEGO = new Oid(ID_SPNEGO); - - KERBEROS5 = new Oid(ID_KERBEROS5); - MSKERBEROS5 = new Oid( ID_MSKERBEROS5); - - NTLMSSP = new Oid(ID_NTLMSSP); - } - catch ( GSSException ex) - { - } - } -} diff --git a/source/java/org/alfresco/filesys/server/auth/spnego/SPNEGO.java b/source/java/org/alfresco/filesys/server/auth/spnego/SPNEGO.java deleted file mode 100644 index 01344aa1ca..0000000000 --- a/source/java/org/alfresco/filesys/server/auth/spnego/SPNEGO.java +++ /dev/null @@ -1,140 +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.server.auth.spnego; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.DERApplicationSpecific; -import org.bouncycastle.asn1.DERObject; -import org.bouncycastle.asn1.DERTaggedObject; - -/** - * SPNEGO Class - * - *

Contains SPNEGO constants - * - * @author gkspencer - */ -public class SPNEGO -{ - // Message types - - public static final int NegTokenInit = 0; - public static final int NegTokenTarg = 1; - - // NegTokenInit context flags - - public static final int ContextDelete = 0; - public static final int ContextMutual = 1; - public static final int ContextReplay = 2; - public static final int ContextSequence = 3; - public static final int ContextAnon = 4; - public static final int ContextConf = 5; - public static final int ContextInteg = 6; - - // NegTokenTarg result codes - - public static final int AcceptCompleted = 0; - public static final int AcceptIncomplete = 1; - public static final int Reject = 2; - - /** - * Return a result code as a string - * - * @param res int - * @return String - */ - public static String asResultString(int res) - { - String resStr = null; - - switch ( res) - { - case AcceptCompleted: - resStr = "AcceptCompleted"; - break; - case AcceptIncomplete: - resStr = "AcceptIncomplete"; - break; - case Reject: - resStr = "Reject"; - break; - default: - resStr = "" + res; - break; - } - - return resStr; - } - - /** - * Determine the SPNEGO token type - * - * @param buf byte[] - * @param off int - * @param len int - * @return int - * @exception IOException - */ - public static int checkTokenType( byte[] buf, int off, int len) - throws IOException - { - // Create a stream around the security blob - - ByteArrayInputStream bytStream = new ByteArrayInputStream( buf, off, len); - ASN1InputStream asnStream = new ASN1InputStream( bytStream); - - // Read the top level object from the security blob - - DERObject derObj = asnStream.readObject(); - int tokType = -1; - - if ( derObj instanceof DERApplicationSpecific) - { - // Looks like a NegTokenInit token - - tokType = NegTokenInit; - } - else if ( derObj instanceof DERTaggedObject) - { - // Check the tag number - - DERTaggedObject derTag = (DERTaggedObject) derObj; - if ( derTag.getTagNo() == 1) - tokType = NegTokenTarg; - } - - // Close the streams - - asnStream.close(); - bytStream.close(); - - // Return the token type - - return tokType; - } -} diff --git a/source/java/org/alfresco/filesys/server/config/IncompleteConfigurationException.java b/source/java/org/alfresco/filesys/server/config/IncompleteConfigurationException.java deleted file mode 100644 index 0e57d561d0..0000000000 --- a/source/java/org/alfresco/filesys/server/config/IncompleteConfigurationException.java +++ /dev/null @@ -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.server.config; - -/** - *

- * Indicates that the server configuration is incomplete, and the server cannot be started. - *

- * The server name, domain name and network broadcast mask are the minimum parameters that must be - * specified for a server configuration. - */ -public class IncompleteConfigurationException extends Exception -{ - private static final long serialVersionUID = 3617577102334244400L; - - /** - * IncompleteConfigurationException constructor. - */ - public IncompleteConfigurationException() - { - super(); - } - - /** - * IncompleteConfigurationException constructor. - * - * @param s java.lang.String - */ - public IncompleteConfigurationException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/config/InvalidConfigurationException.java b/source/java/org/alfresco/filesys/server/config/InvalidConfigurationException.java deleted file mode 100644 index 9874834b4a..0000000000 --- a/source/java/org/alfresco/filesys/server/config/InvalidConfigurationException.java +++ /dev/null @@ -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.server.config; - -/** - *

- * Indicates that one or more parameters in the server configuration are not valid. - */ -public class InvalidConfigurationException extends Exception -{ - private static final long serialVersionUID = 3257568390900887607L; - - /** - * InvalidConfigurationException constructor. - * - * @param s java.lang.String - */ - public InvalidConfigurationException(String s) - { - super(s); - } - - /** - * InvalidConfigurationException constructor. - * - * @param s java.lang.String - * @param ex Exception - */ - public InvalidConfigurationException(String s, Throwable ex) - { - super(s, ex); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java b/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java deleted file mode 100644 index 9043d4e619..0000000000 --- a/source/java/org/alfresco/filesys/server/config/ServerConfiguration.java +++ /dev/null @@ -1,4209 +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.server.config; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; -import java.security.Provider; -import java.security.Security; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.TimeZone; - -import net.sf.acegisecurity.AuthenticationManager; - -import org.alfresco.config.Config; -import org.alfresco.config.ConfigElement; -import org.alfresco.config.ConfigLookupContext; -import org.alfresco.config.ConfigService; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.alfresco.DesktopAction; -import org.alfresco.filesys.alfresco.DesktopActionException; -import org.alfresco.filesys.alfresco.DesktopActionTable; -import org.alfresco.filesys.avm.AVMContext; -import org.alfresco.filesys.avm.AVMDiskDriver; -import org.alfresco.filesys.avm.AVMShareMapper; -import org.alfresco.filesys.ftp.FTPPath; -import org.alfresco.filesys.ftp.InvalidPathException; -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetBIOSNameList; -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.NetworkServerList; -import org.alfresco.filesys.server.auth.AlfrescoRpcAuthenticator; -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.auth.acl.ACLParseException; -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlList; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.auth.acl.AccessControlParser; -import org.alfresco.filesys.server.auth.acl.DefaultAccessControlManager; -import org.alfresco.filesys.server.auth.acl.InvalidACLTypeException; -import org.alfresco.filesys.server.auth.passthru.DomainMapping; -import org.alfresco.filesys.server.auth.passthru.RangeDomainMapping; -import org.alfresco.filesys.server.auth.passthru.SubnetDomainMapping; -import org.alfresco.filesys.server.core.DeviceContext; -import org.alfresco.filesys.server.core.DeviceContextException; -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.DefaultShareMapper; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.DiskSharedDevice; -import org.alfresco.filesys.server.oncrpc.RpcAuthenticator; -import org.alfresco.filesys.smb.ServerType; -import org.alfresco.filesys.smb.TcpipSMB; -import org.alfresco.filesys.smb.server.repo.ContentContext; -import org.alfresco.filesys.smb.server.repo.HomeShareMapper; -import org.alfresco.filesys.util.IPAddress; -import org.alfresco.filesys.util.StringList; -import org.alfresco.filesys.util.X64; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.repo.security.authentication.NTLMMode; -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; -import org.alfresco.util.AbstractLifecycleBean; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationEvent; - -/** - *

- * Provides the configuration parameters for the network file servers. - * - * @author Gary K. Spencer - */ -public class ServerConfiguration extends AbstractLifecycleBean -{ - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Filesystem configuration constants - - private static final String ConfigArea = "file-servers"; - private static final String ConfigCIFS = "CIFS Server"; - private static final String ConfigFTP = "FTP Server"; - private static final String ConfigNFS = "NFS Server"; - private static final String ConfigFilesystems = "Filesystems"; - private static final String ConfigSecurity = "Filesystem Security"; - - // Server configuration bean name - - public static final String SERVER_CONFIGURATION = "fileServerConfiguration"; - - // SMB/CIFS session debug type strings - // - // Must match the bit mask order - - private static final String m_sessDbgStr[] = { "NETBIOS", "STATE", "NEGOTIATE", "TREE", "SEARCH", "INFO", "FILE", - "FILEIO", "TRANSACT", "ECHO", "ERROR", "IPC", "LOCK", "PKTTYPE", "DCERPC", "STATECACHE", "NOTIFY", - "STREAMS", "SOCKET" }; - - // FTP server debug type strings - - private static final String m_ftpDebugStr[] = { "STATE", "SEARCH", "INFO", "FILE", "FILEIO", "ERROR", "PKTTYPE", - "TIMING", "DATAPORT", "DIRECTORY" }; - - // Default FTP server port - - private static final int DefaultFTPServerPort = 21; - - // Default FTP anonymous account name - - private static final String DefaultFTPAnonymousAccount = "anonymous"; - - // NFS server debug type strings - - private static final String m_nfsDebugStr[] = { "RXDATA", "TXDATA", "DUMPDATA", "SEARCH", "INFO", "FILE", - "FILEIO", "ERROR", "TIMING", "DIRECTORY", "SESSION" }; - - // Platform types - - public enum PlatformType - { - Unknown, WINDOWS, LINUX, SOLARIS, MACOSX - }; - - // Token name to substitute current server name into the CIFS server name - - private static final String TokenLocalName = "${localname}"; - - // Authentication manager - - private AuthenticationManager authenticationManager; - - // Configuration service - - private ConfigService configService; - - // Disk interface to use for shared filesystems - - private DiskInterface diskInterface; - - // AVM filesystem interface - - private DiskInterface avmDiskInterface; - - // Runtime platform type - - private PlatformType m_platform = PlatformType.Unknown; - - // Main server enable flags, to enable SMB, FTP and/or NFS server components - - private boolean m_smbEnable = true; - private boolean m_ftpEnable = true; - private boolean m_nfsEnable = true; - - // Server name - - private String m_name; - - // Server type, used by the host announcer - - private int m_srvType = ServerType.WorkStation + ServerType.Server + ServerType.NTServer; - - // Active server list - - private NetworkServerList m_serverList; - - // Server comment - - private String m_comment; - - // Server domain - - private String m_domain = "WORKGROUP"; - - // Network broadcast mask string - - private String m_broadcast; - - // NetBIOS ports - - private int m_nbNamePort = RFCNetBIOSProtocol.NAME_PORT; - private int m_nbSessPort = RFCNetBIOSProtocol.PORT; - private int m_nbDatagramPort = RFCNetBIOSProtocol.DATAGRAM; - - // Native SMB port - - private int m_tcpSMBPort = TcpipSMB.PORT; - - // Announce the server to network neighborhood, announcement interval in - // minutes - - private boolean m_announce; - private int m_announceInterval; - - // List of shared devices - - private SharedDeviceList m_shareList; - - // Authenticator, used to authenticate users and share connections. - - private CifsAuthenticator m_authenticator; - - // Share mapper - - private ShareMapper m_shareMapper; - - // Access control manager - - private AccessControlManager m_aclManager; - - // Global access control list, applied to all shares that do not have access controls - - private AccessControlList m_globalACLs; - - private boolean m_nbDebug = false; - - private boolean m_announceDebug = false; - - // Default session debugging setting - - private int m_sessDebug; - - // Flags to indicate if NetBIOS, native TCP/IP SMB and/or Win32 NetBIOS - // should be enabled - - private boolean m_netBIOSEnable = false; - private boolean m_tcpSMBEnable = false; - private boolean m_win32NBEnable = false; - - // Address to bind the SMB server to, if null all local addresses are used - - private InetAddress m_smbBindAddress; - - // Address to bind the NetBIOS name server to, if null all addresses are used - - private InetAddress m_nbBindAddress; - - // WINS servers - - private InetAddress m_winsPrimary; - private InetAddress m_winsSecondary; - - // Enable/disable Macintosh extension SMBs - - private boolean m_macExtensions; - - // -------------------------------------------------------------------------------- - // Win32 NetBIOS configuration - // - // Server name to register under Win32 NetBIOS, if not set the main server - // name is used - - private String m_win32NBName; - - // LANA to be used for Win32 NetBIOS, if not specified the first available - // is used - - private int m_win32NBLANA = -1; - - // Send out host announcements via the Win32 NetBIOS interface - - private boolean m_win32NBAnnounce = false; - private int m_win32NBAnnounceInterval; - - // Use Winsock NetBIOS interface if true, else use the Netbios() API interface - - private boolean m_win32NBUseWinsock = true; - - // -------------------------------------------------------------------------------- - // FTP specific configuration parameters - // - // Bind address and FTP server port. - - private InetAddress m_ftpBindAddress; - private int m_ftpPort = DefaultFTPServerPort; - - // Allow anonymous FTP access and anonymous FTP account name - - private boolean m_ftpAllowAnonymous; - private String m_ftpAnonymousAccount; - - // FTP root path, if not specified defaults to listing all shares as the root - - private String m_ftpRootPath; - - // FTP server debug flags - - private int m_ftpDebug; - - // FTP character set - - private String m_ftpCharSet; - - //-------------------------------------------------------------------------------- - // NFS specific configuration parameters - // - // Enable the port mapper server - - private boolean m_nfsPortMapper; - - // Port mapper port - - private int m_portMapperPort; - - // Mount server port - - private int m_mountServerPort; - - // NFS server port - - private int m_nfsServerPort; - - // NFS debug flags - - private int m_nfsDebug; - - // Port mapper and mount server debug enable - - private boolean m_portMapDebug; - private boolean m_mountServerDebug; - - // Thread pool size and packet pool size - - private int m_nfsThreadPoolSize; - private int m_nfsPacketPoolSize; - - // RPC authenticator implementation - - private RpcAuthenticator m_rpcAuthenticator; - - // -------------------------------------------------------------------------------- - // Global server configuration - // - // Timezone name and offset from UTC in minutes - - private String m_timeZone; - private int m_tzOffset; - - // JCE provider class name - - private String m_jceProviderClass; - - // Local server name and domain/workgroup name - - private String m_localName; - private String m_localDomain; - - // flag to indicate successful initialization - - private boolean initialised; - - // Main authentication service, public API - - private AuthenticationService authenticationService; - - // Authentication component, for internal functions - - private AuthenticationComponent m_authenticationComponent; - - // Various services - - private NodeService m_nodeService; - private TenantService m_tenantService; - private SearchService m_searchService; - private NamespaceService m_namespaceService; - private PersonService m_personService; - private TransactionService m_transactionService; - - // Domain mappings, by subnet - - private List m_domainMappings; - - /** - * Class constructor - */ - public ServerConfiguration() - { - // Allocate the shared device list - - m_shareList = new SharedDeviceList(); - - // Use the default share mapper - - m_shareMapper = new DefaultShareMapper(); - - try - { - m_shareMapper.initializeMapper(this, null); - } - catch (InvalidConfigurationException ex) - { - throw new AlfrescoRuntimeException("Failed to initialise share mapper", ex); - } - - // Set the default access control manager - - m_aclManager = new DefaultAccessControlManager(); - m_aclManager.initialize(this, null); - - // Use the default timezone - - try - { - setTimeZone(TimeZone.getDefault().getID()); - } - catch (Exception ex) - { - throw new AlfrescoRuntimeException("Failed to set timezone", ex); - } - - // Allocate the active server list - - m_serverList = new NetworkServerList(); - } - - /** - * Set the authentication manager - * - * @param authenticationManager AuthenticationManager - */ - public void setAuthenticationManager(AuthenticationManager authenticationManager) - { - this.authenticationManager = authenticationManager; - } - - /** - * Set the authentication service - * - * @param authenticationService AuthenticationService - */ - public void setAuthenticationService(AuthenticationService authenticationService) - { - this.authenticationService = authenticationService; - } - - /** - * Set the configuration service - * - * @param configService ConfigService - */ - public void setConfigService(ConfigService configService) - { - this.configService = configService; - } - - /** - * Set the filesystem driver for the node service based filesystem - * - * @param diskInterface DiskInterface - */ - public void setDiskInterface(DiskInterface diskInterface) - { - this.diskInterface = diskInterface; - } - - /** - * Set the filesystem driver for the AVM based filesystem - * - */ - public void setAvmDiskInterface(DiskInterface diskInterface) - { - this.avmDiskInterface = diskInterface; - } - - /** - * Set the authentication component - * - * @param component AuthenticationComponent - */ - public void setAuthenticationComponent(AuthenticationComponent component) - { - m_authenticationComponent = component; - } - - /** - * Set the node service - * - * @param service NodeService - */ - public void setNodeService(NodeService service) - { - m_nodeService = service; - } - - /** - * Set the namespace service - * - * @param service NamespaceService - */ - public void setNamespaceService(NamespaceService service) - { - m_namespaceService = service; - } - - /** - * Set the search service - * - * @param service SearchService - */ - public void setSearchService(SearchService service) - { - m_searchService = service; - } - - /** - * Set the tenant service - * - * @param service TenantService - */ - public void setTenantService(TenantService service) - { - m_tenantService = service; - } - - /** - * Set the person service - * - * @param service PersonService - */ - public void setPersonService(PersonService service) - { - m_personService = service; - } - - /** - * Set the transaction service - * - * @param service TransactionService - */ - public void setTransactionService(TransactionService service) - { - m_transactionService = service; - } - - /** - * Check if the configuration has been initialized - * - * @return Returns true if the configuration was fully initialised - */ - public boolean isInitialised() - { - return initialised; - } - - /** - * Initialize the configuration using the configuration service - */ - public void init() - { - // check that all required properties have been set - if (authenticationManager == null) - { - throw new AlfrescoRuntimeException("Property 'authenticationManager' not set"); - } - else if (m_authenticationComponent == null) - { - throw new AlfrescoRuntimeException("Property 'authenticationComponent' not set"); - } - else if (authenticationService == null) - { - throw new AlfrescoRuntimeException("Property 'authenticationService' not set"); - } - else if (m_nodeService == null) - { - throw new AlfrescoRuntimeException("Property 'nodeService' not set"); - } - else if (m_tenantService == null) - { - throw new AlfrescoRuntimeException("Property 'tenantService' not set"); - } - else if (m_searchService == null) - { - throw new AlfrescoRuntimeException("Property 'searchService' not set"); - } - else if (m_namespaceService == null) - { - throw new AlfrescoRuntimeException("Property 'namespaceService' not set"); - } - else if (m_personService == null) - { - throw new AlfrescoRuntimeException("Property 'personService' not set"); - } - else if (m_transactionService == null) - { - throw new AlfrescoRuntimeException("Property 'transactionService' not set"); - } - else if (diskInterface == null) - { - throw new AlfrescoRuntimeException("Property 'diskInterface' not set"); - } - else if (configService == null) - { - throw new AlfrescoRuntimeException("Property 'configService' not set"); - } - - // Create the configuration context - - ConfigLookupContext configCtx = new ConfigLookupContext(ConfigArea); - - // Set the platform type - - determinePlatformType(); - - // Initialize the filesystems - - boolean filesysInitOK = false; - Config config = null; - - try - { - // Process the filesystems configuration - - config = configService.getConfig(ConfigFilesystems, configCtx); - processFilesystemsConfig(config); - - // Indicate that the filesystems were initialized - - filesysInitOK = true; - } - catch (Exception ex) - { - // Configuration error - - logger.error("File server configuration error, " + ex.getMessage(), ex); - } - - // Initialize the CIFS and FTP servers, if the filesystem(s) initialized successfully - - if ( filesysInitOK == true) - { - // Initialize the CIFS server - - try - { - - // Process the CIFS server configuration - - config = configService.getConfig(ConfigCIFS, configCtx); - processCIFSServerConfig(config); - - // Process the security configuration - - config = configService.getConfig(ConfigSecurity, configCtx); - processSecurityConfig(config); - - // Log the successful startup - - logger.info("CIFS server " + (isSMBServerEnabled() ? "" : "NOT ") + "started"); - } - catch (UnsatisfiedLinkError ex) - { - // Error accessing the Win32NetBIOS DLL code - - logger.error("Error accessing Win32 NetBIOS, check DLL is on the path"); - - // Disable the CIFS server - - setNetBIOSSMB(false); - setTcpipSMB(false); - setWin32NetBIOS(false); - - setSMBServerEnabled(false); - } - catch (Throwable ex) - { - // Configuration error - - logger.error("CIFS server configuration error, " + ex.getMessage(), ex); - - // Disable the CIFS server - - setNetBIOSSMB(false); - setTcpipSMB(false); - setWin32NetBIOS(false); - - setSMBServerEnabled(false); - } - - // Initialize the FTP server - - try - { - // Process the FTP server configuration - - config = configService.getConfig(ConfigFTP, configCtx); - processFTPServerConfig(config); - - // Log the successful startup - - logger.info("FTP server " + (isFTPServerEnabled() ? "" : "NOT ") + "started"); - } - catch (Exception ex) - { - // Configuration error - - logger.error("FTP server configuration error, " + ex.getMessage(), ex); - } - - // Initialize the NFS server - - try - { - // Process the NFS server configuration - - config = configService.getConfig(ConfigNFS, configCtx); - processNFSServerConfig(config); - - // Log the successful startup - - logger.info("NFS server " + (isNFSServerEnabled() ? "" : "NOT ") + "started"); - } - catch (Exception ex) - { - // Configuration error - - logger.error("NFS server configuration error, " + ex.getMessage(), ex); - } - } - else - { - // Log the error - - logger.error("CIFS and FTP servers not started due to filesystem initialization error"); - } - } - - /** - * Determine the platform type - */ - private final void determinePlatformType() - { - // Get the operating system type - - String osName = System.getProperty("os.name"); - - if (osName.startsWith("Windows")) - m_platform = PlatformType.WINDOWS; - else if (osName.equalsIgnoreCase("Linux")) - m_platform = PlatformType.LINUX; - else if (osName.startsWith("Mac OS X")) - m_platform = PlatformType.MACOSX; - else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) - m_platform = PlatformType.SOLARIS; - } - - /** - * Return the platform type - * - * @return PlatformType - */ - public final PlatformType getPlatformType() - { - return m_platform; - } - - /** - * Process the CIFS server configuration - * - * @param config Config - */ - private final void processCIFSServerConfig(Config config) - { - // If the configuration section is not valid then CIFS is disabled - - if ( config == null) - { - setSMBServerEnabled(false); - return; - } - - // Check if the server has been disabled - - ConfigElement elem = config.getConfigElement( "serverEnable"); - if ( elem != null) - { - // Check for the enabled attribute - - String srvEnable = elem.getAttribute( "enabled"); - if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) - { - setSMBServerEnabled(false); - return; - } - } - - // Get the network broadcast address - // - // Note: We need to set this first as the call to getLocalDomainName() may use a NetBIOS - // name lookup, so the broadcast mask must be set before then. - - elem = config.getConfigElement("broadcast"); - if (elem != null) - { - - // Check if the broadcast mask is a valid numeric IP address - - if (IPAddress.isNumericAddress(elem.getValue()) == false) - throw new AlfrescoRuntimeException("Invalid broadcast mask, must be n.n.n.n format"); - - // Set the network broadcast mask - - setBroadcastMask(elem.getValue()); - } - - // Get the host configuration - - elem = config.getConfigElement("host"); - if (elem == null) - throw new AlfrescoRuntimeException("CIFS server host settings not specified"); - - String hostName = elem.getAttribute("name"); - if (hostName == null || hostName.length() == 0) - throw new AlfrescoRuntimeException("Host name not specified or invalid"); - - // Check if the host name contains the local name token - - int pos = hostName.indexOf(TokenLocalName); - if (pos != -1) - { - - // Get the local server name - - String srvName = getLocalServerName(true); - - // Rebuild the host name substituting the token with the local server name - - StringBuilder hostStr = new StringBuilder(); - - hostStr.append(hostName.substring(0, pos)); - hostStr.append(srvName); - - pos += TokenLocalName.length(); - if (pos < hostName.length()) - hostStr.append(hostName.substring(pos)); - - hostName = hostStr.toString(); - - // Make sure the CIFS server name does not match the local server name - - if (hostName.equals(srvName) && getPlatformType() == PlatformType.WINDOWS) - throw new AlfrescoRuntimeException("CIFS server name must be unique"); - } - - // Check if the host name is longer than 15 characters. NetBIOS only allows a maximum of 16 characters in the - // server name with the last character reserved for the service type. - - if ( hostName.length() > 15) - { - // Truncate the CIFS server name - - hostName = hostName.substring(0, 15); - - // Output a warning - - logger.warn("CIFS server name is longer than 15 characters, truncated to " + hostName); - } - - // Set the CIFS server name - - setServerName(hostName.toUpperCase()); - - // Get the domain/workgroup name - - String domain = elem.getAttribute("domain"); - if (domain != null && domain.length() > 0) - { - // Set the domain/workgroup name - - setDomainName(domain.toUpperCase()); - } - else - { - // Get the local domain/workgroup name - - String localDomain = getLocalDomainName(); - - if ( localDomain == null && getPlatformType() != PlatformType.WINDOWS) - { - // Use a default domain/workgroup name - - localDomain = "WORKGROUP"; - - // Output a warning - - logger.error("Failed to get local domain/workgroup name, using default of " + localDomain); - logger.error("(This may be due to firewall settings or incorrect setting)"); - } - - // Set the local domain/workgroup that the CIFS server belongs to - - setDomainName( localDomain); - } - - // Check for a server comment - - elem = config.getConfigElement("comment"); - if (elem != null) - setComment(elem.getValue()); - - // Check for a bind address - - elem = config.getConfigElement("bindto"); - if (elem != null) - { - - // Validate the bind address - - String bindText = elem.getValue(); - - try - { - - // Check the bind address - - InetAddress bindAddr = InetAddress.getByName(bindText); - - // Set the bind address for the server - - setSMBBindAddress(bindAddr); - } - catch (UnknownHostException ex) - { - throw new AlfrescoRuntimeException("Invalid CIFS server bind address"); - } - } - - // Check if the host announcer should be enabled - - elem = config.getConfigElement("hostAnnounce"); - if (elem != null) - { - - // Check for an announcement interval - - String interval = elem.getAttribute("interval"); - if (interval != null && interval.length() > 0) - { - try - { - setHostAnnounceInterval(Integer.parseInt(interval)); - } - catch (NumberFormatException ex) - { - throw new AlfrescoRuntimeException("Invalid host announcement interval"); - } - } - - // Check if the domain name has been set, this is required if the - // host announcer is enabled - - if (getDomainName() == null) - throw new AlfrescoRuntimeException("Domain name must be specified if host announcement is enabled"); - - // Enable host announcement - - setHostAnnouncer(true); - } - - // Check if NetBIOS SMB is enabled - - elem = config.getConfigElement("netBIOSSMB"); - if (elem != null) - { - // Check if NetBIOS over TCP/IP is enabled for the current platform - - String platformsStr = elem.getAttribute("platforms"); - boolean platformOK = false; - - if (platformsStr != null) - { - // Parse the list of platforms that NetBIOS over TCP/IP is to be enabled for and - // check if the current platform is included - - EnumSet enabledPlatforms = parsePlatformString(platformsStr); - if (enabledPlatforms.contains(getPlatformType())) - platformOK = true; - } - else - { - // No restriction on platforms - - platformOK = true; - } - - // Enable the NetBIOS SMB support, if enabled for this platform - - setNetBIOSSMB(platformOK); - - // Parse/check NetBIOS settings, if enabled - - if ( hasNetBIOSSMB()) - { - // Check if the broadcast mask has been specified - - if (getBroadcastMask() == null) - throw new AlfrescoRuntimeException("Network broadcast mask not specified"); - - // Check for a bind address - - String bindto = elem.getAttribute("bindto"); - if (bindto != null && bindto.length() > 0) - { - - // Validate the bind address - - try - { - - // Check the bind address - - InetAddress bindAddr = InetAddress.getByName(bindto); - - // Set the bind address for the NetBIOS name server - - setNetBIOSBindAddress(bindAddr); - } - catch (UnknownHostException ex) - { - throw new AlfrescoRuntimeException("Invalid NetBIOS bind address"); - } - } - else if (hasSMBBindAddress()) - { - - // Use the SMB bind address for the NetBIOS name server - - setNetBIOSBindAddress(getSMBBindAddress()); - } - else - { - // Get a list of all the local addresses - - InetAddress[] addrs = null; - - try - { - // Get the local server IP address list - - addrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()); - } - catch (UnknownHostException ex) - { - logger.error("Failed to get local address list", ex); - } - - // Check the address list for one or more valid local addresses filtering out the loopback address - - int addrCnt = 0; - - if ( addrs != null) - { - for (int i = 0; i < addrs.length; i++) - { - - // Check for a valid address, filter out '127.0.0.1' and '0.0.0.0' addresses - - if (addrs[i].getHostAddress().equals("127.0.0.1") == false - && addrs[i].getHostAddress().equals("0.0.0.0") == false) - addrCnt++; - } - } - - // Check if any addresses were found - - if ( addrCnt == 0) - { - // Enumerate the network adapter list - - Enumeration niEnum = null; - - try - { - niEnum = NetworkInterface.getNetworkInterfaces(); - } - catch (SocketException ex) - { - } - - if ( niEnum != null) - { - while ( niEnum.hasMoreElements()) - { - // Get the current network interface - - NetworkInterface ni = niEnum.nextElement(); - - // Enumerate the addresses for the network adapter - - Enumeration niAddrs = ni.getInetAddresses(); - if ( niAddrs != null) - { - // Check for any valid addresses - - while ( niAddrs.hasMoreElements()) - { - InetAddress curAddr = niAddrs.nextElement(); - - if ( curAddr.getHostAddress().equals("127.0.0.1") == false && - curAddr.getHostAddress().equals("0.0.0.0") == false) - addrCnt++; - } - } - } - - // DEBUG - - if ( addrCnt > 0 && logger.isDebugEnabled()) - logger.debug("Found valid IP address from interface list"); - } - - // Check if we found any valid network addresses - - if ( addrCnt == 0) - { - // Log the available IP addresses - - if ( logger.isDebugEnabled()) - { - logger.debug("Local address list dump :-"); - if ( addrs != null) - { - for ( int i = 0; i < addrs.length; i++) - logger.debug( " Address: " + addrs[i]); - } - else - logger.debug(" No addresses"); - } - - // Throw an exception to stop the CIFS/NetBIOS name server from starting - - throw new AlfrescoRuntimeException( "Failed to get IP address(es) for the local server, check hosts file and/or DNS setup"); - } - } - } - - // Check if the session port has been specified - - String portNum = elem.getAttribute("sessionPort"); - if ( portNum != null && portNum.length() > 0) { - try { - setNetBIOSSessionPort(Integer.parseInt(portNum)); - if ( getNetBIOSSessionPort() <= 0 || getNetBIOSSessionPort() >= 65535) - throw new AlfrescoRuntimeException("NetBIOS session port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NetBIOS session port"); - } - } - - // Check if the name port has been specified - - portNum = elem.getAttribute("namePort"); - if ( portNum != null && portNum.length() > 0) { - try { - setNetBIOSNamePort(Integer.parseInt(portNum)); - if ( getNetBIOSNamePort() <= 0 || getNetBIOSNamePort() >= 65535) - throw new AlfrescoRuntimeException("NetBIOS name port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NetBIOS name port"); - } - } - - // Check if the datagram port has been specified - - portNum = elem.getAttribute("datagramPort"); - if ( portNum != null && portNum.length() > 0) { - try { - setNetBIOSDatagramPort(Integer.parseInt(portNum)); - if ( getNetBIOSDatagramPort() <= 0 || getNetBIOSDatagramPort() >= 65535) - throw new AlfrescoRuntimeException("NetBIOS datagram port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NetBIOS datagram port"); - } - } - } - } - else - { - - // Disable NetBIOS SMB support - - setNetBIOSSMB(false); - } - - // Check if TCP/IP SMB is enabled - - elem = config.getConfigElement("tcpipSMB"); - if (elem != null) - { - - // Check if native SMB is enabled for the current platform - - String platformsStr = elem.getAttribute("platforms"); - boolean platformOK = false; - - if (platformsStr != null) - { - // Parse the list of platforms that native SMB is to be enabled for and - // check if the current platform is included - - EnumSet enabledPlatforms = parsePlatformString(platformsStr); - if (enabledPlatforms.contains(getPlatformType())) - platformOK = true; - } - else - { - // No restriction on platforms - - platformOK = true; - } - - // Enable the TCP/IP SMB support, if enabled for this platform - - setTcpipSMB(platformOK); - - // Check if the port has been specified - - String portNum = elem.getAttribute("port"); - if ( portNum != null && portNum.length() > 0) { - try { - setTcpipSMBPort(Integer.parseInt(portNum)); - if ( getTcpipSMBPort() <= 0 || getTcpipSMBPort() >= 65535) - throw new AlfrescoRuntimeException("TCP/IP SMB port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid TCP/IP SMB port"); - } - } - } - else - { - - // Disable TCP/IP SMB support - - setTcpipSMB(false); - } - - // Check if Win32 NetBIOS is enabled - - elem = config.getConfigElement("Win32NetBIOS"); - if (elem != null) - { - - // Check if the Win32 NetBIOS server name has been specified - - String win32Name = elem.getAttribute("name"); - if (win32Name != null && win32Name.length() > 0) - { - - // Validate the name - - if (win32Name.length() > 16) - throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS name, " + win32Name); - - // Set the Win32 NetBIOS file server name - - setWin32NetBIOSName(win32Name); - } - - // Check if the Win32 NetBIOS LANA has been specified - - String lanaStr = elem.getAttribute("lana"); - if (lanaStr != null && lanaStr.length() > 0) - { - // Check if the LANA has been specified as an IP address or adapter name - - int lana = -1; - - if ( IPAddress.isNumericAddress( lanaStr)) - { - - // Convert the IP address to a LANA id - - lana = Win32NetBIOS.getLANAForIPAddress( lanaStr); - if ( lana == -1) - throw new AlfrescoRuntimeException( "Failed to convert IP address " + lanaStr + " to a LANA"); - } - else if ( lanaStr.length() > 1 && Character.isLetter( lanaStr.charAt( 0))) { - - // Convert the network adapter to a LANA id - - lana = Win32NetBIOS.getLANAForAdapterName( lanaStr); - if ( lana == -1) - throw new AlfrescoRuntimeException( "Failed to convert network adapter " + lanaStr + " to a LANA"); - } - else { - - try - { - lana = Integer.parseInt(lanaStr); - } - catch (NumberFormatException ex) - { - throw new AlfrescoRuntimeException("Invalid win32 NetBIOS LANA specified"); - } - } - - // LANA should be in the range 0-255 - - if (lana < 0 || lana > 255) - throw new AlfrescoRuntimeException("Invalid Win32 NetBIOS LANA number, " + lana); - - // Set the LANA number - - setWin32LANA(lana); - } - - // Check if the native NetBIOS interface has been specified, either 'winsock' or 'netbios' - - String nativeAPI = elem.getAttribute("api"); - if ( nativeAPI != null && nativeAPI.length() > 0) - { - // Validate the API type - - boolean useWinsock = true; - - if ( nativeAPI.equalsIgnoreCase("netbios")) - useWinsock = false; - else if ( nativeAPI.equalsIgnoreCase("winsock") == false) - throw new AlfrescoRuntimeException("Invalid NetBIOS API type, spefify 'winsock' or 'netbios'"); - - // Set the NetBIOS API to use - - setWin32WinsockNetBIOS( useWinsock); - } - - // Force the older NetBIOS API code to be used on 64Bit Windows - - if ( useWinsockNetBIOS() == true && X64.isWindows64()) - { - // Log a warning - - logger.warn("Using older Netbios() API code"); - - // Use the older NetBIOS API code - - setWin32WinsockNetBIOS( false); - } - - // Check if the current operating system is supported by the Win32 - // NetBIOS handler - - String osName = System.getProperty("os.name"); - if (osName.startsWith("Windows") - && (osName.endsWith("95") == false && osName.endsWith("98") == false && osName.endsWith("ME") == false)) - { - - // Call the Win32NetBIOS native code to make sure it is initialized - - if ( Win32NetBIOS.LanaEnumerate() != null) - { - // Enable Win32 NetBIOS - - setWin32NetBIOS(true); - } - else - { - logger.warn("No NetBIOS LANAs available"); - } - } - else - { - - // Win32 NetBIOS not supported on the current operating system - - setWin32NetBIOS(false); - } - } - else - { - - // Disable Win32 NetBIOS - - setWin32NetBIOS(false); - } - - // Check if the host announcer should be enabled - - elem = config.getConfigElement("Win32Announce"); - if (elem != null) - { - - // Check for an announcement interval - - String interval = elem.getAttribute("interval"); - if (interval != null && interval.length() > 0) - { - try - { - setWin32HostAnnounceInterval(Integer.parseInt(interval)); - } - catch (NumberFormatException ex) - { - throw new AlfrescoRuntimeException("Invalid host announcement interval"); - } - } - - // Check if the domain name has been set, this is required if the - // host announcer is enabled - - if (getDomainName() == null) - throw new AlfrescoRuntimeException("Domain name must be specified if host announcement is enabled"); - - // Enable Win32 NetBIOS host announcement - - setWin32HostAnnouncer(true); - } - - // Check if NetBIOS and/or TCP/IP SMB have been enabled - - if (hasNetBIOSSMB() == false && hasTcpipSMB() == false && hasWin32NetBIOS() == false) - throw new AlfrescoRuntimeException("NetBIOS SMB, TCP/IP SMB or Win32 NetBIOS must be enabled"); - - // Check if WINS servers are configured - - elem = config.getConfigElement("WINS"); - - if (elem != null) - { - - // Get the primary WINS server - - ConfigElement priWinsElem = elem.getChild("primary"); - - if (priWinsElem == null || priWinsElem.getValue().length() == 0) - throw new AlfrescoRuntimeException("No primary WINS server configured"); - - // Validate the WINS server address - - InetAddress primaryWINS = null; - - try - { - primaryWINS = InetAddress.getByName(priWinsElem.getValue()); - } - catch (UnknownHostException ex) - { - throw new AlfrescoRuntimeException("Invalid primary WINS server address, " + priWinsElem.getValue()); - } - - // Check if a secondary WINS server has been specified - - ConfigElement secWinsElem = elem.getChild("secondary"); - InetAddress secondaryWINS = null; - - if (secWinsElem != null) - { - - // Validate the secondary WINS server address - - try - { - secondaryWINS = InetAddress.getByName(secWinsElem.getValue()); - } - catch (UnknownHostException ex) - { - throw new AlfrescoRuntimeException("Invalid secondary WINS server address, " - + secWinsElem.getValue()); - } - } - - // Set the WINS server address(es) - - setPrimaryWINSServer(primaryWINS); - if (secondaryWINS != null) - setSecondaryWINSServer(secondaryWINS); - - // Pass the setting to the NetBIOS session class - - NetBIOSSession.setWINSServer(primaryWINS); - } - - // Check if WINS is configured, if we are running on Windows and socket based NetBIOS is enabled - - else if (hasNetBIOSSMB() && getPlatformType() == PlatformType.WINDOWS) - { - // Get the WINS server list - - String winsServers = Win32NetBIOS.getWINSServerList(); - - if (winsServers != null) - { - // Use the first WINS server address for now - - StringTokenizer tokens = new StringTokenizer(winsServers, ","); - String addr = tokens.nextToken(); - - try - { - // Convert to a network address and check if the WINS server is accessible - - InetAddress winsAddr = InetAddress.getByName(addr); - - Socket winsSocket = new Socket(); - InetSocketAddress sockAddr = new InetSocketAddress( winsAddr, RFCNetBIOSProtocol.NAME_PORT); - - winsSocket.connect(sockAddr, 3000); - winsSocket.close(); - - // Set the primary WINS server address - - setPrimaryWINSServer(winsAddr); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("Configuring to use WINS server " + addr); - } - catch (UnknownHostException ex) - { - throw new AlfrescoRuntimeException("Invalid auto WINS server address, " + addr); - } - catch (IOException ex) - { - if ( logger.isDebugEnabled()) - logger.debug("Failed to connect to auto WINS server " + addr); - } - } - } - - // Check if session debug is enabled - - elem = config.getConfigElement("sessionDebug"); - if (elem != null) - { - - // Check for session debug flags - - String flags = elem.getAttribute("flags"); - int sessDbg = 0; - - if (flags != null) - { - - // Parse the flags - - flags = flags.toUpperCase(); - StringTokenizer token = new StringTokenizer(flags, ","); - - while (token.hasMoreTokens()) - { - - // Get the current debug flag token - - String dbg = token.nextToken().trim(); - - // Find the debug flag name - - int idx = 0; - - while (idx < m_sessDbgStr.length && m_sessDbgStr[idx].equalsIgnoreCase(dbg) == false) - idx++; - - if (idx > m_sessDbgStr.length) - throw new AlfrescoRuntimeException("Invalid session debug flag, " + dbg); - - // Set the debug flag - - sessDbg += 1 << idx; - } - } - - // Set the session debug flags - - setSessionDebugFlags(sessDbg); - } - } - - /** - * Process the FTP server configuration - * - * @param config Config - */ - private final void processFTPServerConfig(Config config) - { - // If the configuration section is not valid then FTP is disabled - - if ( config == null) - { - setFTPServerEnabled(false); - return; - } - - // Check if the server has been disabled - - ConfigElement elem = config.getConfigElement( "serverEnable"); - if ( elem != null) - { - // Check for the enabled attribute - - String srvEnable = elem.getAttribute( "enabled"); - if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) - { - setFTPServerEnabled(false); - return; - } - } - - // Check for a bind address - - elem = config.getConfigElement("bindto"); - if ( elem != null) { - - // Validate the bind address - - String bindText = elem.getValue(); - - try { - - // Check the bind address - - InetAddress bindAddr = InetAddress.getByName(bindText); - - // Set the bind address for the FTP server - - setFTPBindAddress(bindAddr); - } - catch (UnknownHostException ex) { - throw new AlfrescoRuntimeException("Invalid FTP bindto address, " + elem.getValue()); - } - } - - // Check for an FTP server port - - elem = config.getConfigElement("port"); - if ( elem != null) { - try { - setFTPPort(Integer.parseInt(elem.getValue())); - if ( getFTPPort() <= 0 || getFTPPort() >= 65535) - throw new AlfrescoRuntimeException("FTP server port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid FTP server port"); - } - } - else { - - // Use the default FTP port - - setFTPPort(DefaultFTPServerPort); - } - - // Check if anonymous login is allowed - - elem = config.getConfigElement("allowAnonymous"); - if ( elem != null) { - - // Enable anonymous login to the FTP server - - setAllowAnonymousFTP(true); - - // Check if an anonymous account has been specified - - String anonAcc = elem.getAttribute("user"); - if ( anonAcc != null && anonAcc.length() > 0) { - - // Set the anonymous account name - - setAnonymousFTPAccount(anonAcc); - - // Check if the anonymous account name is valid - - if ( getAnonymousFTPAccount() == null || getAnonymousFTPAccount().length() == 0) - throw new AlfrescoRuntimeException("Anonymous FTP account invalid"); - } - else { - - // Use the default anonymous account name - - setAnonymousFTPAccount(DefaultFTPAnonymousAccount); - } - } - else { - - // Disable anonymous logins - - setAllowAnonymousFTP(false); - } - - // Check if a root path has been specified - - elem = config.getConfigElement("rootDirectory"); - if ( elem != null) { - - // Get the root path - - String rootPath = elem.getValue(); - - // Validate the root path - - try { - - // Parse the path - - new FTPPath(rootPath); - - // Set the root path - - setFTPRootPath(rootPath); - } - catch (InvalidPathException ex) { - throw new AlfrescoRuntimeException("Invalid FTP root directory, " + rootPath); - } - } - - // Check if FTP debug is enabled - - elem = config.getConfigElement("debug"); - if (elem != null) { - - // Check for FTP debug flags - - String flags = elem.getAttribute("flags"); - int ftpDbg = 0; - - if ( flags != null) { - - // Parse the flags - - flags = flags.toUpperCase(); - StringTokenizer token = new StringTokenizer(flags,","); - - while ( token.hasMoreTokens()) { - - // Get the current debug flag token - - String dbg = token.nextToken().trim(); - - // Find the debug flag name - - int idx = 0; - - while ( idx < m_ftpDebugStr.length && m_ftpDebugStr[idx].equalsIgnoreCase(dbg) == false) - idx++; - - if ( idx >= m_ftpDebugStr.length) - throw new AlfrescoRuntimeException("Invalid FTP debug flag, " + dbg); - - // Set the debug flag - - ftpDbg += 1 << idx; - } - } - - // Set the FTP debug flags - - setFTPDebug(ftpDbg); - } - - // Check if a character set has been specified - - elem = config.getConfigElement( "charSet"); - if ( elem != null) { - - try { - - // Validate the character set name - - Charset.forName( elem.getValue()); - - // Set the FTP character set - - setFTPCharacterSet( elem.getValue()); - } - catch ( IllegalCharsetNameException ex) { - throw new AlfrescoRuntimeException("Illegal character set name, " + elem.getValue()); - } - catch ( UnsupportedCharsetException ex) { - throw new AlfrescoRuntimeException("Unsupported character set name, " + elem.getValue()); - } - } - } - - /** - * Process the NFS server configuration - * - * @param config Config - */ - private final void processNFSServerConfig(Config config) - { - // If the configuration section is not valid then NFS is disabled - - if ( config == null) - { - setNFSServerEnabled(false); - return; - } - - // Check if the server has been disabled - - ConfigElement elem = config.getConfigElement( "serverEnable"); - if ( elem != null) - { - // Check for the enabled attribute - - String srvEnable = elem.getAttribute( "enabled"); - if ( srvEnable != null && srvEnable.equalsIgnoreCase( "false")) - { - setNFSServerEnabled(false); - return; - } - } - - // Check if the port mapper is enabled - - if ( config.getConfigElement("enablePortMapper") != null) - m_nfsPortMapper = true; - - // Check for the thread pool size - - elem = config.getConfigElement("ThreadPool"); - - if ( elem != null) { - - try { - - // Convert the pool size value - - int poolSize = Integer.parseInt(elem.getValue()); - - // Range check the pool size value - - if ( poolSize < 4) - throw new AlfrescoRuntimeException("NFS thread pool size is below minimum of 4"); - - // Set the thread pool size - - m_nfsThreadPoolSize = poolSize; - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NFS thread pool size setting, " + elem.getValue()); - } - } - - // NFS packet pool size - - elem = config.getConfigElement("PacketPool"); - - if ( elem != null) { - - try { - - // Convert the packet pool size value - - int pktPoolSize = Integer.parseInt(elem.getValue()); - - // Range check the pool size value - - if ( pktPoolSize < 10) - throw new AlfrescoRuntimeException("NFS packet pool size is below minimum of 10"); - - if ( pktPoolSize < getNFSThreadPoolSize() + 1) - throw new AlfrescoRuntimeException("NFS packet pool must be at least thread pool size plus one"); - - // Set the packet pool size - - m_nfsPacketPoolSize = pktPoolSize; - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NFS packet pool size setting, " + elem.getValue()); - } - } - - // Check for a port mapper server port - - elem = config.getConfigElement("PortMapperPort"); - if ( elem != null) { - try { - m_portMapperPort = Integer.parseInt(elem.getValue()); - if ( getPortMapperPort() <= 0 || getPortMapperPort() >= 65535) - throw new AlfrescoRuntimeException("Port mapper server port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid port mapper server port"); - } - } - - // Check for a mount server port - - elem = config.getConfigElement("MountServerPort"); - if ( elem != null) { - try { - m_mountServerPort = Integer.parseInt(elem.getValue()); - if ( getMountServerPort() <= 0 || getMountServerPort() >= 65535) - throw new AlfrescoRuntimeException("Mount server port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid mount server port"); - } - } - - // Check for an NFS server port - - elem = config.getConfigElement("NFSServerPort"); - if ( elem != null) { - try { - m_nfsServerPort = Integer.parseInt(elem.getValue()); - if ( getNFSServerPort() <= 0 || getNFSServerPort() >= 65535) - throw new AlfrescoRuntimeException("NFS server port out of valid range"); - } - catch (NumberFormatException ex) { - throw new AlfrescoRuntimeException("Invalid NFS server port"); - } - } - - // Check if NFS debug is enabled - - elem = config.getConfigElement("debug"); - if (elem != null) { - - // Check for NFS debug flags - - String flags = elem.getAttribute("flags"); - int nfsDbg = 0; - - if ( flags != null) { - - // Parse the flags - - flags = flags.toUpperCase(); - StringTokenizer token = new StringTokenizer(flags,","); - - while ( token.hasMoreTokens()) { - - // Get the current debug flag token - - String dbg = token.nextToken().trim(); - - // Find the debug flag name - - int idx = 0; - - while ( idx < m_nfsDebugStr.length && m_nfsDebugStr[idx].equalsIgnoreCase(dbg) == false) - idx++; - - if ( idx >= m_nfsDebugStr.length) - throw new AlfrescoRuntimeException("Invalid NFS debug flag, " + dbg); - - // Set the debug flag - - nfsDbg += 1 << idx; - } - } - - // Set the NFS debug flags - - m_nfsDebug = nfsDbg; - } - - // Create the RPC authenticator - - elem = config.getConfigElement("rpcAuthenticator"); - if ( elem != null) - { - // Create the RPC authenticator - - m_rpcAuthenticator = new AlfrescoRpcAuthenticator(); - - try - { - // Initialize the RPC authenticator - - m_rpcAuthenticator.initialize( this, elem); - } - catch (InvalidConfigurationException ex) - { - throw new AlfrescoRuntimeException( ex.getMessage()); - } - } - else - throw new AlfrescoRuntimeException("RPC authenticator configuration missing, require user mappings"); - } - - /** - * Process the filesystems configuration - * - * @param config Config - */ - private final void processFilesystemsConfig(Config config) - { - // Check for the home folder filesystem - - ConfigElement homeElem = config.getConfigElement("homeFolder"); - - if ( homeElem != null) - { - try - { - // Create the home folder share mapper - - HomeShareMapper shareMapper = new HomeShareMapper(); - shareMapper.initializeMapper( this, homeElem); - - // Use the home folder share mapper - - m_shareMapper = shareMapper; - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Using home folder share mapper"); - } - catch (InvalidConfigurationException ex) - { - throw new AlfrescoRuntimeException("Failed to initialize home folder share mapper", ex); - } - } - - // Get the top level filesystems configuration element - - ConfigElement filesystems = config.getConfigElement("filesystems"); - - // Get the filesystem configuration elements - - List filesysElems = null; - if ( filesystems != null) - { - // Get the list of filesystems - - filesysElems = filesystems.getChildren(); - } - else - { - // Check for the old style configuration - - ConfigElement filesysElem = config.getConfigElement( "filesystem"); - - if (filesysElem != null) - { - // create a list with the single filesys element in - - filesysElems = new ArrayList(1); - filesysElems.add(filesysElem); - } - - // Warn that the configuration is using the old format - - logger.warn("Old style file-servers.xml configuration being used"); - } - - // Process the filesystems list - - if (filesysElems != null) - { - - // Add the filesystems - - for (int i = 0; i < filesysElems.size(); i++) - { - - // Get the current filesystem configuration - - ConfigElement elem = filesysElems.get(i); - - String filesysType = elem.getName(); - String filesysName = elem.getAttribute("name"); - - try - { - // Check the filesystem type and use the appropriate driver - - DiskSharedDevice filesys = null; - - if ( filesysType.equalsIgnoreCase("avmfilesystem")) - { - // Create a new filesystem driver instance and create a context for - // the new filesystem - - DiskInterface filesysDriver = this.avmDiskInterface; - AVMContext filesysContext = (AVMContext) filesysDriver.createContext( filesysDriver, filesysName, elem); - filesysContext.setFilesystemName(filesysName); - - // Create the shared filesystem - - filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext); - - // Start the filesystem - - filesysContext.startFilesystem(filesys); - } - else - { - // Create a new filesystem driver instance and create a context for - // the new filesystem - - DiskInterface filesysDriver = this.diskInterface; - ContentContext filesysContext = (ContentContext) filesysDriver.createContext( filesysDriver, filesysName, elem); - - // Check if an access control list has been specified - - AccessControlList acls = null; - ConfigElement aclElem = elem.getChild("accessControl"); - - if (aclElem != null) - { - - // Parse the access control list - - acls = processAccessControlList(aclElem); - } - else if (hasGlobalAccessControls()) - { - - // Use the global access control list for this disk share - - acls = getGlobalAccessControls(); - } - - // Check if change notifications are disabled - - boolean changeNotify = elem.getChild("disableChangeNotification") == null ? true : false; - - // Create the shared filesystem - - filesys = new DiskSharedDevice(filesysName, filesysDriver, filesysContext); - - // Attach desktop actions to the filesystem - - ConfigElement deskActionsElem = elem.getChild("desktopActions"); - if ( deskActionsElem != null) - { - // Get the desktop actions list - - DesktopActionTable desktopActions = processDesktopActions(deskActionsElem, filesys); - if ( desktopActions != null) - filesysContext.setDesktopActions( desktopActions, filesysDriver); - } - - // Add any access controls to the share - - filesys.setAccessControlList(acls); - - // Enable/disable change notification for this device - - filesysContext.enableChangeHandler(changeNotify); - - // Start the filesystem - - filesysContext.startFilesystem(filesys); - } - - // Create the shared device and add to the list of available - // shared filesystems - - addShare(filesys); - } - catch (DeviceContextException ex) - { - throw new AlfrescoRuntimeException("Error creating filesystem " + filesysName, ex); - } - } - } - else - { - // No filesystems defined - - logger.warn("No filesystems defined"); - } - - // Check if shares should be added for all AVM stores - - ConfigElement avmAllStoresElem = config.getConfigElement( "avmAllStores"); - - if ( avmAllStoresElem != null && getAvmDiskInterface() != null) - { - // Get the list of store names - - AVMDiskDriver avmDriver = (AVMDiskDriver) getAvmDiskInterface(); - StringList storeNames = avmDriver.getAVMStoreNames(); - - // Add shares for each of the store names, if the share name does not already exist - - if ( storeNames != null && storeNames.numberOfStrings() > 0) - { - // Add a share for each store - - for ( int i = 0; i < storeNames.numberOfStrings(); i++) - { - String storeName = storeNames.getStringAt( i); - - // Check if a share of the same name already exists - - if ( getShares().findShare( storeName, ShareType.DISK, true) == null) - { - // Create the new share for the store - - AVMContext avmContext = new AVMContext( storeName, storeName + ":/", AVMContext.VERSION_HEAD); - avmContext.enableStateTable( true, avmDriver.getStateReaper()); - - // Create the shared filesystem - - addShare( new DiskSharedDevice( storeName, avmDriver, avmContext)); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "Added AVM share " + storeName); - } - } - } - } - - // Check for the AVM version share mapper - - ConfigElement avmMapperElem = config.getConfigElement( "avmVersionMapper"); - - if ( avmMapperElem != null) - { - try - { - // Create the AVM version share mapper - - AVMShareMapper shareMapper = new AVMShareMapper(); - shareMapper.initializeMapper( this, avmMapperElem); - - // Use the AVM version share mapper - - m_shareMapper = shareMapper; - - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Using AVM version share mapper"); - } - catch (InvalidConfigurationException ex) - { - throw new AlfrescoRuntimeException("Failed to initialize AVM version share mapper", ex); - } - } - - } - - /** - * Process the security configuration - * - * @param config Config - */ - private final void processSecurityConfig(Config config) - { - - // Check if global access controls have been specified - - ConfigElement globalACLs = config.getConfigElement("globalAccessControl"); - if (globalACLs != null) - { - - // Parse the access control list - - AccessControlList acls = processAccessControlList(globalACLs); - if (acls != null) - setGlobalAccessControls(acls); - } - - // Check if a JCE provider class has been specified - - ConfigElement jceElem = config.getConfigElement("JCEProvider"); - if (jceElem != null) - { - - // Set the JCE provider - - setJCEProvider(jceElem.getValue()); - } - else - { - // Use the default Bouncy Castle - - setJCEProvider("org.bouncycastle.jce.provider.BouncyCastleProvider"); - } - - // Check if any domain mappings have been specified - - ConfigElement domainMappings = config.getConfigElement( "DomainMappings"); - if ( domainMappings != null) - { - // Get the domain mapping elements - - List mappings = domainMappings.getChildren(); - if ( mappings != null) - { - DomainMapping mapping = null; - - for ( ConfigElement domainMap : mappings) - { - if ( domainMap.getName().equals( "Domain")) - { - // Get the domain name - - String name = domainMap.getAttribute( "name"); - - // Check if the domain is specified by subnet or range - - if ( domainMap.hasAttribute( "subnet")) - { - String subnetStr = domainMap.getAttribute( "subnet"); - String maskStr = domainMap.getAttribute( "mask"); - - // Parse the subnet and mask, to validate and convert to int values - - int subnet = IPAddress.parseNumericAddress( subnetStr); - int mask = IPAddress.parseNumericAddress( maskStr); - - if ( subnet == 0 || mask == 0) - throw new AlfrescoRuntimeException( "Invalid subnet/mask for domain mapping " + name); - - // Create the subnet domain mapping - - mapping = new SubnetDomainMapping( name, subnet, mask); - } - else if ( domainMap.hasAttribute( "rangeFrom")) - { - String rangeFromStr = domainMap.getAttribute( "rangeFrom"); - String rangeToStr = domainMap.getAttribute( "rangeTo"); - - // Parse the range from/to values and convert to int values - - int rangeFrom = IPAddress.parseNumericAddress( rangeFromStr); - int rangeTo = IPAddress.parseNumericAddress( rangeToStr); - - if ( rangeFrom == 0 || rangeTo == 0) - throw new AlfrescoRuntimeException( "Invalid address range domain mapping " + name); - - // Create the subnet domain mapping - - mapping = new RangeDomainMapping( name, rangeFrom, rangeTo); - } - else - throw new AlfrescoRuntimeException( "Invalid domain mapping specified"); - - // Create the domain mapping - - if ( m_domainMappings == null) - m_domainMappings = new ArrayList(); - m_domainMappings.add( mapping); - } - } - } - } - - // Check if an authenticator has been specified - - ConfigElement authElem = config.getConfigElement("authenticator"); - if (authElem != null) - { - - // Get the authenticator type, should be either 'local' or 'passthru' - - String authType = authElem.getAttribute("type"); - if (authType == null) - authType = "alfresco"; - - // Get the authentication component type - - NTLMMode ntlmMode = m_authenticationComponent.getNTLMMode(); - - // Set the authenticator class to use - - CifsAuthenticator auth = null; - - if (authType.equalsIgnoreCase("passthru")) - { - // Check if the appropriate authentication component type is configured - - if ( ntlmMode == NTLMMode.MD4_PROVIDER) - throw new AlfrescoRuntimeException("Wrong authentication setup for passthru authenticator (cannot be used with Alfresco users)"); - - // Load the passthru authenticator dynamically - - auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.passthru.PassthruAuthenticator"); - if ( auth == null) - throw new AlfrescoRuntimeException("Failed to load passthru authenticator"); - } - else if (authType.equalsIgnoreCase("alfresco")) - { - // Standard authenticator requires MD4 or passthru based authentication - - if ( ntlmMode == NTLMMode.NONE) - throw new AlfrescoRuntimeException("Wrong authentication setup for alfresco authenticator"); - - // Load the Alfresco authenticator dynamically - - auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.AlfrescoAuthenticator"); - - if ( auth == null) - throw new AlfrescoRuntimeException("Failed to load Alfresco authenticator"); - } - else if( authType.equalsIgnoreCase("enterprise")) - { - // Load the Enterprise authenticator dynamically - - auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.EnterpriseCifsAuthenticator"); - - if ( auth == null) - throw new AlfrescoRuntimeException("Failed to load Enterprise authenticator"); - } - else - throw new AlfrescoRuntimeException("Invalid authenticator type, " + authType); - - // Get the allow guest and map unknown user to guest settings - - boolean allowGuest = authElem.getChild("allowGuest") != null ? true : false; - boolean mapGuest = authElem.getChild("mapUnknownUserToGuest") != null ? true : false; - - // Initialize and set the authenticator class - - setAuthenticator(auth, authElem, allowGuest); - auth.setMapToGuest( mapGuest); - } - else - throw new AlfrescoRuntimeException("Authenticator not specified"); - } - - /** - * Process an access control sub-section and return the access control list - * - * @param aclsElem ConfigElement - */ - private final AccessControlList processAccessControlList(ConfigElement aclsElem) - { - - // Check if there is an access control manager configured - - if (getAccessControlManager() == null) - throw new AlfrescoRuntimeException("No access control manager configured"); - - // Create the access control list - - AccessControlList acls = new AccessControlList(); - - // Check if there is a default access level for the ACL group - - String attrib = aclsElem.getAttribute("default"); - - if (attrib != null && attrib.length() > 0) - { - - // Get the access level and validate - - try - { - - // Parse the access level name - - int access = AccessControlParser.parseAccessTypeString(attrib); - - // Set the default access level for the access control list - - acls.setDefaultAccessLevel(access); - } - catch (InvalidACLTypeException ex) - { - throw new AlfrescoRuntimeException("Default access level error", ex); - } - catch (ACLParseException ex) - { - throw new AlfrescoRuntimeException("Default access level error", ex); - } - } - - // Parse each access control element - - List aclElemList = aclsElem.getChildren(); - - if (aclElemList != null && aclElemList.size() > 0) - { - - // Create the access controls - - for (int i = 0; i < aclsElem.getChildCount(); i++) - { - - // Get the current ACL element - - ConfigElement curAclElem = aclElemList.get(i); - - try - { - // Create the access control and add to the list - - acls.addControl(getAccessControlManager().createAccessControl(curAclElem.getName(), curAclElem)); - } - catch (InvalidACLTypeException ex) - { - throw new AlfrescoRuntimeException("Invalid access control type - " + curAclElem.getName()); - } - catch (ACLParseException ex) - { - throw new AlfrescoRuntimeException("Access control parse error (" + curAclElem.getName() + ")", ex); - } - } - } - - // Check if there are no access control rules but the default access level is set to 'None', - // this is not allowed as the share would not be accessible or visible. - - if (acls.getDefaultAccessLevel() == AccessControl.NoAccess && acls.numberOfControls() == 0) - throw new AlfrescoRuntimeException("Empty access control list and default access 'None' not allowed"); - - // Return the access control list - - return acls; - } - - /** - * Process a desktop actions sub-section and return the desktop action table - * - * @param deskActionElem ConfigElement - * @param fileSys DiskSharedDevice - */ - private final DesktopActionTable processDesktopActions(ConfigElement deskActionElem, DiskSharedDevice fileSys) - { - // Get the desktop action configuration elements - - DesktopActionTable desktopActions = null; - List actionElems = deskActionElem.getChildren(); - - if ( actionElems != null) - { - // Check for the global configuration section - - ConfigElement globalConfig = deskActionElem.getChild("global"); - - // Allocate the actions table - - desktopActions = new DesktopActionTable(); - - // Process the desktop actions list - - for ( ConfigElement actionElem : actionElems) - { - if ( actionElem.getName().equals("action")) - { - // Get the desktop action class name or bean id - - ConfigElement className = actionElem.getChild("class"); - if ( className != null) - { - // Load the desktop action class, create a new instance - - Object actionObj = null; - - try - { - // Create a new desktop action instance - - actionObj = Class.forName(className.getValue()).newInstance(); - - // Make sure the object is a desktop action - - if ( actionObj instanceof DesktopAction) - { - // Initialize the desktop action - - DesktopAction deskAction = (DesktopAction) actionObj; - deskAction.initializeAction(globalConfig, actionElem, fileSys); - - // Add the action to the list of desktop actions - - desktopActions.addAction(deskAction); - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Added desktop action " + deskAction.getName()); - } - else - throw new AlfrescoRuntimeException("Desktop action does not extend DesktopAction class, " + className.getValue()); - } - catch ( ClassNotFoundException ex) - { - throw new AlfrescoRuntimeException("Desktop action class not found, " + className.getValue()); - } - catch (IllegalAccessException ex) - { - throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex); - } - catch ( InstantiationException ex) - { - throw new AlfrescoRuntimeException("Failed to create desktop action instance, " + className.getValue(), ex); - } - catch (DesktopActionException ex) - { - throw new AlfrescoRuntimeException("Failed to initialize desktop action", ex); - } - } - } - else if ( actionElem.getName().equals("global") == false) - throw new AlfrescoRuntimeException("Invalid configuration element in desktopActions section, " + actionElem.getName()); - } - } - - // Return the desktop actions list - - return desktopActions; - } - - /** - * Parse the platforms attribute returning the set of platform ids - * - * @param platformStr String - * @return EnumSet - */ - private final EnumSet parsePlatformString(String platformStr) - { - // Split the platform string and build up a set of platform types - - EnumSet platformTypes = EnumSet.noneOf(PlatformType.class); - if (platformStr == null || platformStr.length() == 0) - return platformTypes; - - StringTokenizer token = new StringTokenizer(platformStr.toUpperCase(Locale.ENGLISH), ","); - String typ = null; - - try - { - while (token.hasMoreTokens()) - { - - // Get the current platform type string and validate - - typ = token.nextToken().trim(); - PlatformType platform = PlatformType.valueOf(typ); - - if (platform != PlatformType.Unknown) - platformTypes.add(platform); - else - throw new AlfrescoRuntimeException("Invalid platform type, " + typ); - } - } - catch (IllegalArgumentException ex) - { - throw new AlfrescoRuntimeException("Invalid platform type, " + typ); - } - - // Return the platform types - - return platformTypes; - } - - /** - * Add a shared device to the server configuration. - * - * @param shr SharedDevice - * @return boolean - */ - public final boolean addShare(SharedDevice shr) - { - return m_shareList.addShare(shr); - } - - /** - * Add a server to the list of active servers - * - * @param srv NetworkServer - */ - public synchronized final void addServer(NetworkServer srv) - { - m_serverList.addServer(srv); - } - - /** - * Find an active server using the protocol name - * - * @param proto String - * @return NetworkServer - */ - public final NetworkServer findServer(String proto) - { - return m_serverList.findServer(proto); - } - - /** - * Remove an active server - * - * @param proto String - * @return NetworkServer - */ - public final NetworkServer removeServer(String proto) - { - return m_serverList.removeServer(proto); - } - - /** - * Return the number of active servers - * - * @return int - */ - public final int numberOfServers() - { - return m_serverList.numberOfServers(); - } - - /** - * Return the server at the specified index - * - * @param idx int - * @return NetworkServer - */ - public final NetworkServer getServer(int idx) - { - return m_serverList.getServer(idx); - } - - /** - * Check if there is an access control manager configured - * - * @return boolean - */ - public final boolean hasAccessControlManager() - { - return m_aclManager != null ? true : false; - } - - /** - * Get the access control manager that is used to control per share access - * - * @return AccessControlManager - */ - public final AccessControlManager getAccessControlManager() - { - return m_aclManager; - } - - /** - * Return the associated Acegi authentication manager - * - * @return AuthenticationManager - */ - public final AuthenticationManager getAuthenticationManager() - { - return authenticationManager; - } - - /** - * Check if the global access control list is configured - * - * @return boolean - */ - public final boolean hasGlobalAccessControls() - { - return m_globalACLs != null ? true : false; - } - - /** - * Return the global access control list - * - * @return AccessControlList - */ - public final AccessControlList getGlobalAccessControls() - { - return m_globalACLs; - } - - /** - * Get the authenticator object that is used to provide user and share connection - * authentication for CIFS. - * - * @return CifsAuthenticator - */ - public final CifsAuthenticator getAuthenticator() - { - return m_authenticator; - } - - /** - * Get the alfreso authentication service. - * - * @return - */ - public final AuthenticationService getAuthenticationService() - { - return authenticationService; - } - - /** - * Return the authentication component, for access to internal functions - * - * @return AuthenticationComponent - */ - public final AuthenticationComponent getAuthenticationComponent() - { - return m_authenticationComponent; - } - - /** - * Return the node service - * - * @return NodeService - */ - public final NodeService getNodeService() - { - return m_nodeService; - } - - /** - * Return the tenant service - * - * @return TenantService - */ - public final TenantService getTenantService() - { - return m_tenantService; - } - - /** - * Return the namespace service - * - * @return NamespaceService - */ - public final NamespaceService getNamespaceService() - { - return m_namespaceService; - } - - /** - * Return the node service - * - * @return NodeService - */ - public final SearchService getSearchService() - { - return m_searchService; - } - - /** - * 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 local address that the SMB server should bind to. - * - * @return java.net.InetAddress - */ - public final InetAddress getSMBBindAddress() - { - return m_smbBindAddress; - } - - /** - * Return the local address that the NetBIOS name server should bind to. - * - * @return java.net.InetAddress - */ - public final InetAddress getNetBIOSBindAddress() - { - return m_nbBindAddress; - } - - /** - * Return the NetBIOS name server port - * - * @return int - */ - public final int getNetBIOSNamePort() - { - return m_nbNamePort; - } - - /** - * Return the NetBIOS session port - * - * @return int - */ - public final int getNetBIOSSessionPort() - { - return m_nbSessPort; - } - - /** - * Return the NetBIOS datagram port - * - * @return int - */ - public final int getNetBIOSDatagramPort() - { - return m_nbDatagramPort; - } - - /** - * Return the network broadcast mask to be used for broadcast datagrams. - * - * @return java.lang.String - */ - public final String getBroadcastMask() - { - return m_broadcast; - } - - /** - * Return the server comment. - * - * @return java.lang.String - */ - public final String getComment() - { - return m_comment != null ? m_comment : ""; - } - - /** - * Return the disk interface to be used to create shares - * - * @return DiskInterface - */ - public final DiskInterface getDiskInterface() - { - return diskInterface; - } - - /** - * Return the disk interface to be used to create AVM filesystem shares - * - * @return DiskInterface - */ - public final DiskInterface getAvmDiskInterface() - { - return avmDiskInterface; - } - - /** - * Return the domain name. - * - * @return java.lang.String - */ - public final String getDomainName() - { - return m_domain; - } - - /** - * Return the server name. - * - * @return java.lang.String - */ - public final String getServerName() - { - return m_name; - } - - /** - * Return the server type flags. - * - * @return int - */ - public final int getServerType() - { - return m_srvType; - } - - /** - * Return the server debug flags. - * - * @return int - */ - public final int getSessionDebugFlags() - { - return m_sessDebug; - } - - /** - * Return the shared device list. - * - * @return SharedDeviceList - */ - public final SharedDeviceList getShares() - { - return m_shareList; - } - - /** - * Return the share mapper - * - * @return ShareMapper - */ - public final ShareMapper getShareMapper() - { - return m_shareMapper; - } - - /** - * Return the Win32 NetBIOS server name, if null the default server name will be used - * - * @return String - */ - public final String getWin32ServerName() - { - return m_win32NBName; - } - - /** - * Determine if the server should be announced via Win32 NetBIOS, so that it appears under - * Network Neighborhood. - * - * @return boolean - */ - public final boolean hasWin32EnableAnnouncer() - { - return m_win32NBAnnounce; - } - - /** - * Return the Win32 NetBIOS host announcement interval, in minutes - * - * @return int - */ - public final int getWin32HostAnnounceInterval() - { - return m_win32NBAnnounceInterval; - } - - /** - * Return the Win3 NetBIOS LANA number to use, or -1 for the first available - * - * @return int - */ - public final int getWin32LANA() - { - return m_win32NBLANA; - } - - /** - * Determine if the Win32 Netbios() API or Winsock Netbios calls should be used - * - * @return boolean - */ - public final boolean useWinsockNetBIOS() - { - return m_win32NBUseWinsock; - } - - /** - * Return the native SMB port - * - * @return int - */ - public final int getTcpipSMBPort() - { - return m_tcpSMBPort; - } - - /** - * Return the timezone name - * - * @return String - */ - public final String getTimeZone() - { - return m_timeZone; - } - - /** - * Return the timezone offset from UTC in seconds - * - * @return int - */ - public final int getTimeZoneOffset() - { - return m_tzOffset; - } - - /** - * Determine if the primary WINS server address has been set - * - * @return boolean - */ - public final boolean hasPrimaryWINSServer() - { - return m_winsPrimary != null ? true : false; - } - - /** - * Return the primary WINS server address - * - * @return InetAddress - */ - public final InetAddress getPrimaryWINSServer() - { - return m_winsPrimary; - } - - /** - * Determine if the secondary WINS server address has been set - * - * @return boolean - */ - public final boolean hasSecondaryWINSServer() - { - return m_winsSecondary != null ? true : false; - } - - /** - * Return the secondary WINS server address - * - * @return InetAddress - */ - public final InetAddress getSecondaryWINSServer() - { - return m_winsSecondary; - } - - /** - * Determine if the SMB server should bind to a particular local address - * - * @return boolean - */ - public final boolean hasSMBBindAddress() - { - return m_smbBindAddress != null ? true : false; - } - - /** - * Determine if the NetBIOS name server should bind to a particular local address - * - * @return boolean - */ - public final boolean hasNetBIOSBindAddress() - { - return m_nbBindAddress != null ? true : false; - } - - /** - * Determine if NetBIOS name server debugging is enabled - * - * @return boolean - */ - public final boolean hasNetBIOSDebug() - { - return m_nbDebug; - } - - /** - * Determine if host announcement debugging is enabled - * - * @return boolean - */ - public final boolean hasHostAnnounceDebug() - { - return m_announceDebug; - } - - /** - * Determine if the server should be announced so that it appears under Network Neighborhood. - * - * @return boolean - */ - public final boolean hasEnableAnnouncer() - { - return m_announce; - } - - /** - * Return the host announcement interval, in minutes - * - * @return int - */ - public final int getHostAnnounceInterval() - { - return m_announceInterval; - } - - /** - * Return the JCE provider class name - * - * @return String - */ - public final String getJCEProvider() - { - return m_jceProviderClass; - } - - /** - * Get the local server name and optionally trim the domain name - * - * @param trimDomain boolean - * @return String - */ - public final String getLocalServerName(boolean trimDomain) - { - // Check if the name has already been set - - if (m_localName != null) - return m_localName; - - // Find the local server name - - String srvName = null; - - if (getPlatformType() == PlatformType.WINDOWS) - { - // Get the local name via JNI - - srvName = Win32NetBIOS.GetLocalNetBIOSName(); - } - else - { - // Get the DNS name of the local system - - try - { - srvName = InetAddress.getLocalHost().getHostName(); - } - catch (UnknownHostException ex) - { - } - } - - // Strip the domain name - - if (trimDomain && srvName != null) - { - int pos = srvName.indexOf("."); - if (pos != -1) - srvName = srvName.substring(0, pos); - } - - // Save the local server name - - m_localName = srvName; - - // Return the local server name - - return srvName; - } - - /** - * Get the local domain/workgroup name - * - * @return String - */ - public final String getLocalDomainName() - { - // Check if the local domain has been set - - if (m_localDomain != null) - return m_localDomain; - - // Find the local domain name - - String domainName = null; - - if (getPlatformType() == PlatformType.WINDOWS) - { - // Get the local domain/workgroup name via JNI - - domainName = Win32NetBIOS.GetLocalDomainName(); - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("Local domain name is " + domainName + " (via JNI)"); - } - else - { - NetBIOSName nbName = null; - - try - { - // Try and find the browse master on the local network - - nbName = NetBIOSSession.FindName(NetBIOSName.BrowseMasterName, NetBIOSName.BrowseMasterGroup, 5000); - - // Log the browse master details - - if (logger.isDebugEnabled()) - logger.debug("Found browse master at " + nbName.getIPAddressString(0)); - - // Get the NetBIOS name list from the browse master - - NetBIOSNameList nbNameList = NetBIOSSession.FindNamesForAddress(nbName.getIPAddressString(0)); - if (nbNameList != null) - { - nbName = nbNameList.findName(NetBIOSName.MasterBrowser, false); - // Set the domain/workgroup name - if (nbName != null) - domainName = nbName.getName(); - } - } - catch (IOException ex) - { - } - } - - // Save the local domain name - - m_localDomain = domainName; - - // Return the local domain/workgroup name - - return domainName; - } - - /** - * Check if there are domain mappings - * - * @return boolean - */ - public final boolean hasDomainMappings() - { - return m_domainMappings != null ? true : false; - } - - /** - * Return the domain mappings - * - * @return List - */ - public final List getDomainMappings() - { - return m_domainMappings; - } - - /** - * Return the primary filesystem shared device, or null if not available - * - * @return DiskSharedDevice - */ - public final DiskSharedDevice getPrimaryFilesystem() - { - // Check if there are any global shares defined - - SharedDeviceList shares = getShares(); - DiskSharedDevice diskShare = null; - - if ( shares != null && shares.numberOfShares() > 0) - { - // Find the first available filesystem device - - Enumeration shareEnum = shares.enumerateShares(); - - while ( diskShare == null && shareEnum.hasMoreElements()) - { - SharedDevice curShare = shareEnum.nextElement(); - if ( curShare.getType() == ShareType.DISK) - diskShare = (DiskSharedDevice) curShare; - } - } - - // Return the first filesystem device, or null - - return diskShare; - } - - /** - * Determine if Macintosh extension SMBs are enabled - * - * @return boolean - */ - public final boolean hasMacintoshExtensions() - { - return m_macExtensions; - } - - /** - * Determine if NetBIOS SMB is enabled - * - * @return boolean - */ - public final boolean hasNetBIOSSMB() - { - return m_netBIOSEnable; - } - - /** - * Determine if TCP/IP SMB is enabled - * - * @return boolean - */ - public final boolean hasTcpipSMB() - { - return m_tcpSMBEnable; - } - - /** - * Determine if Win32 NetBIOS is enabled - * - * @return boolean - */ - public final boolean hasWin32NetBIOS() - { - return m_win32NBEnable; - } - - /** - * Check if the SMB server is enabled - * - * @return boolean - */ - public final boolean isSMBServerEnabled() - { - return m_smbEnable; - } - - /** - * Set the SMB server enabled state - * - * @param ena boolean - */ - public final void setSMBServerEnabled(boolean ena) - { - m_smbEnable = ena; - } - - /** - * Set the FTP server enabled state - * - * @param ena boolean - */ - public final void setFTPServerEnabled(boolean ena) - { - m_ftpEnable = ena; - } - - /** - * Set the NFS server enabled state - * - * @param ena boolean - */ - public final void setNFSServerEnabled(boolean ena) - { - m_nfsEnable = ena; - } - - /** - * Set the authenticator to be used to authenticate users and share connections for CIFS. - * - * @param auth CifsAuthenticator - * @param params ConfigElement - * @param allowGuest boolean - */ - public final void setAuthenticator(CifsAuthenticator auth, ConfigElement params, boolean allowGuest) - { - - // Set the server authenticator mode and guest access - - auth.setAllowGuest(allowGuest); - - // Initialize the authenticator using the parameter values - - try - { - auth.initialize(this, params); - } - catch (InvalidConfigurationException ex) - { - throw new AlfrescoRuntimeException("Failed to initialize authenticator", ex); - } - - // Set the server authenticator and initialization parameters - - m_authenticator = auth; - } - - /** - * Set the local address that the SMB server should bind to. - * - * @param addr InetAddress - */ - public final void setSMBBindAddress(InetAddress addr) - { - m_smbBindAddress = addr; - } - - /** - * Set the local address that the NetBIOS name server should bind to. - * - * @param addr InetAddress - */ - public final void setNetBIOSBindAddress(InetAddress addr) - { - m_nbBindAddress = addr; - } - - /** - * Set the broadcast mask to be used for broadcast datagrams. - * - * @param mask String - */ - public final void setBroadcastMask(String mask) - { - m_broadcast = mask; - - // Copy settings to the NetBIOS session class - - NetBIOSSession.setSubnetMask(mask); - } - - /** - * Set the server comment. - * - * @param comment String - */ - public final void setComment(String comment) - { - m_comment = comment; - } - - /** - * Set the domain that the server belongs to. - * - * @param domain String - */ - public final void setDomainName(String domain) - { - m_domain = domain; - } - - /** - * Enable/disable the host announcer. - * - * @param b boolean - */ - public final void setHostAnnouncer(boolean b) - { - m_announce = b; - } - - /** - * Set the host announcement interval, in minutes - * - * @param ival int - */ - public final void setHostAnnounceInterval(int ival) - { - m_announceInterval = ival; - } - - /** - * Set the JCE provider - * - * @param providerClass String - */ - public final void setJCEProvider(String providerClass) - { - - // Validate the JCE provider class - - try - { - - // Load the JCE provider class and validate - - Object jceObj = Class.forName(providerClass).newInstance(); - if (jceObj instanceof java.security.Provider) - { - - // Inform listeners, validate the configuration change - - Provider jceProvider = (Provider) jceObj; - - // Save the JCE provider class name - - m_jceProviderClass = providerClass; - - // Add the JCE provider - - Security.addProvider(jceProvider); - } - else - { - throw new AlfrescoRuntimeException("JCE provider class is not a valid Provider class"); - } - } - catch (ClassNotFoundException ex) - { - throw new AlfrescoRuntimeException("JCE provider class " + providerClass + " not found"); - } - catch (Exception ex) - { - throw new AlfrescoRuntimeException("JCE provider class error", ex); - } - } - - /** - * Enable/disable NetBIOS name server debug output - * - * @param ena boolean - */ - public final void setNetBIOSDebug(boolean ena) - { - m_nbDebug = ena; - } - - /** - * Enable/disable host announcement debug output - * - * @param ena boolean - */ - public final void setHostAnnounceDebug(boolean ena) - { - m_announceDebug = ena; - } - - /** - * Set the server name. - * - * @param name String - */ - public final void setServerName(String name) - { - m_name = name; - } - - /** - * Set the debug flags to be used by the server. - * - * @param flags int - */ - public final void setSessionDebugFlags(int flags) - { - m_sessDebug = flags; - } - - /** - * Set the global access control list - * - * @param acls AccessControlList - */ - public final void setGlobalAccessControls(AccessControlList acls) - { - m_globalACLs = acls; - } - - /** - * Enable/disable the NetBIOS SMB support - * - * @param ena boolean - */ - public final void setNetBIOSSMB(boolean ena) - { - m_netBIOSEnable = ena; - } - - /** - * Set the NetBIOS name server port - * - * @param port int - */ - public final void setNetBIOSNamePort(int port) - { - m_nbNamePort = port; - } - - /** - * Set the NetBIOS session port - * - * @param port int - */ - public final void setNetBIOSSessionPort(int port) - { - m_nbSessPort = port; - } - - /** - * Set the NetBIOS datagram port - * - * @param port int - */ - public final void setNetBIOSDatagramPort(int port) - { - m_nbDatagramPort = port; - } - - /** - * Enable/disable the TCP/IP SMB support - * - * @param ena boolean - */ - public final void setTcpipSMB(boolean ena) - { - m_tcpSMBEnable = ena; - } - - /** - * Set the TCP/IP SMB port - * - * @param port int - */ - public final void setTcpipSMBPort( int port) - { - m_tcpSMBPort = port; - } - - /** - * Enable/disable the Win32 NetBIOS SMB support - * - * @param ena boolean - */ - public final void setWin32NetBIOS(boolean ena) - { - m_win32NBEnable = ena; - } - - /** - * Set the Win32 NetBIOS file server name - * - * @param name String - */ - public final void setWin32NetBIOSName(String name) - { - m_win32NBName = name; - } - - /** - * Enable/disable the Win32 NetBIOS host announcer. - * - * @param b boolean - */ - public final void setWin32HostAnnouncer(boolean b) - { - m_win32NBAnnounce = b; - } - - /** - * Set the Win32 LANA to be used by the Win32 NetBIOS interface - * - * @param ival int - */ - public final void setWin32LANA(int ival) - { - m_win32NBLANA = ival; - } - - /** - * Set the Win32 NetBIOS host announcement interval, in minutes - * - * @param ival int - */ - public final void setWin32HostAnnounceInterval(int ival) - { - m_win32NBAnnounceInterval = ival; - } - - /** - * Set the Win32 NetBIOS interface to use either Winsock NetBIOS or the Netbios() API calls - * - * @param useWinsock boolean - */ - public final void setWin32WinsockNetBIOS(boolean useWinsock) - { - m_win32NBUseWinsock = useWinsock; - } - - /** - * Set the server timezone name - * - * @param name String - * @exception InvalidConfigurationException If the timezone is invalid - */ - public final void setTimeZone(String name) throws InvalidConfigurationException - { - - // Validate the timezone - - TimeZone tz = TimeZone.getTimeZone(name); - if (tz == null) - throw new InvalidConfigurationException("Invalid timezone, " + name); - - // Set the timezone name and offset from UTC in minutes - // - // Invert the result of TimeZone.getRawOffset() as SMB/CIFS requires - // positive minutes west of UTC - - m_timeZone = name; - m_tzOffset = -(tz.getRawOffset() / 60000); - } - - /** - * Set the timezone offset from UTC in seconds (+/-) - * - * @param offset int - */ - public final void setTimeZoneOffset(int offset) - { - m_tzOffset = offset; - } - - /** - * Set the primary WINS server address - * - * @param addr InetAddress - */ - public final void setPrimaryWINSServer(InetAddress addr) - { - m_winsPrimary = addr; - } - - /** - * Set the secondary WINS server address - * - * @param addr InetAddress - */ - public final void setSecondaryWINSServer(InetAddress addr) - { - m_winsSecondary = addr; - } - - /** - * Check if the FTP server is enabled - * - * @return boolean - */ - public final boolean isFTPServerEnabled() - { - return m_ftpEnable; - } - - /** - * Return the FTP server bind address, may be null to indicate bind to all available addresses - * - * @return InetAddress - */ - public final InetAddress getFTPBindAddress() - { - return m_ftpBindAddress; - } - - /** - * Return the FTP server port to use for incoming connections - * - * @return int - */ - public final int getFTPPort() - { - return m_ftpPort; - } - - /** - * Determine if anonymous FTP access is allowed - * - * @return boolean - */ - public final boolean allowAnonymousFTP() - { - return m_ftpAllowAnonymous; - } - - /** - * Return the anonymous FTP account name - * - * @return String - */ - public final String getAnonymousFTPAccount() - { - return m_ftpAnonymousAccount; - } - - /** - * Return the FTP debug flags - * - * @return int - */ - public final int getFTPDebug() - { - return m_ftpDebug; - } - - /** - * Check if an FTP root path has been configured - * - * @return boolean - */ - public final boolean hasFTPRootPath() - { - return m_ftpRootPath != null ? true : false; - } - - /** - * Return the FTP root path - * - * @return String - */ - public final String getFTPRootPath() - { - return m_ftpRootPath; - } - - /** - * Set the FTP server bind address, may be null to indicate bind to all available addresses - * - * @param addr InetAddress - */ - public final void setFTPBindAddress(InetAddress addr) - { - m_ftpBindAddress = addr; - } - - /** - * Return the FTP character set - * - * @return String - */ - public final String getFTPCharacterSet() - { - return m_ftpCharSet; - } - - /** - * Set the FTP server port to use for incoming connections, -1 indicates disable the FTP server - * - * @param port int - */ - public final void setFTPPort(int port) - { - m_ftpPort = port; - } - - /** - * Set the FTP root path - * - * @param path String - */ - public final void setFTPRootPath(String path) - { - m_ftpRootPath = path; - } - - /** - * Enable/disable anonymous FTP access - * - * @param ena boolean - */ - public final void setAllowAnonymousFTP(boolean ena) - { - m_ftpAllowAnonymous = ena; - } - - /** - * Set the anonymous FTP account name - * - * @param acc String - */ - public final void setAnonymousFTPAccount(String acc) - { - m_ftpAnonymousAccount = acc; - } - - /** - * Set the FTP debug flags - * - * @param dbg int - */ - public final void setFTPDebug(int dbg) - { - m_ftpDebug = dbg; - } - - /** - * Set the FTP character set - * - * @param charSet String - */ - public final void setFTPCharacterSet( String charSet) - { - m_ftpCharSet = charSet; - } - - /** - * Check if the NFS server is enabled - * - * @return boolean - */ - public final boolean isNFSServerEnabled() - { - return m_nfsEnable; - } - - /** - * Determine if port mapper debug is enabled - * - * @return boolean - */ - public final boolean hasPortMapperDebug() - { - return m_portMapDebug; - } - - /** - * Determine if mount server debug is enabled - * - * @return boolean - */ - public final boolean hasMountServerDebug() - { - return m_mountServerDebug; - } - - /** - * Check if the NFS port mapper is enabled - * - * @return boolean - */ - public final boolean hasNFSPortMapper() - { - return m_nfsPortMapper; - } - - /** - * Return the port for port mapper to use, or zero for the default port - * - * @return int - */ - public final int getPortMapperPort() - { - return m_portMapperPort; - } - - /** - * Return the port the mount server should use, or zero for the default port - * - * @return int - */ - public final int getMountServerPort() - { - return m_mountServerPort; - } - - /** - * Return the port the NFS server should use, or zero for the default port - * - * @return int - */ - public final int getNFSServerPort() - { - return m_nfsServerPort; - } - - /** - * Return the NFS debug flags - * - * @return int - */ - public final int getNFSDebug() - { - return m_nfsDebug; - } - - /** - * Return the NFS thread pool size - * - * @return int - */ - public final int getNFSThreadPoolSize() - { - return m_nfsThreadPoolSize; - } - - /** - * Return the NFS server packet pool size, or -1 for the default size - * - * @return int - */ - public final int getNFSPacketPoolSize() - { - return m_nfsPacketPoolSize; - } - - /** - * Get the authenticator object that is used to provide RPC authentication (for the portmapper, mount server and - * NFS server) - * - * @return RpcAuthenticator - */ - public final RpcAuthenticator getRpcAuthenticator() - { - return m_rpcAuthenticator; - } - - /** - * Close the server configuration, used to close various components that are shared between protocol - * handlers. - */ - public final void closeConfiguration() - { - // Close the authenticator - - if ( getAuthenticator() != null) - { - getAuthenticator().closeAuthenticator(); - m_authenticator = null; - } - - // Close the shared filesystems - - if ( getShares() != null && getShares().numberOfShares() > 0) - { - // Close the shared filesystems - - Enumeration shareEnum = getShares().enumerateShares(); - - while ( shareEnum.hasMoreElements()) - { - SharedDevice share = shareEnum.nextElement(); - DeviceContext devCtx = share.getContext(); - - if ( devCtx != null) - devCtx.CloseContext(); - } - } - } - - /** - * Load a CIFS authenticator using dyanmic loading - * - * @param className String - * @return CifsAuthenticator - */ - private final CifsAuthenticator loadAuthenticatorClass(String className) - { - CifsAuthenticator srvAuth = null; - - try - { - // Load the authenticator class - - Object authObj = Class.forName(className).newInstance(); - - // Verify that the class is an authenticator - - if ( authObj instanceof CifsAuthenticator) - srvAuth = (CifsAuthenticator) authObj; - } - catch (Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Failed to load authenticator class " + className); - } - - // Return the authenticator class, or null if not available or invalid - - return srvAuth; - } - - @Override - protected void onBootstrap(ApplicationEvent event) - { - init(); - } - - @Override - protected void onShutdown(ApplicationEvent event) - { - // NO-OP - } - -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/DeviceContext.java b/source/java/org/alfresco/filesys/server/core/DeviceContext.java deleted file mode 100644 index e1a26c31a5..0000000000 --- a/source/java/org/alfresco/filesys/server/core/DeviceContext.java +++ /dev/null @@ -1,153 +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.server.core; - -/** - *

- * The device context is passed to the methods of a device interface. Each shared device has a - * device interface and a device context associated with it. The device context allows a single - * device interface to be used for multiple shared devices. - */ -public class DeviceContext -{ - - // Device name that the interface is associated with - - private String m_devName; - - // Filesystem name - - private String m_filesysName; - - // Flag to indicate if the device is available. Unavailable devices will not be listed by the - // various protocol servers. - - private boolean m_available = true; - - /** - * Default constructor - */ - public DeviceContext() - { - super(); - } - - /** - * Class constructor - * - * @param filesysName String - * @param devName String - */ - public DeviceContext(String filesysName, String devName) - { - m_filesysName = filesysName; - m_devName = devName; - } - - /** - * Return the device name. - * - * @return String - */ - public final String getDeviceName() - { - return m_devName; - } - - /** - * Return the filesystem name - * - * @return String - */ - public final String getFilesystemName() - { - return m_filesysName; - } - - /** - * Determine if the filesystem is available - * - * @return boolean - */ - public final boolean isAvailable() - { - return m_available; - } - - /** - * Set the filesystem as available, or not - * - * @param avail boolean - */ - public final void setAvailable(boolean avail) - { - m_available = avail; - } - - /** - * Set the device name. - * - * @param name String - */ - public final void setDeviceName(String name) - { - m_devName = name; - } - - /** - * Set the filesystem name - * - * @param filesysName String - */ - public final void setFilesystemName( String filesysName) - { - m_filesysName = filesysName; - } - - /** - * Close the device context, free any resources allocated by the context - */ - public void CloseContext() - { - } - - /** - * Return the context as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getFilesystemName()); - str.append(","); - str.append(getDeviceName()); - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/DeviceContextException.java b/source/java/org/alfresco/filesys/server/core/DeviceContextException.java deleted file mode 100644 index 781b798fd6..0000000000 --- a/source/java/org/alfresco/filesys/server/core/DeviceContextException.java +++ /dev/null @@ -1,54 +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.server.core; - -/** - * Device Context Exception Class - *

- * Thrown when a device context parameter string is invalid. - */ -public class DeviceContextException extends Exception -{ - private static final long serialVersionUID = 3761124938182244658L; - - /** - * Class constructor - */ - public DeviceContextException() - { - super(); - } - - /** - * Class constructor - * - * @param s java.lang.String - */ - public DeviceContextException(String s) - { - super(s); - } - -} diff --git a/source/java/org/alfresco/filesys/server/core/DeviceInterface.java b/source/java/org/alfresco/filesys/server/core/DeviceInterface.java deleted file mode 100644 index 3718c11020..0000000000 --- a/source/java/org/alfresco/filesys/server/core/DeviceInterface.java +++ /dev/null @@ -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.server.core; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.TreeConnection; - -/** - * The device interface is the base of the shared device interfaces that are used by shared devices - * on the SMB server. - */ -public interface DeviceInterface -{ - - /** - * Parse and validate the parameter string and create a device context object for this instance - * of the shared device. The same DeviceInterface implementation may be used for multiple - * shares. - * - * @param devIface DeviceInterface - * @param name String - * @param args ConfigElement - * @return DeviceContext - * @exception DeviceContextException - */ - public DeviceContext createContext(DeviceInterface devIface, String name, ConfigElement args) - throws DeviceContextException; - - /** - * Connection opened to this disk device - * - * @param sess Server session - * @param tree Tree connection - */ - public void treeOpened(SrvSession sess, TreeConnection tree); - - /** - * Connection closed to this device - * - * @param sess Server session - * @param tree Tree connection - */ - public void treeClosed(SrvSession sess, TreeConnection tree); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/InvalidDeviceInterfaceException.java b/source/java/org/alfresco/filesys/server/core/InvalidDeviceInterfaceException.java deleted file mode 100644 index 40d857eb60..0000000000 --- a/source/java/org/alfresco/filesys/server/core/InvalidDeviceInterfaceException.java +++ /dev/null @@ -1,54 +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.server.core; - -/** - *

- * This exception may be thrown by a SharedDevice when the device interface has not been specified, - * the device interface does not match the shared device type, or the device interface driver class - * cannot be loaded. - */ -public class InvalidDeviceInterfaceException extends Exception -{ - private static final long serialVersionUID = 3834029177581222198L; - - /** - * InvalidDeviceInterfaceException constructor. - */ - public InvalidDeviceInterfaceException() - { - super(); - } - - /** - * InvalidDeviceInterfaceException constructor. - * - * @param s java.lang.String - */ - public InvalidDeviceInterfaceException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/ShareMapper.java b/source/java/org/alfresco/filesys/server/core/ShareMapper.java deleted file mode 100644 index 10278219a7..0000000000 --- a/source/java/org/alfresco/filesys/server/core/ShareMapper.java +++ /dev/null @@ -1,86 +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.server.core; - -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; - -/** - * Share Mapper Interface - *

- * The share mapper interface is used to allocate a share of the specified name and type. It is - * called by the SMB server to allocate disk and print type shares. - */ -public interface ShareMapper -{ - - /** - * Initialize the share mapper - * - * @param config ServerConfiguration - * @param params ConfigElement - * @exception InvalidConfigurationException - */ - public void initializeMapper(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException; - - /** - * Return the share list for the specified host. The host name can be used to implement virtual - * hosts. - * - * @param host - * @param sess SrvSession - * @param allShares boolean - * @return SharedDeviceList - */ - public SharedDeviceList getShareList(String host, SrvSession sess, boolean allShares); - - /** - * Find the share of the specified name/type - * - * @param tohost String - * @param name String - * @param typ int - * @param sess SrvSession - * @param create boolean - * @return SharedDevice - * @exception Exception - */ - public SharedDevice findShare(String tohost, String name, int typ, SrvSession sess, boolean create) - throws Exception; - - /** - * Delete any temporary shares created for the specified session - * - * @param sess SrvSession - */ - public void deleteShares(SrvSession sess); - - /** - * Close the share mapper, release any resources. Called when the server is shutting down. - */ - public void closeMapper(); -} diff --git a/source/java/org/alfresco/filesys/server/core/ShareType.java b/source/java/org/alfresco/filesys/server/core/ShareType.java deleted file mode 100644 index 0322cb4f7b..0000000000 --- a/source/java/org/alfresco/filesys/server/core/ShareType.java +++ /dev/null @@ -1,143 +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.server.core; - -/** - *

- * Available shared resource types. - */ -public class ShareType -{ - // Disk share resource type. - - public static final int DISK = 0; - - // Printer share resource type. - - public static final int PRINTER = 1; - - // Named pipe/IPC share resource type. - - public static final int NAMEDPIPE = 2; - - // Remote administration named pipe, IPC$ - - public static final int ADMINPIPE = 3; - - // Unknown share type - - public static final int UNKNOWN = -1; - - /** - * Return the share type as a share information type. - * - * @return int - * @param typ int - */ - public final static int asShareInfoType(int typ) - { - - // Convert the share type value to a valid share information structure share type - // value. - - int shrTyp = 0; - - switch (typ) - { - case DISK: - shrTyp = 0; - break; - case PRINTER: - shrTyp = 1; - break; - case NAMEDPIPE: - case ADMINPIPE: - shrTyp = 3; - break; - } - return shrTyp; - } - - /** - * Return the SMB service name as a shared device type. - * - * @return int - * @param srvName java.lang.String - */ - public final static int ServiceAsType(String srvName) - { - - // Check the service name - - if (srvName.compareTo("A:") == 0) - return DISK; - else if (srvName.compareTo("LPT1:") == 0) - return PRINTER; - else if (srvName.compareTo("IPC") == 0) - return NAMEDPIPE; - - // Unknown service name string - - return UNKNOWN; - } - - /** - * Return the share type as a service string. - * - * @return java.lang.String - * @param typ int - */ - public final static String TypeAsService(int typ) - { - - if (typ == DISK) - return "A:"; - else if (typ == PRINTER) - return "LPT1:"; - else if (typ == NAMEDPIPE || typ == ADMINPIPE) - return "IPC"; - return ""; - } - - /** - * Return the share type as a string. - * - * @return java.lang.String - * @param typ int - */ - public final static String TypeAsString(int typ) - { - - if (typ == DISK) - return "DISK"; - else if (typ == PRINTER) - return "PRINT"; - else if (typ == NAMEDPIPE) - return "PIPE"; - else if (typ == ADMINPIPE) - return "IPC$"; - return ""; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/SharedDevice.java b/source/java/org/alfresco/filesys/server/core/SharedDevice.java deleted file mode 100644 index 34b269faff..0000000000 --- a/source/java/org/alfresco/filesys/server/core/SharedDevice.java +++ /dev/null @@ -1,504 +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.server.core; - -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlList; - -/** - *

- * The shared device class is the base class for all shared device implementations. - */ -public class SharedDevice implements Comparable -{ - // Share attribute types - - public static final int Admin = 0x0001; - public static final int Hidden = 0x0002; - public static final int ReadOnly = 0x0004; - public static final int Temporary = 0x0008; - - // Shared device name - - private String m_name; - - // Shared device type - - private int m_type; - - // Comment - - private String m_comment; - - // Device interface and context object - - private DeviceInterface m_interface; - private DeviceContext m_drvCtx; - - // Share attributes - - private int m_attrib; - - // Current and maximum connections to this shared device - - private int m_maxUses = -1; // unlimited - private int m_curUses; - - // Access control list - - private AccessControlList m_acls; - - /** - * SharedDevice constructor. - * - * @param name Shared device name. - * @param typ Share device type, as specified by class ShareType. - * @param ctx Context object that will be passed to the interface. - */ - protected SharedDevice(String name, int typ, DeviceContext ctx) - { - - // Set the shared name and device type - - setName(name); - setType(typ); - setContext(ctx); - } - - /** - * Return the shared device attribtues. - * - * @return int - */ - public final int getAttributes() - { - return m_attrib; - } - - /** - * Determine if the shared device has any access controls configured - * - * @return boolean - */ - public final boolean hasAccessControls() - { - if (m_acls == null) - return false; - return true; - } - - /** - * Return the access control list - * - * @return AccessControlList - */ - public final AccessControlList getAccessControls() - { - return m_acls; - } - - /** - * Check if the shared device has a comment - * - * @return boolean - */ - public final boolean hasComment() - { - return m_comment != null ? true : false; - } - - /** - * Return the shared device comment. - * - * @return java.lang.String - */ - public final String getComment() - { - return m_comment; - } - - /** - * Return the device interface specific context object. - * - * @return Device context. - */ - public final DeviceContext getContext() - { - return m_drvCtx; - } - - /** - * Return the device interface for this shared device. - * - * @return DeviceInterface - */ - public DeviceInterface getInterface() throws InvalidDeviceInterfaceException - { - return m_interface; - } - - /** - * Return the shared device name. - * - * @return java.lang.String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the shared device type, as specified by the ShareType class. - * - * @return int - */ - public int getType() - { - return m_type; - } - - /** - * Return the current connection count for the share - * - * @return int - */ - public final int getCurrentConnectionCount() - { - return m_curUses; - } - - /** - * Return the maximum connection count for the share - * - * @return int - */ - public final int getMaximumConnectionCount() - { - return m_maxUses; - } - - /** - * Generates a hash code for the receiver. This method is supported primarily for hash tables, - * such as those provided in java.util. - * - * @return an integer hash code for the receiver - * @see java.util.Hashtable - */ - public int hashCode() - { - - // Use the share name to generate the hash code. - - return getName().hashCode(); - } - - /** - * Determine if this is an admin share. - * - * @return boolean - */ - public final boolean isAdmin() - { - return (m_attrib & Admin) == 0 ? false : true; - } - - /** - * Determine if this is a hidden share. - * - * @return boolean - */ - public final boolean isHidden() - { - return (m_attrib & Hidden) == 0 ? false : true; - } - - /** - * Determine if the share is read-only. - * - * @return boolean - */ - public final boolean isReadOnly() - { - return (m_attrib & ReadOnly) == 0 ? false : true; - } - - /** - * Determine if the share is a temporary share - * - * @return boolean - */ - public final boolean isTemporary() - { - return (m_attrib & Temporary) == 0 ? false : true; - } - - /** - * Set the shared device comment string. - * - * @param comm java.lang.String - */ - public final void setComment(String comm) - { - m_comment = comm; - } - - /** - * Set the shared device attributes. - * - * @param attr int - */ - public final void setAttributes(int attr) - { - m_attrib = attr; - } - - /** - * Set the context that is passed to the device interface. - * - * @param ctx DeviceContext - */ - protected void setContext(DeviceContext ctx) - { - m_drvCtx = ctx; - } - - /** - * Set the device interface for this shared device. - * - * @param iface DeviceInterface - */ - protected final void setInterface(DeviceInterface iface) - { - m_interface = iface; - } - - /** - * Set the shared device name. - * - * @param name java.lang.String Shared device name. - */ - protected final void setName(String name) - { - m_name = name; - } - - /** - * Set the shared device type. - * - * @param typ int Shared device type, as specified by class ShareType. - */ - protected final void setType(int typ) - { - m_type = typ; - } - - /** - * Set the maximum connection coutn for this shared device - * - * @param maxConn int - */ - public final void setMaximumConnectionCount(int maxConn) - { - m_maxUses = maxConn; - } - - /** - * Set the access control list using the specified list - * - * @param acls AccessControlList - */ - public final void setAccessControlList(AccessControlList acls) - { - m_acls = acls; - } - - /** - * Add an access control to the shared device - * - * @param acl AccessControl - */ - public final void addAccessControl(AccessControl acl) - { - - // Check if the access control list has been allocated - - if (m_acls == null) - m_acls = new AccessControlList(); - - // Add the access control - - m_acls.addControl(acl); - } - - /** - * Remove an access control - * - * @param idx int - * @return AccessControl - */ - public final AccessControl removeAccessControl(int idx) - { - - // validate the index - - if (m_acls == null || idx < 0 || idx >= m_acls.numberOfControls()) - return null; - - // Remove the access control - - return m_acls.removeControl(idx); - } - - /** - * Remove all access controls from this shared device - */ - public final void removeAllAccessControls() - { - if (m_acls != null) - { - m_acls.removeAllControls(); - m_acls = null; - } - } - - /** - * Parse and validate the parameters string and create a device context for the shared device. - * - * @param args String[] - * @return DeviceContext - */ - public DeviceContext createContext(String[] args) - { - return new DeviceContext("", args[0]); - } - - /** - * Increment the connection count for the share - */ - public synchronized void incrementConnectionCount() - { - m_curUses++; - } - - /** - * Decrement the connection count for the share - */ - public synchronized void decrementConnectionCount() - { - m_curUses--; - } - - /** - * Compare this shared device to another shared device using the device name - * - * @param obj Object - */ - public int compareTo(Object obj) - { - if (obj instanceof SharedDevice) - { - SharedDevice sd = (SharedDevice) obj; - return getName().compareTo(sd.getName()); - } - return -1; - } - - /** - * Compares two objects for equality. Returns a boolean that indicates whether this object is - * equivalent to the specified object. This method is used when an object is stored in a - * hashtable. - * - * @param obj the Object to compare with - * @return true if these Objects are equal; false otherwise. - * @see java.util.Hashtable - */ - public boolean equals(Object obj) - { - - // Check if the object is a SharedDevice - - if (obj instanceof SharedDevice) - { - - // Check if the share names are equal - - SharedDevice shr = (SharedDevice) obj; - if (getName().compareTo(shr.getName()) == 0) - return true; - } - - // Object type, or share name is not equal - - return false; - } - - /** - * Returns a String that represents the value of this object. - * - * @return a string representation of the receiver - */ - public String toString() - { - - // Build a string that represents this shared device - - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(getName()); - str.append(","); - str.append(ShareType.TypeAsString(getType())); - str.append(","); - - if (hasAccessControls()) - { - str.append("ACLs="); - str.append(m_acls.numberOfControls()); - } - - if (isAdmin()) - str.append(",Admin"); - - if (isHidden()) - str.append(",Hidden"); - - if (isReadOnly()) - str.append(",ReadOnly"); - - if (isTemporary()) - str.append(",Temp"); - - if (getContext() != null && getContext().isAvailable() == false) - str.append(",Offline"); - - if (m_drvCtx != null) - { - str.append(","); - str.append(m_drvCtx.toString()); - } - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/core/SharedDeviceList.java b/source/java/org/alfresco/filesys/server/core/SharedDeviceList.java deleted file mode 100644 index a5c0761f6f..0000000000 --- a/source/java/org/alfresco/filesys/server/core/SharedDeviceList.java +++ /dev/null @@ -1,261 +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.server.core; - -import java.util.Enumeration; -import java.util.Hashtable; - -/** - *

- * List of shared devices. - */ -public class SharedDeviceList -{ - - // Shared device list - - private Hashtable m_shares; - - /** - * SharedDeviceList constructor. - */ - public SharedDeviceList() - { - - // Allocate the shared device list - - m_shares = new Hashtable(); - } - - /** - * Copy constructor - * - * @param shrList SharedDeviceList - */ - public SharedDeviceList(SharedDeviceList shrList) - { - - // Allocate the shared device list - - m_shares = new Hashtable(); - - // Copy the shares from the original list, shallow copy - - addShares(shrList); - } - - /** - * Add a shared device to the list. - * - * @param shr Shared device to be added to the list. - * @return True if the share was added successfully, else false. - */ - public final boolean addShare(SharedDevice shr) - { - - // Check if a share with the specified name already exists - - if (m_shares.containsKey(shr.getName())) - return false; - - // Add the shared device - - m_shares.put(shr.getName(), shr); - return true; - } - - /** - * Add shares from the specified list to this list, using a shallow copy - * - * @param shrList SharedDeviceList - */ - public final void addShares(SharedDeviceList shrList) - { - - // Copy the shares to this list - - Enumeration enm = shrList.enumerateShares(); - - while (enm.hasMoreElements()) - addShare(enm.nextElement()); - } - - /** - * Delete the specified shared device from the list. - * - * @param name String Name of the shared resource to remove from the list. - * @return SharedDevice that has been removed from the list, else null. - */ - public final SharedDevice deleteShare(String name) - { - - // Remove the shared device from the list - - return (SharedDevice) m_shares.remove(name); - } - - /** - * Return an enumeration to allow the shared devices to be listed. - * - * @return Enumeration - */ - public final Enumeration enumerateShares() - { - return m_shares.elements(); - } - - /** - * Find the shared device with the specified name. - * - * @param name Name of the shared device to find. - * @return SharedDevice with the specified name, else null. - */ - public final SharedDevice findShare(String name) - { - return m_shares.get(name); - } - - /** - * Find the shared device with the specified name and type - * - * @param name Name of shared device to find - * @param typ Type of shared device (see ShareType) - * @param nocase Case sensitive search if false, else case insensitive search - * @return SharedDevice with the specified name and type, else null - */ - public final SharedDevice findShare(String name, int typ, boolean nocase) - { - - // Enumerate the share list - - Enumeration keys = m_shares.keys(); - - while (keys.hasMoreElements()) - { - - // Get the current share name - - String curName = keys.nextElement(); - - if ((nocase == false && curName.equals(name)) || (nocase == true && curName.equalsIgnoreCase(name))) - { - - // Get the shared device and check if the share is of the required type - - SharedDevice share = (SharedDevice) m_shares.get(curName); - if (share.getType() == typ || typ == ShareType.UNKNOWN) - return share; - } - } - - // Required share not found - - return null; - } - - /** - * Return the number of shared devices in the list. - * - * @return int - */ - public final int numberOfShares() - { - return m_shares.size(); - } - - /** - * Remove shares that have an unavailable status from the list - * - * @return int - */ - public final int removeUnavailableShares() - { - - // Check if any shares are unavailable - - Enumeration shrEnum = enumerateShares(); - int remCnt = 0; - - while (shrEnum.hasMoreElements()) - { - - // Check if the current share is unavailable - - SharedDevice shr = shrEnum.nextElement(); - if (shr.getContext() != null && shr.getContext().isAvailable() == false) - { - deleteShare(shr.getName()); - remCnt++; - } - } - - // Return the count of shares removed - - return remCnt; - } - - /** - * Remove all shared devices from the share list - */ - public final void removeAllShares() - { - m_shares.clear(); - } - - /** - * Return the share list as a string - * - * @return String - */ - public String toString() - { - - // Create a buffer to build the string - - StringBuffer str = new StringBuffer(); - str.append("["); - - // Enumerate the shares - - Enumeration enm = m_shares.keys(); - - while (enm.hasMoreElements()) - { - String name = enm.nextElement(); - str.append(name); - str.append(","); - } - - // Remove the trailing comma - - if (str.length() > 1) - str.setLength(str.length() - 1); - str.append("]"); - - // Return the string - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/AccessDeniedException.java b/source/java/org/alfresco/filesys/server/filesys/AccessDeniedException.java deleted file mode 100644 index 967577f310..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/AccessDeniedException.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * Thrown when an attempt is made to write to a file that is read-only or the user only has read - * access to, or open a file that is actually a directory. - */ -public class AccessDeniedException extends java.io.IOException -{ - private static final long serialVersionUID = 3688785881968293433L; - - /** - * AccessDeniedException constructor - */ - public AccessDeniedException() - { - super(); - } - - /** - * AccessDeniedException constructor. - * - * @param s java.lang.String - */ - public AccessDeniedException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/AccessMode.java b/source/java/org/alfresco/filesys/server/filesys/AccessMode.java deleted file mode 100644 index 3163d59e85..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/AccessMode.java +++ /dev/null @@ -1,100 +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.server.filesys; - -/** - * SMB file access mode class. - *

- * The SMB access mode values are used when opening a file using one of the SMBDiskSession OpenFile - * (), OpenInputStream () or OpenOutputStream () methods. - */ -public final class AccessMode -{ - - // Access mode constants - - public static final int ReadOnly = 0x0000; - public static final int WriteOnly = 0x0001; - public static final int ReadWrite = 0x0002; - public static final int Execute = 0x0003; - public static final int Compatability = 0x0000; - public static final int Exclusive = 0x0010; - public static final int DenyWrite = 0x0020; - public static final int DenyRead = 0x0030; - public static final int DenyNone = 0x0040; - public static final int NoCaching = 0x1000; - public static final int WriteThrough = 0x4000; - protected static final int FCBOpen = 0x00FF; - - // NT access mode constants - - public static final int NTRead = 0x00000001; - public static final int NTWrite = 0x00000002; - public static final int NTAppend = 0x00000004; - public static final int NTReadEA = 0x00000008; - public static final int NTWriteEA = 0x00000010; - public static final int NTExecute = 0x00000020; - public static final int NTDeleteChild = 0x00000040; - public static final int NTReadAttrib = 0x00000080; - public static final int NTWriteAttrib = 0x00000100; - - public static final int NTDelete = 0x00010000; - public static final int NTReadControl = 0x00020000; - public static final int NTWriteDAC = 0x00040000; - public static final int NTWriteOwner = 0x00080000; - public static final int NTSynchronize = 0x00100000; - public static final int NTSystemSecurity = 0x01000000; - - public static final int NTGenericRead = 0x80000000; - public static final int NTGenericWrite = 0x40000000; - public static final int NTGenericExecute = 0x20000000; - public static final int NTGenericAll = 0x10000000; - - public static final int NTMaximumAllowed = 0x02000000; - - public static final int NTReadWrite = NTRead + NTWrite; - - /** - * Return the file access mode from the specified flags value. - * - * @param val File flags value. - * @return File access mode. - */ - public static final int getAccessMode(int val) - { - return val & 0x03; - } - - /** - * Return the file sharing mode from the specified flags value. - * - * @param val File flags value. - * @return File sharing mode. - */ - public static final int getSharingMode(int val) - { - return val & 0x70; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/DefaultShareMapper.java b/source/java/org/alfresco/filesys/server/filesys/DefaultShareMapper.java deleted file mode 100644 index a5d40c8f4a..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DefaultShareMapper.java +++ /dev/null @@ -1,219 +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.server.filesys; - -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.ShareMapper; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.core.SharedDeviceList; - -/** - * Default Share Mapper Class - * - *

Maps disk and print share lookup requests to the list of shares defined in the server - * configuration. - * - * @author GKSpencer - */ -public class DefaultShareMapper implements ShareMapper -{ - // Server configuration - - private ServerConfiguration m_config; - - // Debug enable flag - - private boolean m_debug; - - /** - * Default constructor - */ - public DefaultShareMapper() - { - } - - /** - * 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; - - // Check if debug is enabled - - if (params != null && params.getChild("debug") != null) - m_debug = true; - } - - /** - * 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 for the special HOME disk share - - SharedDevice share = null; - - // Search the sessions dynamic share list first - - if ( sess.hasDynamicShares()) { - - // Check if the required share exists in the sessions dynamic share list - - share = sess.getDynamicShareList().findShare(name, typ, true); - } - - // If we did not find a share then search the global share list - - if ( share == null) - { - // 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); - - if (share == null) - { - - // Try a case insensitive search for the required share - - share = m_config.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 enm = shares.enumerateShares(); - - while ( enm.hasMoreElements()) { - - // Get the current share from the list - - SharedDevice shr = (SharedDevice) enm.nextElement(); - - // Close the shared device - - shr.getContext().CloseContext(); - } - - // Clear the dynamic share list - - shares.removeAllShares(); - } - - /** - * 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 if the session is valid, if so then check if the session has any dynamic shares - - // Make a copy of the global share list and add the per session dynamic shares - - SharedDeviceList shrList = new SharedDeviceList(m_config.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() - { - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DeviceAttribute.java b/source/java/org/alfresco/filesys/server/filesys/DeviceAttribute.java deleted file mode 100644 index 0e4da5f1be..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DeviceAttribute.java +++ /dev/null @@ -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.server.filesys; - -/** - * Device Attribute Constants Class - *

- * Specifies the constants that can be used to set the DiskDeviceContext device attributes. - */ -public final class DeviceAttribute -{ - // Device attributes - - public static final int Removable = 0x0001; - public static final int ReadOnly = 0x0002; - public static final int FloppyDisk = 0x0004; - public static final int WriteOnce = 0x0008; - public static final int Remote = 0x0010; - public static final int Mounted = 0x0020; - public static final int Virtual = 0x0040; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DirectoryNotEmptyException.java b/source/java/org/alfresco/filesys/server/filesys/DirectoryNotEmptyException.java deleted file mode 100644 index 3a9bba2919..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DirectoryNotEmptyException.java +++ /dev/null @@ -1,54 +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.server.filesys; - -import java.io.IOException; - -/** - *

- * Thrown when an attempt is made to delete a directory that contains files or directories. - */ -public class DirectoryNotEmptyException extends IOException -{ - private static final long serialVersionUID = 3906083464527491128L; - - /** - * Default constructor - */ - public DirectoryNotEmptyException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public DirectoryNotEmptyException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskDeviceContext.java b/source/java/org/alfresco/filesys/server/filesys/DiskDeviceContext.java deleted file mode 100644 index 8424e0b057..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskDeviceContext.java +++ /dev/null @@ -1,286 +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.server.filesys; - -import org.alfresco.filesys.server.core.DeviceContext; -import org.alfresco.filesys.server.core.DeviceContextException; -import org.alfresco.filesys.smb.server.notify.NotifyChangeHandler; -import org.alfresco.filesys.smb.server.notify.NotifyRequest; - -/** - * Disk Device Context Class - */ -public class DiskDeviceContext extends DeviceContext -{ - - // Change notification handler - - private NotifyChangeHandler m_changeHandler; - - // Volume information - - private VolumeInfo m_volumeInfo; - - // Disk sizing information - - private SrvDiskInfo m_diskInfo; - - // Filesystem attributes, required to enable features such as compression and encryption - - private int m_filesysAttribs; - - // Disk device attributes, can be used to make the device appear as a removeable, read-only, - // or write-once device for example. - - private int m_deviceAttribs; - - /** - * Class constructor - */ - public DiskDeviceContext() - { - super(); - } - - /** - * Class constructor - * - * @param filesysName String - * @param devName String - */ - public DiskDeviceContext(String filesysName, String devName) - { - super(filesysName, devName); - } - - /** - * Determine if the volume information is valid - * - * @return boolean - */ - public final boolean hasVolumeInformation() - { - return m_volumeInfo != null ? true : false; - } - - /** - * Return the volume information - * - * @return VolumeInfo - */ - public final VolumeInfo getVolumeInformation() - { - return m_volumeInfo; - } - - /** - * Determine if the disk sizing information is valid - * - * @return boolean - */ - public final boolean hasDiskInformation() - { - return m_diskInfo != null ? true : false; - } - - /** - * Return the disk sizing information - * - * @return SMBSrvDiskInfo - */ - public final SrvDiskInfo getDiskInformation() - { - return m_diskInfo; - } - - /** - * Return the filesystem attributes - * - * @return int - */ - public final int getFilesystemAttributes() - { - return m_filesysAttribs; - } - - /** - * Return the filesystem type, either FileSystem.TypeFAT or FileSystem.TypeNTFS. - * - * Defaults to FileSystem.FAT but will be overridden if the filesystem driver implements the - * NTFSStreamsInterface. - * - * @return String - */ - public String getFilesystemType() - { - return FileSystem.TypeFAT; - } - - /** - * Return the device attributes - * - * @return int - */ - public final int getDeviceAttributes() - { - return m_deviceAttribs; - } - - /** - * Determine if the filesystem is case sensitive or not - * - * @return boolean - */ - public final boolean isCaseless() - { - return (m_filesysAttribs & FileSystem.CasePreservedNames) == 0 ? true : false; - } - - /** - * Enable/disable the change notification handler for this device - * - * @param ena boolean - */ - public final void enableChangeHandler(boolean ena) - { - if (ena == true) - m_changeHandler = new NotifyChangeHandler(this); - else - { - - // Shutdown the change handler, if valid - - if (m_changeHandler != null) - m_changeHandler.shutdownRequest(); - m_changeHandler = null; - } - } - - /** - * Close the disk device context. Release the file state cache resources. - */ - public void CloseContext() - { - // Close the notify handler - - if ( hasChangeHandler()) - getChangeHandler().shutdownRequest(); - - // Call the base class - - super.CloseContext(); - } - - /** - * Determine if the disk context has a change notification handler - * - * @return boolean - */ - public final boolean hasChangeHandler() - { - return m_changeHandler != null ? true : false; - } - - /** - * Return the change notification handler - * - * @return NotifyChangeHandler - */ - public final NotifyChangeHandler getChangeHandler() - { - return m_changeHandler; - } - - /** - * Add a request to the change notification list - * - * @param req NotifyRequest - */ - public final void addNotifyRequest(NotifyRequest req) - { - m_changeHandler.addNotifyRequest(req); - } - - /** - * Remove a request from the notify change request list - * - * @param req NotifyRequest - */ - public final void removeNotifyRequest(NotifyRequest req) - { - m_changeHandler.removeNotifyRequest(req); - } - - /** - * Set the volume information - * - * @param vol VolumeInfo - */ - public final void setVolumeInformation(VolumeInfo vol) - { - m_volumeInfo = vol; - } - - /** - * Set the disk information - * - * @param disk SMBSrvDiskInfo - */ - public final void setDiskInformation(SrvDiskInfo disk) - { - m_diskInfo = disk; - } - - /** - * Set the filesystem attributes - * - * @param attrib int - */ - public final void setFilesystemAttributes(int attrib) - { - m_filesysAttribs = attrib; - } - - /** - * Set the device attributes - * - * @param attrib int - */ - public final void setDeviceAttributes(int attrib) - { - m_deviceAttribs = attrib; - } - - /** - * Context has been initialized and attached to a shared device, do any startup processing in - * this method. - * - * @param share DiskSharedDevice - * @exception DeviceContextException - */ - public void startFilesystem(DiskSharedDevice share) throws DeviceContextException - { - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskFullException.java b/source/java/org/alfresco/filesys/server/filesys/DiskFullException.java deleted file mode 100644 index d3a4dc36cc..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskFullException.java +++ /dev/null @@ -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.server.filesys; - -import java.io.IOException; - -/** - *

- * Thrown when a disk write or file extend will exceed the available disk quota for the shared - * filesystem. - */ -public class DiskFullException extends IOException -{ - private static final long serialVersionUID = 3256446901959472181L; - - /** - * Default constructor - */ - public DiskFullException() - { - super(); - } - - /** - * Class constructor - * - * @param msg String - */ - public DiskFullException(String msg) - { - super(msg); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskInfo.java b/source/java/org/alfresco/filesys/server/filesys/DiskInfo.java deleted file mode 100644 index 0630025d47..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskInfo.java +++ /dev/null @@ -1,245 +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.server.filesys; - -import org.alfresco.filesys.smb.PCShare; - -/** - * SMB disk information class. - *

- * The DiskInfo class contains the details of a remote disk share. - */ -public class DiskInfo -{ - - // Node/share details - - protected String m_nodename; - protected String m_share; - - // Total number of allocation units, available allocation units - - protected long m_totalunits; - protected long m_freeunits; - - // Blocks per allocation unit and block size in bytes - - protected long m_blockperunit; - protected long m_blocksize; - - /** - * Construct a blank disk information object. - */ - public DiskInfo() - { - } - - /** - * Class constructor - * - * @param shr PCShare - * @param totunits int - * @param blkunit int - * @param blksiz int - * @param freeunit int - */ - public DiskInfo(PCShare shr, int totunits, int blkunit, int blksiz, int freeunit) - { - if (shr != null) - { - m_nodename = shr.getNodeName(); - m_share = shr.getShareName(); - } - - m_totalunits = (long) totunits; - m_freeunits = (long) freeunit; - - m_blockperunit = (long) blkunit; - m_blocksize = (long) blksiz; - } - - /** - * Class constructor - * - * @param shr PCShare - * @param totunits long - * @param blkunit int - * @param blksiz int - * @param freeunit long - */ - public DiskInfo(PCShare shr, long totunits, int blkunit, int blksiz, long freeunit) - { - if (shr != null) - { - m_nodename = shr.getNodeName(); - m_share = shr.getShareName(); - } - - m_totalunits = totunits; - m_freeunits = freeunit; - - m_blockperunit = (long) blkunit; - m_blocksize = (long) blksiz; - } - - /** - * Get the block size, in bytes. - * - * @return Block size in bytes. - */ - public final int getBlockSize() - { - return (int) m_blocksize; - } - - /** - * Get the number of blocks per allocation unit. - * - * @return Number of blocks per allocation unit. - */ - public final int getBlocksPerAllocationUnit() - { - return (int) m_blockperunit; - } - - /** - * Get the disk free space in kilobytes. - * - * @return Remote disk free space in kilobytes. - */ - public final long getDiskFreeSizeKb() - { - return (((m_freeunits * m_blockperunit) * m_blocksize) / 1024L); - } - - /** - * Get the disk free space in megabytes. - * - * @return Remote disk free space in megabytes. - */ - public final long getDiskFreeSizeMb() - { - return getDiskFreeSizeKb() / 1024L; - } - - /** - * Get the disk size in kilobytes. - * - * @return Remote disk size in kilobytes. - */ - public final long getDiskSizeKb() - { - return (((m_totalunits * m_blockperunit) * m_blocksize) / 1024L); - } - - /** - * Get the disk size in megabytes. - * - * @return Remote disk size in megabytes. - */ - public final long getDiskSizeMb() - { - return (getDiskSizeKb() / 1024L); - } - - /** - * Get the number of free units on this share. - * - * @return Number of free units. - */ - public final long getFreeUnits() - { - return m_freeunits; - } - - /** - * Return the unit size in bytes - * - * @return long - */ - public final long getUnitSize() - { - return m_blockperunit * m_blocksize; - } - - /** - * Get the node name. - * - * @return Node name of the remote server. - */ - public final String getNodeName() - { - return m_nodename; - } - - /** - * Get the share name. - * - * @return Remote share name. - */ - public final String getShareName() - { - return m_share; - } - - /** - * Get the total number of allocation units. - * - * @return The total number of allocation units. - */ - public final long getTotalUnits() - { - return m_totalunits; - } - - /** - * Return the disk information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getTotalUnits()); - str.append("/"); - str.append(getFreeUnits()); - str.append(","); - str.append(getBlockSize()); - str.append("/"); - str.append(getBlocksPerAllocationUnit()); - - str.append(","); - str.append(getDiskSizeMb()); - str.append("Mb/"); - str.append(getDiskFreeSizeMb()); - str.append("Mb"); - - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskInterface.java b/source/java/org/alfresco/filesys/server/filesys/DiskInterface.java deleted file mode 100644 index ea90a7fb68..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskInterface.java +++ /dev/null @@ -1,236 +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.server.filesys; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.DeviceContext; -import org.alfresco.filesys.server.core.DeviceInterface; - -/** - * The disk interface is implemented by classes that provide an interface for a disk type shared - * device. - */ -public interface DiskInterface extends DeviceInterface -{ - - /** - * Close the file. - * - * @param sess Server session - * @param tree Tree connection. - * @param param Network file context. - * @exception java.io.IOException If an error occurs. - */ - public void closeFile(SrvSession sess, TreeConnection tree, NetworkFile param) throws java.io.IOException; - - /** - * Create a new directory on this file system. - * - * @param sess Server session - * @param tree Tree connection. - * @param params Directory create parameters - * @exception java.io.IOException If an error occurs. - */ - public void createDirectory(SrvSession sess, TreeConnection tree, FileOpenParams params) throws java.io.IOException; - - /** - * Create a new file on the file system. - * - * @param sess Server session - * @param tree Tree connection - * @param params File create parameters - * @return NetworkFile - * @exception java.io.IOException If an error occurs. - */ - public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params) - throws java.io.IOException; - - /** - * Delete the directory from the filesystem. - * - * @param sess Server session - * @param tree Tree connection - * @param dir Directory name. - * @exception java.io.IOException The exception description. - */ - public void deleteDirectory(SrvSession sess, TreeConnection tree, String dir) throws java.io.IOException; - - /** - * Delete the specified file. - * - * @param sess Server session - * @param tree Tree connection - * @param file NetworkFile - * @exception java.io.IOException The exception description. - */ - public void deleteFile(SrvSession sess, TreeConnection tree, String name) throws java.io.IOException; - - /** - * Check if the specified file exists, and whether it is a file or directory. - * - * @param sess Server session - * @param tree Tree connection - * @param name java.lang.String - * @return int - * @see FileStatus - */ - int fileExists(SrvSession sess, TreeConnection tree, String name); - - /** - * Flush any buffered output for the specified file. - * - * @param sess Server session - * @param tree Tree connection - * @param file Network file context. - * @exception java.io.IOException The exception description. - */ - public void flushFile(SrvSession sess, TreeConnection tree, NetworkFile file) throws java.io.IOException; - - /** - * Get the file information for the specified file. - * - * @param sess Server session - * @param tree Tree connection - * @param name File name/path that information is required for. - * @return File information if valid, else null - * @exception java.io.IOException The exception description. - */ - public FileInfo getFileInformation(SrvSession sess, TreeConnection tree, String name) throws java.io.IOException; - - /** - * Determine if the disk device is read-only. - * - * @param sess Server session - * @param ctx Device context - * @return boolean - * @exception java.io.IOException If an error occurs. - */ - boolean isReadOnly(SrvSession sess, DeviceContext ctx) throws java.io.IOException; - - /** - * Open a file on the file system. - * - * @param sess Server session - * @param tree Tree connection - * @param params File open parameters - * @return NetworkFile - * @exception java.io.IOException If an error occurs. - */ - public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws java.io.IOException; - - /** - * Read a block of data from the specified file. - * - * @param sess Session details - * @param tree Tree connection - * @param file Network file - * @param buf Buffer to return data to - * @param bufPos Starting position in the return buffer - * @param siz Maximum size of data to return - * @param filePos File offset to read data - * @return Number of bytes read - * @exception java.io.IOException The exception description. - */ - public int readFile(SrvSession sess, TreeConnection tree, NetworkFile file, byte[] buf, int bufPos, int siz, - long filePos) throws java.io.IOException; - - /** - * Rename the specified file. - * - * @param sess Server session - * @param tree Tree connection - * @param oldName java.lang.String - * @param newName java.lang.String - * @exception java.io.IOException The exception description. - */ - public void renameFile(SrvSession sess, TreeConnection tree, String oldName, String newName) - throws java.io.IOException; - - /** - * Seek to the specified file position. - * - * @param sess Server session - * @param tree Tree connection - * @param file Network file. - * @param pos Position to seek to. - * @param typ Seek type. - * @return New file position, relative to the start of file. - */ - long seekFile(SrvSession sess, TreeConnection tree, NetworkFile file, long pos, int typ) throws java.io.IOException; - - /** - * Set the file information for the specified file. - * - * @param sess Server session - * @param tree Tree connection - * @param name java.lang.String - * @param info FileInfo - * @exception java.io.IOException The exception description. - */ - public void setFileInformation(SrvSession sess, TreeConnection tree, String name, FileInfo info) - throws java.io.IOException; - - /** - * Start a new search on the filesystem using the specified searchPath that may contain - * wildcards. - * - * @param sess Server session - * @param tree Tree connection - * @param searchPath File(s) to search for, may include wildcards. - * @param attrib Attributes of the file(s) to search for, see class SMBFileAttribute. - * @return SearchContext - * @exception java.io.FileNotFoundException If the search could not be started. - */ - public SearchContext startSearch(SrvSession sess, TreeConnection tree, String searchPath, int attrib) - throws java.io.FileNotFoundException; - - /** - * Truncate a file to the specified size - * - * @param sess Server session - * @param tree Tree connection - * @param file Network file details - * @param siz New file length - * @exception java.io.IOException The exception description. - */ - public void truncateFile(SrvSession sess, TreeConnection tree, NetworkFile file, long siz) - throws java.io.IOException; - - /** - * Write a block of data to the file. - * - * @param sess Server session - * @param tree Tree connection - * @param file Network file details - * @param buf byte[] Data to be written - * @param bufoff Offset within the buffer that the data starts - * @param siz int Data length - * @param fileoff Position within the file that the data is to be written. - * @return Number of bytes actually written - * @exception java.io.IOException The exception description. - */ - public int writeFile(SrvSession sess, TreeConnection tree, NetworkFile file, byte[] buf, int bufoff, int siz, - long fileoff) throws java.io.IOException; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskSharedDevice.java b/source/java/org/alfresco/filesys/server/filesys/DiskSharedDevice.java deleted file mode 100644 index 577a463d0f..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskSharedDevice.java +++ /dev/null @@ -1,93 +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.server.filesys; - -import org.alfresco.filesys.server.core.DeviceInterface; -import org.alfresco.filesys.server.core.ShareType; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - *

- * A disk shared device has a name, a driver class and a context for the driver. - */ -public class DiskSharedDevice extends SharedDevice -{ - - /** - * Construct a disk share with the specified name and device interface. - * - * @param name Disk share name. - * @param iface Disk device interface. - * @param ctx Context that will be passed to the device interface. - */ - public DiskSharedDevice(String name, DeviceInterface iface, DiskDeviceContext ctx) - { - super(name, ShareType.DISK, ctx); - setInterface(iface); - } - - /** - * Construct a disk share with the specified name and device interface. - * - * @param name java.lang.String - * @param iface DeviceInterface - * @param ctx DeviceContext - * @param attrib int - */ - public DiskSharedDevice(String name, DeviceInterface iface, DiskDeviceContext ctx, int attrib) - { - super(name, ShareType.DISK, ctx); - setInterface(iface); - setAttributes(attrib); - } - - /** - * Return the disk device context - * - * @return DiskDeviceContext - */ - public final DiskDeviceContext getDiskContext() - { - return (DiskDeviceContext) getContext(); - } - - /** - * Return the disk interface - * - * @return DiskInterface - */ - public final DiskInterface getDiskInterface() - { - try - { - if (getInterface() instanceof DiskInterface) - return (DiskInterface) getInterface(); - } - catch (Exception ex) - { - } - return null; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskSizeInterface.java b/source/java/org/alfresco/filesys/server/filesys/DiskSizeInterface.java deleted file mode 100644 index 57d7c19fec..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskSizeInterface.java +++ /dev/null @@ -1,44 +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.server.filesys; - -/** - * Disk Size Interface - *

- * Optional interface that a DiskInterface driver can implement to provide disk sizing information. - * The disk size information may also be specified via the configuration. - */ -public interface DiskSizeInterface -{ - - /** - * Get the disk information for this shared disk device. - * - * @param cts DiskDeviceContext - * @param diskDev SrvDiskInfo - * @exception java.io.IOException The exception description. - */ - public void getDiskInformation(DiskDeviceContext ctx, SrvDiskInfo diskDev) throws java.io.IOException; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/DiskVolumeInterface.java b/source/java/org/alfresco/filesys/server/filesys/DiskVolumeInterface.java deleted file mode 100644 index 71dc9b3216..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/DiskVolumeInterface.java +++ /dev/null @@ -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.server.filesys; - -/** - * Disk Volume Interface - *

- * Optional interface that a DiskInterface driver can implement to provide disk volume information. - * The disk volume information may also be specified via the configuration. - */ -public interface DiskVolumeInterface -{ - - /** - * Return the disk device volume information. - * - * @param ctx DiskDeviceContext - * @return VolumeInfo - */ - public VolumeInfo getVolumeInformation(DiskDeviceContext ctx); -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileAccess.java b/source/java/org/alfresco/filesys/server/filesys/FileAccess.java deleted file mode 100644 index c68f2012a6..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileAccess.java +++ /dev/null @@ -1,65 +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.server.filesys; - -/** - * File Access Class - *

- * Contains a list of the available file permissions that may be applied to a share, directory or - * file. - */ -public final class FileAccess -{ - // Permissions - - public static final int NoAccess = 0; - public static final int ReadOnly = 1; - public static final int Writeable = 2; - - /** - * Return the file permission as a string. - * - * @param perm int - * @return java.lang.String - */ - public final static String asString(int perm) - { - String permStr = ""; - - switch (perm) - { - case NoAccess: - permStr = "NoAccess"; - break; - case ReadOnly: - permStr = "ReadOnly"; - break; - case Writeable: - permStr = "Writeable"; - break; - } - return permStr; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileAction.java b/source/java/org/alfresco/filesys/server/filesys/FileAction.java deleted file mode 100644 index 60a6581810..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileAction.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * The file actions are sent in OpenAndX and NTCreateAndX request/response SMBs. - */ -public final class FileAction -{ - // File open action request codes - - public static final int FailIfExists = 0x0000; - public static final int OpenIfExists = 0x0001; - public static final int TruncateExisting = 0x0002; - public static final int CreateNotExist = 0x0010; - - // File open action response codes - - public static final int FileExisted = 0x0001; - public static final int FileCreated = 0x0002; - public static final int FileTruncated = 0x0003; - - // NT file/device open action codes - - public final static int NTSupersede = 0; // supersede if exists, else create a new file - public final static int NTOpen = 1; // only open if the file exists - public final static int NTCreate = 2; // create if file does not exist, else fail - public final static int NTOpenIf = 3; // open if exists else create - public final static int NTOverwrite = 4; // overwrite if exists, else fail - public final static int NTOverwriteIf = 5; // overwrite if exists, else create - - /** - * Check if the file action value indicates that the file should be created if the file does not - * exist. - * - * @return boolean - * @param action int - */ - public final static boolean createNotExists(int action) - { - if ((action & CreateNotExist) != 0) - return true; - return false; - } - - /** - * Check if the open file if exists action is set. - * - * @return boolean - * @param action int - */ - public final static boolean openIfExists(int action) - { - if ((action & OpenIfExists) != 0) - return true; - return false; - } - - /** - * Check if the existing file should be truncated. - * - * @return boolean - * @param action int - */ - public final static boolean truncateExistingFile(int action) - { - if ((action & TruncateExisting) != 0) - return true; - return false; - } - - /** - * Convert the file exists action flags to a string - * - * @param flags int - * @return String - */ - public final static String asString(int flags) - { - StringBuffer str = new StringBuffer(); - - str.append("[0x"); - str.append(Integer.toHexString(flags)); - str.append(":"); - - if (openIfExists(flags)) - str.append("OpenExists|"); - - if (truncateExistingFile(flags)) - str.append("Truncate|"); - - if (createNotExists(flags)) - str.append("CreateNotExist"); - - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileAttribute.java b/source/java/org/alfresco/filesys/server/filesys/FileAttribute.java deleted file mode 100644 index f478d2e198..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileAttribute.java +++ /dev/null @@ -1,151 +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.server.filesys; - -/** - * SMB file attribute class. - *

- * Defines various bit masks that may be returned in an FileInfo object, that is returned by the - * DiskInterface.getFileInformation () and SearchContext.nextFileInfo() methods. - *

- * The values are also used by the DiskInterface.StartSearch () method to determine the - * file/directory types that are returned. - * - * @see DiskInterface - * @see SearchContext - */ -public final class FileAttribute -{ - - // Standard file attribute constants - - public static final int Normal = 0x00; - public static final int ReadOnly = 0x01; - public static final int Hidden = 0x02; - public static final int System = 0x04; - public static final int Volume = 0x08; - public static final int Directory = 0x10; - public static final int Archive = 0x20; - - // NT file attribute flags - - public static final int NTReadOnly = 0x00000001; - public static final int NTHidden = 0x00000002; - public static final int NTSystem = 0x00000004; - public static final int NTVolumeId = 0x00000008; - public static final int NTDirectory = 0x00000010; - public static final int NTArchive = 0x00000020; - public static final int NTDevice = 0x00000040; - public static final int NTNormal = 0x00000080; - public static final int NTTemporary = 0x00000100; - public static final int NTSparse = 0x00000200; - public static final int NTReparsePoint = 0x00000400; - public static final int NTCompressed = 0x00000800; - public static final int NTOffline = 0x00001000; - public static final int NTIndexed = 0x00002000; - public static final int NTEncrypted = 0x00004000; - public static final int NTOpenNoRecall = 0x00100000; - public static final int NTOpenReparsePoint = 0x00200000; - public static final int NTPosixSemantics = 0x01000000; - public static final int NTBackupSemantics = 0x02000000; - public static final int NTDeleteOnClose = 0x04000000; - public static final int NTSequentialScan = 0x08000000; - public static final int NTRandomAccess = 0x10000000; - public static final int NTNoBuffering = 0x20000000; - public static final int NTOverlapped = 0x40000000; - public static final int NTWriteThrough = 0x80000000; - - /** - * Determine if the specified file attribute mask has the specified file attribute enabled. - * - * @return boolean - * @param attr int - * @param reqattr int - */ - public final static boolean hasAttribute(int attr, int reqattr) - { - - // Check for the specified attribute - - if ((attr & reqattr) != 0) - return true; - return false; - } - - /** - * Check if the read-only attribute is set - * - * @param attr int - * @return boolean - */ - public static final boolean isReadOnly(int attr) - { - return (attr & ReadOnly) != 0 ? true : false; - } - - /** - * Check if the directory attribute is set - * - * @param attr int - * @return boolean - */ - public static final boolean isDirectory(int attr) - { - return (attr & Directory) != 0 ? true : false; - } - - /** - * Check if the hidden attribute is set - * - * @param attr int - * @return boolean - */ - public static final boolean isHidden(int attr) - { - return (attr & Hidden) != 0 ? true : false; - } - - /** - * Check if the system attribute is set - * - * @param attr int - * @return boolean - */ - public static final boolean isSystem(int attr) - { - return (attr & System) != 0 ? true : false; - } - - /** - * Check if the archive attribute is set - * - * @param attr int - * @return boolean - */ - public static final boolean isArchived(int attr) - { - return (attr & Archive) != 0 ? true : false; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileExistsException.java b/source/java/org/alfresco/filesys/server/filesys/FileExistsException.java deleted file mode 100644 index 0eaac06b6f..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileExistsException.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * This exception may be thrown by a disk interface when an attempt to create a new file fails - * because the file already exists. - */ -public class FileExistsException extends java.io.IOException -{ - private static final long serialVersionUID = 3258408439242895670L; - - /** - * FileExistsException constructor. - */ - public FileExistsException() - { - super(); - } - - /** - * FileExistsException constructor. - * - * @param s java.lang.String - */ - public FileExistsException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileIdInterface.java b/source/java/org/alfresco/filesys/server/filesys/FileIdInterface.java deleted file mode 100644 index a33eaacf0f..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileIdInterface.java +++ /dev/null @@ -1,52 +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.server.filesys; - -import java.io.FileNotFoundException; - -import org.alfresco.filesys.server.SrvSession; - -/** - * File Id Interface - *

- * Optional interface that a DiskInterface driver can implement to provide file id to path - * conversion. - */ -public interface FileIdInterface -{ - - /** - * Convert a file id to a share relative path - * - * @param sess SrvSession - * @param tree TreeConnection - * @param dirid int - * @param fileid - * @return String - * @exception FileNotFoundException - */ - public String buildPathForFileId(SrvSession sess, TreeConnection tree, int dirid, int fileid) - throws FileNotFoundException; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileInfo.java b/source/java/org/alfresco/filesys/server/filesys/FileInfo.java deleted file mode 100644 index 9df390d0d3..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileInfo.java +++ /dev/null @@ -1,977 +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.server.filesys; - -import java.io.Serializable; -import java.util.Date; - -import org.alfresco.filesys.smb.SMBDate; - -/** - * File information class. - *

- * The FileInfo class is returned by the DiskInterface.getFileInformation () and - * SearchContext.nextFileInfo() methods. - * - * @see DiskInterface - * @see SearchContext - */ -public class FileInfo implements Serializable -{ - private static final long serialVersionUID = 5710753560656277110L; - - // Constants - // - // Set file information flags - - public static final int SetFileSize = 0x0001; - public static final int SetAllocationSize = 0x0002; - public static final int SetAttributes = 0x0004; - public static final int SetModifyDate = 0x0008; - public static final int SetCreationDate = 0x0010; - public static final int SetAccessDate = 0x0020; - public static final int SetChangeDate = 0x0040; - public static final int SetGid = 0x0080; - public static final int SetUid = 0x0100; - public static final int SetMode = 0x0200; - public static final int SetDeleteOnClose = 0x0400; - - // File name string - - protected String m_name; - - // 8.3 format file name - - protected String m_shortName; - - // Path string - - protected String m_path; - - // File size, in bytes - - protected long m_size; - - // File attributes bits - - protected int m_attr = -1; - - // File modification date/time - - private long m_modifyDate; - - // Creation date/time - - private long m_createDate; - - // Last access date/time (if available) - - private long m_accessDate; - - // Change date/time (for Un*x inode changes) - - private long m_changeDate; - - // Filesystem allocation size - - private long m_allocSize; - - // File identifier and parent directory id - - private int m_fileId = -1; - private int m_dirId = -1; - - // User/group id - - private int m_gid = -1; - private int m_uid = -1; - - // Unix mode - - private int m_mode = -1; - - // Delete file on close - - private boolean m_deleteOnClose; - - // File type - - private int m_fileType; - - // Set file information flags - // - // Used to indicate which values in the file information object are valid and should be used to set - // the file information. - - private int m_setFlags; - - /** - * Default constructor - */ - public FileInfo() - { - } - - /** - * Construct an SMB file information object. - * - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - */ - public FileInfo(String fname, long fsize, int fattr) - { - m_name = fname; - m_size = fsize; - m_attr = fattr; - - setAllocationSize(0); - } - - /** - * Construct an SMB file information object. - * - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - * @param ftime File time, in seconds since 1-Jan-1970 00:00:00 - */ - public FileInfo(String fname, long fsize, int fattr, int ftime) - { - m_name = fname; - m_size = fsize; - m_attr = fattr; - m_modifyDate = new SMBDate(ftime).getTime(); - - setAllocationSize(0); - } - - /** - * Construct an SMB file information object. - * - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - * @param fdate SMB encoded file date. - * @param ftime SMB encoded file time. - */ - public FileInfo(String fname, long fsize, int fattr, int fdate, int ftime) - { - m_name = fname; - m_size = fsize; - m_attr = fattr; - - if (fdate != 0 && ftime != 0) - m_modifyDate = new SMBDate(fdate, ftime).getTime(); - - setAllocationSize(0); - } - - /** - * Construct an SMB file information object. - * - * @param fpath File path string. - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - */ - public FileInfo(String fpath, String fname, long fsize, int fattr) - { - m_path = fpath; - m_name = fname; - m_size = fsize; - m_attr = fattr; - - setAllocationSize(0); - } - - /** - * Construct an SMB file information object. - * - * @param fpath File path string. - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - * @param ftime File time, in seconds since 1-Jan-1970 00:00:00 - */ - public FileInfo(String fpath, String fname, long fsize, int fattr, int ftime) - { - m_path = fpath; - m_name = fname; - m_size = fsize; - m_attr = fattr; - m_modifyDate = new SMBDate(ftime).getTime(); - - setAllocationSize(0); - } - - /** - * Construct an SMB file information object. - * - * @param fpath File path string. - * @param fname File name string. - * @param fsize File size, in bytes. - * @param fattr File attributes. - * @param fdate SMB encoded file date. - * @param ftime SMB encoded file time. - */ - public FileInfo(String fpath, String fname, long fsize, int fattr, int fdate, int ftime) - { - m_path = fpath; - m_name = fname; - m_size = fsize; - m_attr = fattr; - m_modifyDate = new SMBDate(fdate, ftime).getTime(); - - setAllocationSize(0); - } - - /** - * Return the files last access date/time. - * - * @return long - */ - public long getAccessDateTime() - { - return m_accessDate; - } - - /** - * Get the files allocated size. - * - * @return long - */ - public long getAllocationSize() - { - return m_allocSize; - } - - /** - * Get the files allocated size, as a 32bit value - * - * @return int - */ - public int getAllocationSizeInt() - { - return (int) (m_allocSize & 0x0FFFFFFFFL); - } - - /** - * Return the inode change date/time of the file. - * - * @return long - */ - public long getChangeDateTime() - { - return m_changeDate; - } - - /** - * Return the creation date/time of the file. - * - * @return long - */ - public long getCreationDateTime() - { - return m_createDate; - } - - /** - * Return the delete on close flag setting - * - * @return boolean - */ - public final boolean hasDeleteOnClose() - { - return m_deleteOnClose; - } - - /** - * Return the file attributes value. - * - * @return File attributes value. - */ - public int getFileAttributes() - { - return m_attr; - } - - /** - * Get the file name string - * - * @return File name string. - */ - public final String getFileName() - { - return m_name; - } - - /** - * Check if the short (8.3) file name is available - * - * @return boolean - */ - public final boolean hasShortName() - { - return m_shortName != null ? true : false; - } - - /** - * Get the short file name (8.3 format) - * - * @return String - */ - public final String getShortName() - { - return m_shortName; - } - - /** - * Get the files date/time of last write - * - * @return long - */ - public final long getModifyDateTime() - { - return m_modifyDate; - } - - /** - * Get the file path string. - * - * @return File path string, relative to the share. - */ - public final String getPath() - { - return m_path; - } - - /** - * Get the file size, in bytes. - * - * @return File size in bytes. - */ - public final long getSize() - { - return m_size; - } - - /** - * Get the file size in bytes, as a 32bit value - * - * @return File size in bytes, as an int - */ - public final int getSizeInt() - { - return (int) (m_size & 0x0FFFFFFFFL); - } - - /** - * Get the file identifier - * - * @return int - */ - public final int getFileId() - { - return m_fileId; - } - - /** - * Get the file identifier - * - * @return long - */ - public final long getFileIdLong() - { - return ((long) m_fileId) & 0xFFFFFFFFL; - } - - /** - * Get the parent directory identifier - * - * @return int - */ - public final int getDirectoryId() - { - return m_dirId; - } - - /** - * Get the parent directory identifier - * - * @return long - */ - public final long getDirectoryIdLong() - { - return ((long) m_dirId) & 0xFFFFFFFFL; - } - - /** - * Determine if the last access date/time is available. - * - * @return boolean - */ - public boolean hasAccessDateTime() - { - return m_accessDate == 0L ? false : true; - } - - /** - * Determine if the inode change date/time details are available. - * - * @return boolean - */ - public boolean hasChangeDateTime() - { - return m_changeDate == 0L ? false : true; - } - - /** - * Determine if the creation date/time details are available. - * - * @return boolean - */ - public boolean hasCreationDateTime() - { - return m_createDate == 0L ? false : true; - } - - /** - * Determine if the modify date/time details are available. - * - * @return boolean - */ - public boolean hasModifyDateTime() - { - return m_modifyDate == 0L ? false : true; - } - - /** - * Determine if the file attributes field has been set - * - * @return boolean - */ - public final boolean hasFileAttributes() - { - return m_attr != -1 ? true : false; - } - - /** - * Return the specified attribute status - * - * @param attr int - */ - public final boolean hasAttribute(int attr) - { - return (m_attr & attr) != 0 ? true : false; - } - - /** - * Return the directory file attribute status. - * - * @return true if the file is a directory, else false. - */ - public final boolean isDirectory() - { - return (m_attr & FileAttribute.Directory) != 0 ? true : false; - } - - /** - * Return the hidden file attribute status. - * - * @return true if the file is hidden, else false. - */ - public final boolean isHidden() - { - return (m_attr & FileAttribute.Hidden) != 0 ? true : false; - } - - /** - * Return the read-only file attribute status. - * - * @return true if the file is read-only, else false. - */ - public final boolean isReadOnly() - { - return (m_attr & FileAttribute.ReadOnly) != 0 ? true : false; - } - - /** - * Return the system file attribute status. - * - * @return true if the file is a system file, else false. - */ - public final boolean isSystem() - { - return (m_attr & FileAttribute.System) != 0 ? true : false; - } - - /** - * Return the archived attribute status - * - * @return boolean - */ - public final boolean isArchived() - { - return (m_attr & FileAttribute.Archive) != 0 ? true : false; - } - - /** - * Return the file type - * - * @return int - */ - public final int isFileType() - { - return m_fileType; - } - - /** - * Determine if the group id field has been set - * - * @return boolean - */ - public final boolean hasGid() - { - return m_gid != -1 ? true : false; - } - - /** - * Return the owner group id - * - * @return int - */ - public final int getGid() - { - return m_gid; - } - - /** - * Determine if the user id field has been set - * - * @return boolean - */ - public final boolean hasUid() - { - return m_uid != -1 ? true : false; - } - - /** - * Return the owner user id - * - * @return int - */ - public final int getUid() - { - return m_uid; - } - - /** - * Determine if the mode field has been set - * - * @return boolean - */ - public final boolean hasMode() - { - return m_mode != -1 ? true : false; - } - - /** - * Return the Unix mode - * - * @return int - */ - public final int getMode() - { - return m_mode; - } - - /** - * Reset all values to zero/null values. - */ - public final void resetInfo() - { - m_name = ""; - m_path = null; - - m_size = 0L; - m_allocSize = 0L; - - m_attr = 0; - - m_accessDate = 0L; - m_createDate = 0L; - m_modifyDate = 0L; - m_changeDate = 0L; - - m_fileId = -1; - m_dirId = -1; - - m_gid = -1; - m_uid = -1; - m_mode = -1; - } - - /** - * Copy the file information - * - * @param finfo FileInfo - */ - public final void copyFrom(FileInfo finfo) - { - m_name = finfo.getFileName(); - m_path = finfo.getPath(); - - m_size = finfo.getSize(); - m_allocSize = finfo.getAllocationSize(); - - m_attr = finfo.getFileAttributes(); - - m_accessDate = finfo.getAccessDateTime(); - m_createDate = finfo.getCreationDateTime(); - m_modifyDate = finfo.getModifyDateTime(); - m_changeDate = finfo.getChangeDateTime(); - - m_fileId = finfo.getFileId(); - m_dirId = finfo.getDirectoryId(); - - m_gid = finfo.getGid(); - m_uid = finfo.getUid(); - m_mode = finfo.getMode(); - } - - /** - * Set the files last access date/time. - * - * @param timesec long - */ - public void setAccessDateTime(long timesec) - { - - // Create the access date/time - - m_accessDate = timesec; - } - - /** - * Set the files allocation size. - * - * @param siz long - */ - public void setAllocationSize(long siz) - { - m_allocSize = siz; - } - - /** - * Set the inode change date/time for the file. - * - * @param timesec long - */ - public void setChangeDateTime(long timesec) - { - - // Set the inode change date/time - - m_changeDate = timesec; - } - - /** - * Set the creation date/time for the file. - * - * @param timesec long - */ - public void setCreationDateTime(long timesec) - { - - // Set the creation date/time - - m_createDate = timesec; - } - - /** - * Set/clear the delete on close flag - * - * @param del boolean - */ - public final void setDeleteOnClose(boolean del) - { - m_deleteOnClose = del; - } - - /** - * Set the file attributes. - * - * @param attr int - */ - public final void setFileAttributes(int attr) - { - m_attr = attr; - } - - /** - * Set the file name. - * - * @param name java.lang.String - */ - public final void setFileName(String name) - { - m_name = name; - } - - /** - * Set the file size in bytes - * - * @param siz long - */ - public final void setFileSize(long siz) - { - m_size = siz; - } - - /** - * Set the modification date/time for the file. - * - * @param timesec long - */ - public void setModifyDateTime(long timesec) - { - - // Set the date/time - - m_modifyDate = timesec; - } - - /** - * Set the file identifier - * - * @param id int - */ - public final void setFileId(int id) - { - m_fileId = id; - } - - /** - * Set the parent directory id - * - * @param id int - */ - public final void setDirectoryId(int id) - { - m_dirId = id; - } - - /** - * Set the short (8.3 format) file name - * - * @param name String - */ - public final void setShortName(String name) - { - m_shortName = name; - } - - /** - * Set the path - * - * @param path String - */ - public final void setPath(String path) - { - m_path = path; - } - - /** - * Set the file size. - * - * @param siz int - */ - public final void setSize(int siz) - { - m_size = siz; - } - - /** - * Set the file size. - * - * @param siz long - */ - public final void setSize(long siz) - { - m_size = siz; - } - - /** - * Set the owner group id - * - * @param id int - */ - public final void setGid(int id) - { - m_gid = id; - } - - /** - * Set the owner user id - * - * @param id int - */ - public final void setUid(int id) - { - m_uid = id; - } - - /** - * Set the file mode - * - * @param mode int - */ - public final void setMode(int mode) - { - m_mode = mode; - } - - /** - * Set the file type - * - * @param typ int - */ - public final void setFileType(int typ) - { - m_fileType = typ; - } - - /** - * Set the set file information flags to indicated which values are to be set - * - * @param setFlags int - */ - public final void setFileInformationFlags(int setFlags) - { - m_setFlags = setFlags; - } - - /** - * Determine if the specified set file information flags is enabled - * - * @param setFlag int - * @return boolean - */ - public final boolean hasSetFlag(int flag) - { - if ((m_setFlags & flag) != 0) - return true; - return false; - } - - /** - * Return the set file information flags - * - * @return int - */ - public final int getSetFileInformationFlags() - { - return m_setFlags; - } - - /** - * Return the file information as a string. - * - * @return File information string. - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - // Append the path, and terminate with a trailing '\' - - if (m_path != null) - { - str.append(m_path); - if (!m_path.endsWith("\\")) - str.append("\\"); - } - - // Append the file name - - str.append(m_name); - - // Space fill - - while (str.length() < 15) - str.append(" "); - - // Append the attribute states - - if (isReadOnly()) - str.append("R"); - else - str.append("-"); - if (isHidden()) - str.append("H"); - else - str.append("-"); - if (isSystem()) - str.append("S"); - else - str.append("-"); - if (isDirectory()) - str.append("D"); - else - str.append("-"); - - // Append the file size, in bytes - - str.append(" "); - str.append(m_size); - - // Space fill - - while (str.length() < 30) - str.append(" "); - - // Append the file write date/time, if available - - if (m_modifyDate != 0L) - { - str.append(" - "); - str.append(new Date(m_modifyDate)); - } - - // Append the short (8.3) file name, if available - - if (hasShortName()) - { - str.append(" ("); - str.append(getShortName()); - str.append(")"); - } - - // Return the file information string - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileName.java b/source/java/org/alfresco/filesys/server/filesys/FileName.java deleted file mode 100644 index d1a2b06a50..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileName.java +++ /dev/null @@ -1,628 +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.server.filesys; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.StringTokenizer; - -/** - *

- * Provides utility methods for manipulating file names. - */ -public final class FileName -{ - - // DOS file name seperator - - public static final char DOS_SEPERATOR = '\\'; - public static final String DOS_SEPERATOR_STR = "\\"; - - // NTFS Stream seperator - - public static final String NTFSStreamSeperator = ":"; - - /** - * Build a path using the specified components. - * - * @param dev java.lang.String - * @param path java.lang.String - * @param filename java.lang.String - * @param sep char - * @return java.lang.String - */ - public static String buildPath(String dev, String path, String filename, char sep) - { - - // Build the path string - - StringBuffer fullPath = new StringBuffer(); - - // Check for a device name - - if (dev != null) - { - - // Add the device name - - fullPath.append(dev); - - // Check if the device name has a file seperator - - if (dev.length() > 0 && dev.charAt(dev.length() - 1) != sep) - fullPath.append(sep); - } - - // Check for a path - - if (path != null) - { - - // Add the path - - if (fullPath.length() > 0 && path.length() > 0 - && (path.charAt(0) == sep || path.charAt(0) == DOS_SEPERATOR)) - fullPath.append(path.substring(1)); - else - fullPath.append(path); - - // Add a trailing seperator, if required - - if (path.length() > 0 && path.charAt(path.length() - 1) != sep && filename != null) - fullPath.append(sep); - } - - // Check for a file name - - if (filename != null) - { - - // Add the file name - - if (fullPath.length() > 0 && filename.length() > 0 - && (filename.charAt(0) == sep || filename.charAt(0) == DOS_SEPERATOR)) - fullPath.append(filename.substring(1)); - else - fullPath.append(filename); - } - - // Convert the file seperator characters in the path if we are not using the normal - // DOS file seperator character. - - if (sep != DOS_SEPERATOR) - return convertSeperators(fullPath.toString(), sep); - return fullPath.toString(); - } - - /** - * Convert the file seperators in a path to the specified path seperator character. - * - * @param path java.lang.String - * @param sep char - * @return java.lang.String - */ - public static String convertSeperators(String path, char sep) - { - - // Check if the path contains any DOS seperators - - if (path.indexOf(DOS_SEPERATOR) == -1) - return path; - - // Convert DOS path seperators to the specified seperator - - StringBuffer newPath = new StringBuffer(); - int idx = 0; - - while (idx < path.length()) - { - - // Get the current character from the path and check if it is a DOS path - // seperator character. - - char ch = path.charAt(idx++); - if (ch == DOS_SEPERATOR) - newPath.append(sep); - else - newPath.append(ch); - } - - // Return the new path string - - return newPath.toString(); - } - - /** - * Map the input path to a real path, this may require changing the case of various parts of the - * path. The base path is not checked, it is assumed to exist. - * - * @param base java.lang.String - * @param path java.lang.String - * @return java.lang.String - * @exception java.io.FileNotFoundException The path could not be mapped to a real path. - */ - public static final String mapPath(String base, String path) throws java.io.FileNotFoundException - { - - // Split the path string into seperate directory components - - String pathCopy = path; - if (pathCopy.length() > 0 && pathCopy.startsWith(DOS_SEPERATOR_STR)) - pathCopy = pathCopy.substring(1); - - StringTokenizer token = new StringTokenizer(pathCopy, "\\/"); - int tokCnt = token.countTokens(); - - // The mapped path string, if it can be mapped - - String mappedPath = null; - - if (tokCnt > 0) - { - - // Allocate an array to hold the directory names - - String[] dirs = new String[token.countTokens()]; - - // Get the directory names - - int idx = 0; - while (token.hasMoreTokens()) - dirs[idx++] = token.nextToken(); - - // Check if the path ends with a directory or file name, ie. has a trailing '\' or not - - int maxDir = dirs.length; - - if (path.endsWith(DOS_SEPERATOR_STR) == false) - { - - // Ignore the last token as it is a file name - - maxDir--; - } - - // Build up the path string and validate that the path exists at each stage. - - StringBuffer pathStr = new StringBuffer(base); - if (base.endsWith(java.io.File.separator) == false) - pathStr.append(java.io.File.separator); - - int lastPos = pathStr.length(); - idx = 0; - File lastDir = null; - if (base != null && base.length() > 0) - lastDir = new File(base); - File curDir = null; - - while (idx < maxDir) - { - - // Append the current directory to the path - - pathStr.append(dirs[idx]); - pathStr.append(java.io.File.separator); - - // Check if the current path exists - - curDir = new File(pathStr.toString()); - - if (curDir.exists() == false) - { - - // Check if there is a previous directory to search - - if (lastDir == null) - throw new FileNotFoundException(); - - // Search the current path for a matching directory, the case may be different - - String[] fileList = lastDir.list(); - if (fileList == null || fileList.length == 0) - throw new FileNotFoundException(); - - int fidx = 0; - boolean foundPath = false; - - while (fidx < fileList.length && foundPath == false) - { - - // Check if the current file name matches the required directory name - - if (fileList[fidx].equalsIgnoreCase(dirs[idx])) - { - - // Use the current directory name - - pathStr.setLength(lastPos); - pathStr.append(fileList[fidx]); - pathStr.append(java.io.File.separator); - - // Check if the path is valid - - curDir = new File(pathStr.toString()); - if (curDir.exists()) - { - foundPath = true; - break; - } - } - - // Update the file name index - - fidx++; - } - - // Check if we found the required directory - - if (foundPath == false) - throw new FileNotFoundException(); - } - - // Set the last valid directory file - - lastDir = curDir; - - // Update the end of valid path location - - lastPos = pathStr.length(); - - // Update the current directory index - - idx++; - } - - // Check if there is a file name to be added to the mapped path - - if (path.endsWith(DOS_SEPERATOR_STR) == false) - { - - // Map the file name - - String[] fileList = lastDir.list(); - String fileName = dirs[dirs.length - 1]; - - // Check if the file list is valid, if not then the path is not valid - - if (fileList == null) - throw new FileNotFoundException(path); - - // Search for the required file - - idx = 0; - boolean foundFile = false; - - while (idx < fileList.length && foundFile == false) - { - if (fileList[idx].compareTo(fileName) == 0) - foundFile = true; - else - idx++; - } - - // Check if we found the file name, if not then do a case insensitive search - - if (foundFile == false) - { - - // Search again using a case insensitive search - - idx = 0; - - while (idx < fileList.length && foundFile == false) - { - if (fileList[idx].equalsIgnoreCase(fileName)) - { - foundFile = true; - fileName = fileList[idx]; - } - else - idx++; - } - } - - // Append the file name - - pathStr.append(fileName); - } - - // Set the new path string - - mappedPath = pathStr.toString(); - } - - // Return the mapped path string, if successful. - - return mappedPath; - } - - /** - * Remove the file name from the specified path string. - * - * @param path java.lang.String - * @return java.lang.String - */ - public final static String removeFileName(String path) - { - - // Find the last path seperator - - int pos = path.lastIndexOf(DOS_SEPERATOR); - if (pos != -1) - return path.substring(0, pos); - - // Return an empty string, no path seperators - - return ""; - } - - /** - * Split the path into seperate directory path and file name strings. - * - * @param path Full path string. - * @param sep Path seperator character. - * @return java.lang.String[] - */ - public static String[] splitPath(String path) - { - return splitPath(path, DOS_SEPERATOR, null); - } - - /** - * Split the path into seperate directory path and file name strings. - * - * @param path Full path string. - * @param sep Path seperator character. - * @return java.lang.String[] - */ - public static String[] splitPath(String path, char sep) - { - return splitPath(path, sep, null); - } - - /** - * Split the path into seperate directory path and file name strings. - * - * @param path Full path string. - * @param sep Path seperator character. - * @param list String list to return values in, or null to allocate - * @return java.lang.String[] - */ - public static String[] splitPath(String path, char sep, String[] list) - { - if (path == null) - throw new IllegalArgumentException("Path may not be null"); - - // Create an array of strings to hold the path and file name strings - String[] pathStr = list; - if (pathStr == null) - pathStr = new String[] {"", ""}; - - // Check if the path is valid - if (path.length() > 0) - { - // Check if the path has a trailing seperator, if so then there is no file name. - int pos = path.lastIndexOf(sep); - if (pos == -1 || pos == (path.length() - 1)) - { - // Set the path string in the returned string array - pathStr[0] = path; - } - else - { - // Split the path into directory list and file name strings - pathStr[1] = path.substring(pos + 1); - - if (pos == 0) - pathStr[0] = path.substring(0, pos + 1); - else - pathStr[0] = path.substring(0, pos); - } - } - - // Return the path strings - return pathStr; - } - - /** - * Split the path into all the component directories and filename - * - * @param path String - * @return String[] - */ - public static String[] splitAllPaths(String path) - { - - // Check if the path is valid - - if (path == null || path.length() == 0) - return null; - - // Determine the number of components in the path - - StringTokenizer token = new StringTokenizer(path, DOS_SEPERATOR_STR); - String[] names = new String[token.countTokens()]; - - // Split the path - - int i = 0; - - while (i < names.length && token.hasMoreTokens()) - names[i++] = token.nextToken(); - - // Return the path components - - return names; - } - - /** - * Split a path string into directory path, file name and stream name components - * - * @param path Full path string. - * @return java.lang.String[] - */ - public static String[] splitPathStream(String path) - { - - // Allocate the return list - - String[] pathStr = new String[3]; - - // Split the path into directory path and file/stream name - - FileName.splitPath(path, DOS_SEPERATOR, pathStr); - if (pathStr[1] == null) - return pathStr; - - // Split the file name into file and stream names - - int pos = pathStr[1].indexOf(NTFSStreamSeperator); - - if (pos != -1) - { - - // Split the file/stream name - - pathStr[2] = pathStr[1].substring(pos); - pathStr[1] = pathStr[1].substring(0, pos); - } - - // Return the path components list - - return pathStr; - } - - /** - * Test if a file name contains an NTFS stream name - * - * @param path String - * @return boolean - */ - public static boolean containsStreamName(String path) - { - - // Check if the path contains the stream name seperator character - - if (path.indexOf(NTFSStreamSeperator) != -1) - return true; - return false; - } - - /** - * Normalize the path to uppercase the directory names and keep the case of the file name. - * - * @param path String - * @return String - */ - public final static String normalizePath(String path) - { - - // Split the path into directories and file name, only uppercase the directories to - // normalize - // the path. - - String normPath = path; - - if (path.length() > 3) - { - - // Split the path to seperate the folders/file name - - int pos = path.lastIndexOf(DOS_SEPERATOR); - if (pos != -1) - { - - // Get the path and file name parts, normalize the path - - String pathPart = path.substring(0, pos).toUpperCase(); - String namePart = path.substring(pos); - - // Rebuild the path string - - normPath = pathPart + namePart; - } - } - - // Return the normalized path - - return normPath; - } - - /** - * Make a path relative to the base path for the specified path. - * - * @param basePath String - * @param fullPath String - * @return String - */ - public final static String makeRelativePath(String basePath, String fullPath) - { - - // Check if the base path is the root path - - if (basePath.length() == 0 || basePath.equals(DOS_SEPERATOR_STR)) - { - - // Return the full path, strip any leading seperator - - if (fullPath.length() > 0 && fullPath.charAt(0) == DOS_SEPERATOR) - return fullPath.substring(1); - return fullPath; - } - - // Split the base and full paths into seperate components - - String[] baseNames = splitAllPaths(basePath); - String[] fullNames = splitAllPaths(fullPath); - - // Check that the full path is actually within the base path tree - - if (baseNames != null && baseNames.length > 0 && fullNames != null && fullNames.length > 0 - && baseNames[0].equalsIgnoreCase(fullNames[0]) == false) - return null; - - // Match the path names - - int idx = 0; - - while (idx < baseNames.length && idx < fullNames.length && baseNames[idx].equalsIgnoreCase(fullNames[idx])) - idx++; - - // Build the relative path - - StringBuffer relPath = new StringBuffer(128); - - while (idx < fullNames.length) - { - relPath.append(fullNames[idx++]); - if (idx < fullNames.length) - relPath.append(DOS_SEPERATOR); - } - - // Return the relative path - - return relPath.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/FileOfflineException.java b/source/java/org/alfresco/filesys/server/filesys/FileOfflineException.java deleted file mode 100644 index e47b9eac59..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileOfflineException.java +++ /dev/null @@ -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.server.filesys; - -import java.io.IOException; - -/** - *

- * This exception may be thrown by a disk interface when the file data is not available due to the - * file being archived or the repository being unavailable. - */ -public class FileOfflineException extends IOException -{ - private static final long serialVersionUID = 3257006574835807795L; - - /** - * Class constructor. - */ - public FileOfflineException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public FileOfflineException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileOpenParams.java b/source/java/org/alfresco/filesys/server/filesys/FileOpenParams.java deleted file mode 100644 index 83fac3f334..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileOpenParams.java +++ /dev/null @@ -1,813 +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.server.filesys; - -import org.alfresco.filesys.smb.SharingMode; -import org.alfresco.filesys.smb.WinNT; - -/** - * File Open Parameters Class - *

- * Contains the details of a file open request. - */ -public class FileOpenParams -{ - // Constants - - public final static String StreamSeparator = ":"; - - // Conversion array for Core/LanMan open actions to NT open action codes - - private static int[] _NTToLMOpenCode = { - FileAction.TruncateExisting + FileAction.CreateNotExist, - FileAction.OpenIfExists, - FileAction.CreateNotExist, - FileAction.OpenIfExists + FileAction.CreateNotExist, - FileAction.TruncateExisting, - FileAction.TruncateExisting + FileAction.CreateNotExist }; - - // File open mode strings - - private static String[] _openMode = { "Supersede", "Open", "Create", "OpenIf", "Overwrite", "OverwriteIf" }; - - // File/directory to be opened - - private String m_path; - - // Stream name - - private String m_stream; - - // File open action - - private int m_openAction; - - // Desired access mode - - private int m_accessMode; - - // File attributes - - private int m_attr; - - // Allocation size - - private long m_allocSize; - - // Shared access flags - - private int m_sharedAccess = SharingMode.READWRITE; - - // Creation date/time - - private long m_createDate; - - // Root directory file id, zero if not specified - - private int m_rootFID; - - // Create options - - private int m_createOptions; - - // Security impersonation level, -1 if not set - - private int m_secLevel; - - // Security flags - - private int m_secFlags; - - // Owner group and user id - - private int m_gid = -1; - private int m_uid = -1; - - // Unix mode - - private int m_mode = -1; - - // File type and symbolic name - - private int m_fileType; - private String m_symName; - - /** - * Class constructor for Core SMB dialect Open SMB requests - * - * @param path String - * @param openAction int - * @param accessMode int - * @param fileAttr int - */ - public FileOpenParams(String path, int openAction, int accessMode, int fileAttr) - { - - // Parse the file path, split into file name and stream if specified - - parseFileName(path); - - m_openAction = convertToNTOpenAction(openAction); - m_accessMode = convertToNTAccessMode(accessMode); - m_attr = fileAttr; - - // Check if the diectory attribute is set - - if (FileAttribute.isDirectory(m_attr)) - m_createOptions = WinNT.CreateDirectory; - - // No security settings - - m_secLevel = -1; - } - - /** - * Class constructor for Core SMB dialect Open SMB requests - * - * @param path String - * @param openAction int - * @param accessMode int - * @param fileAttr int - * @param gid int - * @param uid int - * @param mode int - */ - public FileOpenParams(String path, int openAction, int accessMode, int fileAttr, int gid, int uid, int mode) - { - - // Parse the file path, split into file name and stream if specified - - parseFileName(path); - - m_openAction = convertToNTOpenAction(openAction); - m_accessMode = convertToNTAccessMode(accessMode); - m_attr = fileAttr; - - // Check if the diectory attribute is set - - if (FileAttribute.isDirectory(m_attr)) - m_createOptions = WinNT.CreateDirectory; - - // No security settings - - m_secLevel = -1; - - m_gid = gid; - m_uid = uid; - m_mode = mode; - } - - /** - * Class constructor for LanMan SMB dialect OpenAndX requests - * - * @param path String - * @param openAction int - * @param accessMode int - * @param searchAttr int - * @param fileAttr int - * @param allocSize int - * @param createDate long - */ - public FileOpenParams(String path, int openAction, int accessMode, int searchAttr, int fileAttr, int allocSize, - long createDate) - { - - // Parse the file path, split into file name and stream if specified - - parseFileName(path); - - m_openAction = convertToNTOpenAction(openAction); - m_accessMode = convertToNTAccessMode(accessMode); - m_attr = fileAttr; - m_sharedAccess = convertToNTSharedMode(accessMode); - m_allocSize = (long) allocSize; - m_createDate = createDate; - - // Check if the diectory attribute is set - - if (FileAttribute.isDirectory(m_attr)) - m_createOptions = WinNT.CreateDirectory; - - // No security settings - - m_secLevel = -1; - } - - /** - * Class constructor for NT SMB dialect NTCreateAndX requests - * - * @param path String - * @param openAction int - * @param accessMode int - * @param attr int - * @param sharedAccess int - * @param allocSize long - * @param createOption int - * @param rootFID int - * @param secLevel int - * @param secFlags int - */ - public FileOpenParams(String path, int openAction, int accessMode, int attr, int sharedAccess, long allocSize, - int createOption, int rootFID, int secLevel, int secFlags) - { - - // Parse the file path, split into file name and stream if specified - - parseFileName(path); - - m_openAction = openAction; - m_accessMode = accessMode; - m_attr = attr; - m_sharedAccess = sharedAccess; - m_allocSize = allocSize; - m_createOptions = createOption; - m_rootFID = rootFID; - m_secLevel = secLevel; - m_secFlags = secFlags; - - // Make sure the directory attribute is set if the create directory option is set - - if ((createOption & WinNT.CreateDirectory) != 0 && (m_attr & FileAttribute.Directory) == 0) - m_attr += FileAttribute.Directory; - } - - /** - * Return the path to be opened/created - * - * @return String - */ - public final String getPath() - { - return m_path; - } - - /** - * Return the full path to be opened/created, including the stream - * - * @return String - */ - public final String getFullPath() - { - if (isStream()) - return m_path + m_stream; - else - return m_path; - } - - /** - * Return the file attributes - * - * @return int - */ - public final int getAttributes() - { - return m_attr; - } - - /** - * Return the allocation size, or zero if not specified - * - * @return long - */ - public final long getAllocationSize() - { - return m_allocSize; - } - - /** - * Determine if a creation date/time has been specified - * - * @return boolean - */ - public final boolean hasCreationDateTime() - { - return m_createDate != 0L ? true : false; - } - - /** - * Return the file creation date/time - * - * @return long - */ - public final long getCreationDateTime() - { - return m_createDate; - } - - /** - * Return the open/create file/directory action All actions are mapped to the FileAction.NTxxx - * action codes. - * - * @return int - */ - public final int getOpenAction() - { - return m_openAction; - } - - /** - * Return the root directory file id, or zero if not specified - * - * @return int - */ - public final int getRootDirectoryFID() - { - return m_rootFID; - } - - /** - * Return the stream name - * - * @return String - */ - public final String getStreamName() - { - return m_stream; - } - - /** - * Check if the specified create option is enabled, specified in the WinNT class. - * - * @param flag int - * @return boolean - */ - public final boolean hasCreateOption(int flag) - { - return (m_createOptions & flag) != 0 ? true : false; - } - - /** - * Check if a file stream has been specified in the path to be created/opened - * - * @return boolean - */ - public final boolean isStream() - { - return m_stream != null ? true : false; - } - - /** - * Determine if the file is to be opened read-only - * - * @return boolean - */ - public final boolean isReadOnlyAccess() - { - // Check if read-only or execute access has been requested - - if (( m_accessMode & AccessMode.NTReadWrite) == AccessMode.NTRead || - (m_accessMode & AccessMode.NTExecute) != 0) - return true; - return false; - } - - /** - * Determine if the file is to be opened write-only - * - * @return boolean - */ - public final boolean isWriteOnlyAccess() - { - return (m_accessMode & AccessMode.NTReadWrite) == AccessMode.NTWrite ? true : false; - } - - /** - * Determine if the file is to be opened read/write - * - * @return boolean - */ - public final boolean isReadWriteAccess() - { - return (m_accessMode & AccessMode.NTReadWrite) == AccessMode.NTReadWrite ? true : false; - } - - /** - * Check for a particular access mode - * - * @param mode int - * @return boolean - */ - public final boolean hasAccessMode(int mode) - { - return (m_accessMode & mode) == mode ? true : false; - } - - /** - * Determine if the target of the create/open is a directory - * - * @return boolean - */ - public final boolean isDirectory() - { - return hasCreateOption(WinNT.CreateDirectory); - } - - /** - * Determine if the file will be accessed sequentially only - * - * @return boolean - */ - public final boolean isSequentialAccessOnly() - { - return hasCreateOption(WinNT.CreateSequential); - } - - /** - * Determine if the file should be deleted when closed - * - * @return boolean - */ - public final boolean isDeleteOnClose() - { - return hasCreateOption(WinNT.CreateDeleteOnClose); - } - - /** - * Determine if write-through mode is enabled (buffering is not allowed if enabled) - * - * @return boolean - */ - public final boolean isWriteThrough() - { - return hasCreateOption(WinNT.CreateWriteThrough); - } - - /** - * Determine if the open mode should overwrite/truncate an existing file - * - * @return boolean - */ - public final boolean isOverwrite() - { - if (getOpenAction() == FileAction.NTSupersede || getOpenAction() == FileAction.NTOverwrite - || getOpenAction() == FileAction.NTOverwriteIf) - return true; - return false; - } - - /** - * Return the file type - * - * @return int - */ - public final int isFileType() - { - return m_fileType; - } - - /** - * determine if the target of the create/open is a symbolic link - * - * @return boolean - */ - public final boolean isSymbolicLink() - { - return isFileType() == FileType.SymbolicLink; - } - - /** - * Return the symbolic link name - * - * @return String - */ - public final String getSymbolicLinkName() - { - return m_symName; - } - - /** - * Return the shared access mode, zero equals allow any shared access - * - * @return int - */ - public final int getSharedAccess() - { - return m_sharedAccess; - } - - /** - * Determine if security impersonation is enabled - * - * @return boolean - */ - public final boolean hasSecurityLevel() - { - return m_secLevel != -1 ? true : false; - } - - /** - * Return the security impersonation level. Levels are defined in the WinNT class. - * - * @return int - */ - public final int getSecurityLevel() - { - return m_secLevel; - } - - /** - * Determine if the security context tracking flag is enabled - * - * @return boolean - */ - public final boolean hasSecurityContextTracking() - { - return (m_secFlags & WinNT.SecurityContextTracking) != 0 ? true : false; - } - - /** - * Determine if the security effective only flag is enabled - * - * @return boolean - */ - public final boolean hasSecurityEffectiveOnly() - { - return (m_secFlags & WinNT.SecurityEffectiveOnly) != 0 ? true : false; - } - - /** - * Determine if the group id has been set - * - * @return boolean - */ - public final boolean hasGid() - { - return m_gid != -1 ? true : false; - } - - /** - * Return the owner group id - * - * @return int - */ - public final int getGid() - { - return m_gid; - } - - /** - * Determine if the user id has been set - * - * @return boolean - */ - public final boolean hasUid() - { - return m_uid != -1 ? true : false; - } - - /** - * Return the owner user id - * - * @return int - */ - public final int getUid() - { - return m_uid; - } - - /** - * Determine if the mode has been set - * - * @return boolean - */ - public final boolean hasMode() - { - return m_mode != -1 ? true : false; - } - - /** - * Return the Unix mode - * - * @return int - */ - public final int getMode() - { - return m_mode; - } - - /** - * Set the Unix mode - * - * @param mode int - */ - public final void setMode(int mode) - { - m_mode = mode; - } - - /** - * Set a create option flag - * - * @param flag int - */ - public final void setCreateOption(int flag) - { - m_createOptions = m_createOptions | flag; - } - - /** - * Set the file type - * - * @param typ int - */ - public final void setFileType(int typ) - { - m_fileType = typ; - } - - /** - * Set the symbolic link name - * - * @param name String - */ - public final void setSymbolicLink(String name) - { - m_symName = name; - m_fileType = FileType.SymbolicLink; - } - - /** - * Convert a Core/LanMan access mode to an NT access mode - * - * @param accessMode int - * @return int - */ - private final int convertToNTAccessMode(int accessMode) - { - - // Convert the Core/LanMan SMB dialect format access mode value to an NT access mode - - int mode = 0; - - switch (AccessMode.getAccessMode(accessMode)) - { - case AccessMode.ReadOnly: - mode = AccessMode.NTRead; - break; - case AccessMode.WriteOnly: - mode = AccessMode.NTWrite; - break; - case AccessMode.ReadWrite: - mode = AccessMode.NTReadWrite; - break; - } - return mode; - } - - /** - * Convert a Core/LanMan open action to an NT open action - * - * @param openAction int - * @return int - */ - private final int convertToNTOpenAction(int openAction) - { - - // Convert the Core/LanMan SMB dialect open action to an NT open action - - int action = FileAction.NTOpen; - - for (int i = 0; i < _NTToLMOpenCode.length; i++) - { - if (_NTToLMOpenCode[i] == openAction) - action = i; - } - return action; - } - - /** - * Convert a Core/LanMan shared access to NT sharing flags - * - * @param sharedAccess int - * @return int - */ - private final int convertToNTSharedMode(int sharedAccess) - { - - // Get the shared access value from the access mask - - int shr = AccessMode.getSharingMode(sharedAccess); - int ret = SharingMode.READWRITE; - - switch (shr) - { - case AccessMode.Exclusive: - ret = SharingMode.NOSHARING; - break; - case AccessMode.DenyRead: - ret = SharingMode.WRITE; - break; - case AccessMode.DenyWrite: - ret = SharingMode.READ; - break; - } - return ret; - } - - /** - * Parse a file name to split the main file name/path and stream name - * - * @param fileName String - */ - private final void parseFileName(String fileName) - { - - // Check if the file name contains a stream name - - int pos = fileName.indexOf(StreamSeparator); - if (pos == -1) - { - m_path = fileName; - return; - } - - // Split the main file name and stream name - - m_path = fileName.substring(0, pos); - m_stream = fileName.substring(pos); - } - - /** - * Return the file open parameters as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - - str.append(getPath()); - - str.append(","); - str.append(_openMode[getOpenAction()]); - str.append(",acc=0x"); - str.append(Integer.toHexString(m_accessMode)); - str.append(",attr=0x"); - str.append(Integer.toHexString(getAttributes())); - str.append(",alloc="); - str.append(getAllocationSize()); - str.append(",share=0x"); - str.append(Integer.toHexString(getSharedAccess())); - - if (getRootDirectoryFID() != 0) - { - str.append(",fid="); - str.append(getRootDirectoryFID()); - } - - if (hasCreationDateTime()) - { - str.append(",cdate="); - str.append(getCreationDateTime()); - } - - if (m_createOptions != 0) - { - str.append(",copt=0x"); - str.append(Integer.toHexString(m_createOptions)); - } - - if (hasSecurityLevel()) - { - str.append(",seclev="); - str.append(getSecurityLevel()); - str.append(",secflg=0x"); - str.append(Integer.toHexString(m_secFlags)); - } - str.append("]"); - - if (hasGid() || hasUid()) - { - str.append(",gid="); - str.append(getGid()); - str.append(",uid="); - str.append(getUid()); - str.append(",mode="); - str.append(getMode()); - } - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileSharingException.java b/source/java/org/alfresco/filesys/server/filesys/FileSharingException.java deleted file mode 100644 index 91730b183b..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileSharingException.java +++ /dev/null @@ -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.server.filesys; - -/** - * File sharing exception class. - */ -public class FileSharingException extends java.io.IOException -{ - private static final long serialVersionUID = 3258130241309260085L; - - /** - * Class constructor - */ - public FileSharingException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public FileSharingException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileStatus.java b/source/java/org/alfresco/filesys/server/filesys/FileStatus.java deleted file mode 100644 index e1f6d2a7af..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileStatus.java +++ /dev/null @@ -1,71 +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.server.filesys; - -/** - * File Status Class - */ -public class FileStatus -{ - - // File status constants - - public final static int Unknown = -1; - public final static int NotExist = 0; - public final static int FileExists = 1; - public final static int DirectoryExists = 2; - - /** - * Return the file status as a string - * - * @param sts int - * @return String - */ - public final static String asString(int sts) - { - - // Convert the status to a string - - String ret = ""; - - switch (sts) - { - case Unknown: - ret = "Unknown"; - break; - case NotExist: - ret = "NotExist"; - break; - case FileExists: - ret = "FileExists"; - break; - case DirectoryExists: - ret = "DirExists"; - break; - } - - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileSystem.java b/source/java/org/alfresco/filesys/server/filesys/FileSystem.java deleted file mode 100644 index 82dc845e89..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileSystem.java +++ /dev/null @@ -1,56 +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.server.filesys; - -/** - * Filesystem Attributes Class - *

- * Contains constant attributes used to define filesystem features available. The values are taken - * from the SMB/CIFS protocol query filesystem call. - */ -public final class FileSystem -{ - - // Filesystem attributes - - public static final int CaseSensitiveSearch = 0x00000001; - public static final int CasePreservedNames = 0x00000002; - public static final int UnicodeOnDisk = 0x00000004; - public static final int PersistentACLs = 0x00000008; - public static final int FileCompression = 0x00000010; - public static final int VolumeQuotas = 0x00000020; - public static final int SparseFiles = 0x00000040; - public static final int ReparsePoints = 0x00000080; - public static final int RemoteStorage = 0x00000100; - public static final int LFNAPISupport = 0x00004000; - public static final int VolumeIsCompressed = 0x00008000; - public static final int ObjectIds = 0x00010000; - public static final int Encryption = 0x00020000; - - // Filesystem type strings - - public static final String TypeFAT = "FAT"; - public static final String TypeNTFS = "NTFS"; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FileType.java b/source/java/org/alfresco/filesys/server/filesys/FileType.java deleted file mode 100644 index 92ce566710..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FileType.java +++ /dev/null @@ -1,78 +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.server.filesys; - -/* - * FileType.java - * - * Copyright (c) Starlasoft 2006. All rights reserved. - */ - -/** - * File Type Class - * - *

File type constants. - * - * @author GKSpencer - */ -public class FileType { - - // File types - - public static final int RegularFile = 1; - public static final int Directory = 2; - public static final int SymbolicLink = 3; - public static final int HardLink = 4; - public static final int Device = 5; - - /** - * Return a file type as a string - * - * @param typ int - * @return String - */ - public final static String asString(int typ) { - - String typStr = "Unknown"; - - switch (typ) { - case RegularFile: - typStr = "File"; - break; - case Directory: - typStr = "Directory"; - break; - case SymbolicLink: - typStr = "SymbolicLink"; - break; - case HardLink: - typStr = "HardLink"; - break; - case Device: - typStr = "Device"; - break; - } - - return typStr; - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/FilesysTransaction.java b/source/java/org/alfresco/filesys/server/filesys/FilesysTransaction.java deleted file mode 100644 index 8de371778f..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/FilesysTransaction.java +++ /dev/null @@ -1,118 +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.server.filesys; - -import javax.transaction.UserTransaction; - -/** - * Filesystem Transaction Class - * - *

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(); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java b/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java deleted file mode 100644 index 9376e49cc6..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java +++ /dev/null @@ -1,56 +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.server.filesys; - -/** - * I/O Control Not Implemented Exception Class - * - *

This exception may be thrown by an IOCtlInterface implementation. - * - * @author gkspencer - */ -public class IOControlNotImplementedException extends Exception -{ - private static final long serialVersionUID = -7107739317519497749L; - - /** - * Default constructor. - */ - public IOControlNotImplementedException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public IOControlNotImplementedException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java b/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java deleted file mode 100644 index d01ebf734e..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java +++ /dev/null @@ -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.server.filesys; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.util.DataBuffer; - -/** - * IO Control Interface - * - *

Optional interface that a DiskInterface driver can implement to enable NT I/O control function - * processing. - * - * @author gkspencer - */ -public interface IOCtlInterface -{ - /** - * Process a filesystem I/O control request - * - * @param sess Server session - * @param tree Tree connection. - * @param ctrlCode I/O control code - * @param fid File id - * @param dataBuf I/O control specific input data - * @param isFSCtrl true if this is a filesystem control, or false for a device control - * @param filter if bit0 is set indicates that the control applies to the share root handle - * @return DataBuffer - * @exception IOControlNotImplementedException - * @exception SMBException - */ - public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf, - boolean isFSCtrl, int filter) throws IOControlNotImplementedException, SMBException; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/MediaOfflineException.java b/source/java/org/alfresco/filesys/server/filesys/MediaOfflineException.java deleted file mode 100644 index c2a8776d92..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/MediaOfflineException.java +++ /dev/null @@ -1,57 +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.server.filesys; - -import java.io.IOException; - -/** - * Media Offline Exception Class - *

- * This exception may be thrown by a disk interface when a file/folder is not available due to the - * storage media being offline, repository being unavailable, database unavailable or inaccessible - * or similar condition. - */ -public class MediaOfflineException extends IOException -{ - private static final long serialVersionUID = 3544956554064704306L; - - /** - * Class constructor. - */ - public MediaOfflineException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public MediaOfflineException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/NetworkFile.java b/source/java/org/alfresco/filesys/server/filesys/NetworkFile.java deleted file mode 100644 index d5af35f120..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/NetworkFile.java +++ /dev/null @@ -1,869 +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.server.filesys; - -import java.io.IOException; - -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.locking.FileLockList; -import org.alfresco.filesys.server.state.FileState; - -/** - *

- * The network file represents a file or directory on a filesystem. The server keeps track of the - * open files on a per session basis. - *

- * This class may be extended as required by your own disk driver class. - */ -public abstract class NetworkFile -{ - - // Granted file access types - - public static final int READONLY = 0; - public static final int WRITEONLY = 1; - public static final int READWRITE = 2; - - // File status flags - - public static final int IOPending = 0x0001; - public static final int DeleteOnClose = 0x0002; - - // File identifier and parent directory identifier - - protected int m_fid; - protected int m_dirId; - - // Unique file identifier - - protected long m_uniqueId; - - // File/directory name - - protected String m_name; - - // Stream name and id - - protected String m_streamName; - protected int m_streamId; - - // Full name, relative to the share - - protected String m_fullName; - - // File attributes - - protected int m_attrib; - - // File size - - protected long m_fileSize; - - // File creation/modify/last access date/time - - protected long m_createDate; - protected long m_modifyDate; - protected long m_accessDate; - - // Granted file access type - - protected int m_grantedAccess; - - // Flag to indicate that the file has been closed - - protected boolean m_closed = true; - - // Count of write requests to the file, used to determine if the file size may have changed - - protected int m_writeCount; - - // List of locks on this file by this session. The lock object will almost certainly be - // referenced elsewhere depending upon the LockManager implementation used. If locking support is not - // enabled for the DiskInterface implementation the lock list will not be allocated. - // - // This lock list is used to release locks on the file if the session abnormally terminates or - // closes the file without releasing all locks. - - private FileLockList m_lockList; - - // File status flags - - private int m_flags; - - // Associated file state - - private FileState m_state; - - /** - * Create a network file object with the specified file identifier. - * - * @param fid int - */ - public NetworkFile(int fid) - { - m_fid = fid; - } - - /** - * Create a network file with the specified file and parent directory ids - * - * @param fid int - * @param did int - */ - public NetworkFile(int fid, int did) - { - m_fid = fid; - m_dirId = did; - } - - /** - * Create a network file with the specified file id, stream id and parent directory id - * - * @param fid int - * @param stid int - * @param did int - */ - public NetworkFile(int fid, int stid, int did) - { - m_fid = fid; - m_streamId = stid; - m_dirId = did; - } - - /** - * Create a network file object with the specified file/directory name. - * - * @param name File name string. - */ - public NetworkFile(String name) - { - m_name = name; - } - - /** - * Return the parent directory identifier - * - * @return int - */ - public final int getDirectoryId() - { - return m_dirId; - } - - /** - * Return the file attributes. - * - * @return int - */ - public final int getFileAttributes() - { - return m_attrib; - } - - /** - * Return the file identifier. - * - * @return int - */ - public final int getFileId() - { - return m_fid; - } - - /** - * Get the file size, in bytes. - * - * @return long - */ - public final long getFileSize() - { - return m_fileSize; - } - - /** - * Get the file size, in bytes. - * - * @return int - */ - public final int getFileSizeInt() - { - return (int) (m_fileSize & 0x0FFFFFFFFL); - } - - /** - * Return the associated file state - * - * @return FileState - */ - public final FileState getFileState() - { - return m_state; - } - - /** - * Return the full name, relative to the share. - * - * @return java.lang.String - */ - public final String getFullName() - { - return m_fullName; - } - - /** - * Return the full name including the stream name, relative to the share. - * - * @return java.lang.String - */ - public final String getFullNameStream() - { - if (isStream()) - return m_fullName + m_streamName; - else - return m_fullName; - } - - /** - * Return the granted file access mode. - */ - public final int getGrantedAccess() - { - return m_grantedAccess; - } - - /** - * Return the file/directory name. - * - * @return java.lang.String - */ - public String getName() - { - return m_name; - } - - /** - * Return the stream id, zero indicates the main file stream - * - * @return int - */ - public final int getStreamId() - { - return m_streamId; - } - - /** - * Return the stream name, if this is a stream - * - * @return String - */ - public final String getStreamName() - { - return m_streamName; - } - - /** - * Return the unique file identifier - * - * @return long - */ - public final long getUniqueId() - { - return m_uniqueId; - } - - /** - * Determine if the file has been closed. - * - * @return boolean - */ - public final boolean isClosed() - { - return m_closed; - } - - /** - * Return the directory file attribute status. - * - * @return true if the file is a directory, else false. - */ - - public final boolean isDirectory() - { - return (m_attrib & FileAttribute.Directory) != 0 ? true : false; - } - - /** - * Return the hidden file attribute status. - * - * @return true if the file is hidden, else false. - */ - - public final boolean isHidden() - { - return (m_attrib & FileAttribute.Hidden) != 0 ? true : false; - } - - /** - * Return the read-only file attribute status. - * - * @return true if the file is read-only, else false. - */ - - public final boolean isReadOnly() - { - return (m_attrib & FileAttribute.ReadOnly) != 0 ? true : false; - } - - /** - * Return the system file attribute status. - * - * @return true if the file is a system file, else false. - */ - - public final boolean isSystem() - { - return (m_attrib & FileAttribute.System) != 0 ? true : false; - } - - /** - * Return the archived attribute status - * - * @return boolean - */ - public final boolean isArchived() - { - return (m_attrib & FileAttribute.Archive) != 0 ? true : false; - } - - /** - * Check if this is a stream file - * - * @return boolean - */ - public final boolean isStream() - { - return m_streamName != null ? true : false; - } - - /** - * Check if there are active locks on this file by this session - * - * @return boolean - */ - public final boolean hasLocks() - { - if (m_lockList != null && m_lockList.numberOfLocks() > 0) - return true; - return false; - } - - /** - * Check for NT attributes - * - * @param attr int - * @return boolean - */ - public final boolean hasNTAttribute(int attr) - { - return (m_attrib & attr) == attr ? true : false; - } - - /** - * Determine if the file access date/time is valid - * - * @return boolean - */ - public final boolean hasAccessDate() - { - return m_accessDate != 0L ? true : false; - } - - /** - * Return the file access date/time - * - * @return long - */ - public final long getAccessDate() - { - return m_accessDate; - } - - /** - * Determine if the file creation date/time is valid - * - * @return boolean - */ - public final boolean hasCreationDate() - { - return m_createDate != 0L ? true : false; - } - - /** - * Return the file creation date/time - * - * @return long - */ - public final long getCreationDate() - { - return m_createDate; - } - - /** - * Check if the delete on close flag has been set for this file - * - * @return boolean - */ - public final boolean hasDeleteOnClose() - { - return (m_flags & DeleteOnClose) != 0 ? true : false; - } - - /** - * Check if the file has an I/O request pending - * - * @return boolean - */ - public final boolean hasIOPending() - { - return (m_flags & IOPending) != 0 ? true : false; - } - - /** - * Determine if the file modification date/time is valid - * - * @return boolean - */ - public boolean hasModifyDate() - { - return m_modifyDate != 0L ? true : false; - } - - /** - * Return the file modify date/time - * - * @return long - */ - public final long getModifyDate() - { - return m_modifyDate; - } - - /** - * Get the write count for the file - * - * @return int - */ - public final int getWriteCount() - { - return m_writeCount; - } - - /** - * Increment the write count - */ - public final void incrementWriteCount() - { - m_writeCount++; - } - - /** - * Set the file attributes, as specified by the SMBFileAttribute class. - * - * @param attrib int - */ - public final void setAttributes(int attrib) - { - m_attrib = attrib; - } - - /** - * Set, or clear, the delete on close flag - * - * @param del boolean - */ - public final void setDeleteOnClose(boolean del) - { - setStatusFlag(DeleteOnClose, del); - } - - /** - * Set the parent directory identifier - * - * @param dirId int - */ - public final void setDirectoryId(int dirId) - { - m_dirId = dirId; - } - - /** - * Set the file identifier. - * - * @param fid int - */ - public final void setFileId(int fid) - { - m_fid = fid; - } - - /** - * Set the file size. - * - * @param siz long - */ - public final void setFileSize(long siz) - { - m_fileSize = siz; - } - - /** - * Set the file size. - * - * @param siz int - */ - public final void setFileSize(int siz) - { - m_fileSize = (long) siz; - } - - /** - * Set the associated file state - * - * @param state FileState - */ - public final void setFileState( FileState state) - { - m_state = state; - } - - /** - * Set the full file name, relative to the share. - * - * @param name java.lang.String - */ - public final void setFullName(String name) - { - m_fullName = name; - } - - /** - * Set the granted file access mode. - * - * @param mode int - */ - public final void setGrantedAccess(int mode) - { - m_grantedAccess = mode; - } - - /** - * Set the file name. - * - * @param name String - */ - public final void setName(String name) - { - m_name = name; - } - - /** - * set/clear the I/O pending flag - * - * @param pending boolean - */ - public final void setIOPending(boolean pending) - { - setStatusFlag(IOPending, pending); - } - - /** - * Set the stream id - * - * @param id int - */ - public final void setStreamId(int id) - { - m_streamId = id; - } - - /** - * Set the stream name - * - * @param name String - */ - public final void setStreamName(String name) - { - m_streamName = name; - } - - /** - * Set the file closed state. - * - * @param b boolean - */ - public final synchronized void setClosed(boolean b) - { - m_closed = b; - } - - /** - * Set the file access date/time - * - * @param dattim long - */ - public final void setAccessDate(long dattim) - { - m_accessDate = dattim; - } - - /** - * Set the file creation date/time - * - * @param dattim long - */ - public final void setCreationDate(long dattim) - { - m_createDate = dattim; - } - - /** - * Set the file modification date/time - * - * @param dattim long - */ - public final void setModifyDate(long dattim) - { - m_modifyDate = dattim; - } - - /** - * Set/clear a file status flag - * - * @param flag int - * @param sts boolean - */ - protected final synchronized void setStatusFlag(int flag, boolean sts) - { - boolean state = (m_flags & flag) != 0; - if (sts == true && state == false) - m_flags += flag; - else if (sts == false && state == true) - m_flags -= flag; - } - - /** - * Add a lock to the active lock list - * - * @param lock FileLock - */ - public final synchronized void addLock(FileLock lock) - { - - // Check if the lock list has been allocated - - if (m_lockList == null) - m_lockList = new FileLockList(); - - // Add the lock - - m_lockList.addLock(lock); - } - - /** - * Remove a lock from the active lock list - * - * @param lock FileLock - */ - public final synchronized void removeLock(FileLock lock) - { - - // Check if the lock list is allocated - - if (m_lockList == null) - return; - - // Remove the lock - - m_lockList.removeLock(lock); - } - - /** - * Remove all locks from the lock list - */ - public final synchronized void removeAllLocks() - { - - // Check if the lock list is valid - - if (m_lockList != null) - m_lockList.removeAllLocks(); - } - - /** - * Return the count of active locks - * - * @return int - */ - public final int numberOfLocks() - { - - // Check if the lock list is allocated - - if (m_lockList == null) - return 0; - return m_lockList.numberOfLocks(); - } - - /** - * Get the details of an active lock from the list - * - * @param idx int - * @return FileLock - */ - public final FileLock getLockAt(int idx) - { - - // Check if the lock list is allocated and the index is valid - - if (m_lockList != null) - return m_lockList.getLockAt(idx); - - // Invalid index or lock list not valid - - return null; - } - - /** - * Return the lock list - * - * @return FileLockList - */ - public final FileLockList getLockList() - { - return m_lockList; - } - - /** - * Set the unique file identifier - * - * @param id long - */ - protected final void setUniqueId(long id) - { - m_uniqueId = id; - } - - /** - * Set the unique id using the file and directory id - * - * @param fid int - * @param did int - */ - protected final void setUniqueId(int fid, int did) - { - long ldid = (long) did; - long lfid = (long) fid; - m_uniqueId = (ldid << 32) + lfid; - } - - /** - * Set the unique id using the full path string - * - * @param path String - */ - protected final void setUniqueId(String path) - { - m_uniqueId = (long) path.toUpperCase().hashCode(); - } - - /** - * Open the file - * - * @param createFlag boolean - * @exception IOException - */ - public abstract void openFile(boolean createFlag) throws IOException; - - /** - * Read from the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param fileOff long - * @return Length of data read. - * @exception IOException - */ - public abstract int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException; - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param fileOff long - * @exception IOException - */ - public abstract void writeFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException; - - /** - * Seek to the specified file position. - * - * @param pos long - * @param typ int - * @return int - * @exception IOException - */ - public abstract long seekFile(long pos, int typ) throws IOException; - - /** - * Flush any buffered output to the file - * - * @throws IOException - */ - public abstract void flushFile() throws IOException; - - /** - * Truncate the file to the specified file size - * - * @param siz long - * @exception IOException - */ - public abstract void truncateFile(long siz) throws IOException; - - /** - * Close the database file - */ - public abstract void closeFile() throws IOException; - - /** - * Temporary method - */ - public void close() throws IOException - { - closeFile(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/NetworkFileServer.java b/source/java/org/alfresco/filesys/server/filesys/NetworkFileServer.java deleted file mode 100644 index 50aa4c2f27..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/NetworkFileServer.java +++ /dev/null @@ -1,49 +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.server.filesys; - -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.config.ServerConfiguration; - -/** - * Network File Server Class - *

- * Base class for all network file servers. - */ -public abstract class NetworkFileServer extends NetworkServer -{ - - /** - * Class constructor - * - * @param proto String - * @param serviceRegistry repository connection - * @param config ServerConfiguration - */ - public NetworkFileServer(String proto, ServerConfiguration config) - { - super(proto, config); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/NotifyChange.java b/source/java/org/alfresco/filesys/server/filesys/NotifyChange.java deleted file mode 100644 index f16a84161a..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/NotifyChange.java +++ /dev/null @@ -1,178 +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.server.filesys; - -/** - * Notify Change Transaction Class - */ -public class NotifyChange -{ - - // Change notification filter flags - - public final static int FileName = 0x0001; - public final static int DirectoryName = 0x0002; - public final static int Attributes = 0x0004; - public final static int Size = 0x0008; - public final static int LastWrite = 0x0010; - public final static int LastAccess = 0x0020; - public final static int Creation = 0x0040; - public final static int Security = 0x0100; - - // Change notification actions - - public final static int ActionAdded = 1; - public final static int ActionRemoved = 2; - public final static int ActionModified = 3; - public final static int ActionRenamedOldName = 4; - public final static int ActionRenamedNewName = 5; - public final static int ActionAddedStream = 6; - public final static int ActionRemovedStream = 7; - public final static int ActionModifiedStream = 8; - - // Change notification action names - - private final static String[] _actnNames = { "Added", "Removed", "Modified", "RenamedOldName", "RenamedNewName", - "AddedStream", "RemovedStream", "ModifiedStream" }; - - /** - * Return the change notification action as a string - * - * @param action int - * @return String - */ - public static final String getActionAsString(int action) - { - - // Range check the action - - if (action <= 0 || action > _actnNames.length) - return "Unknown"; - - // Return the action as a string - - return _actnNames[action - 1]; - } - - /** - * Return the change notification filter flag as a string. This method assumes a single flag is - * set. - * - * @param filter int - * @return String - */ - public static final String getFilterAsString(int filter) - { - - // Check if there are any flags set - - if (filter == 0) - return ""; - - // Determine the filter type - - String filtStr = null; - - switch (filter) - { - case FileName: - filtStr = "FileName"; - break; - case DirectoryName: - filtStr = "DirectoryName"; - break; - case Attributes: - filtStr = "Attributes"; - break; - case Size: - filtStr = "Size"; - break; - case LastWrite: - filtStr = "LastWrite"; - break; - case LastAccess: - filtStr = "LastAccess"; - break; - case Creation: - filtStr = "Creation"; - break; - case Security: - filtStr = "Security"; - break; - } - - // Return the filter type string - - return filtStr; - } - - /** - * Return the change notification filter flags as a string. - * - * @param filter int - * @return String - */ - public static final String getFilterFlagsAsString(int filter) - { - - // Check if there are any flags set - - if (filter == 0) - return ""; - - // Build the filter flags string - - StringBuffer filtStr = new StringBuffer(); - int i = 0x0001; - - while (i < Security) - { - - // Check if the current filter flag is set - - if ((filter & i) != 0) - { - - // Get the filter flag name - - String name = getFilterAsString(i); - if (name != null) - { - if (filtStr.length() > 0) - filtStr.append(","); - filtStr.append(name); - } - } - - // Update the filter flag mask - - i = i << 1; - } - - // Return the filter flags string - - return filtStr.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/PathNotFoundException.java b/source/java/org/alfresco/filesys/server/filesys/PathNotFoundException.java deleted file mode 100644 index b36b10e5a8..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/PathNotFoundException.java +++ /dev/null @@ -1,56 +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.server.filesys; - -import java.io.IOException; - -/** - * Path Not Found Exception Class - *

- * Indicates that the upper part of a path does not exist, as opposed to the file/folder at the end - * of the path. - */ -public class PathNotFoundException extends IOException -{ - private static final long serialVersionUID = 4050768191053378616L; - - /** - * Class constructor. - */ - public PathNotFoundException() - { - super(); - } - - /** - * Class constructor. - * - * @param s java.lang.String - */ - public PathNotFoundException(String s) - { - super(s); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/SearchContext.java b/source/java/org/alfresco/filesys/server/filesys/SearchContext.java deleted file mode 100644 index c0e48abfc8..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/SearchContext.java +++ /dev/null @@ -1,233 +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.server.filesys; - -/** - *

- * The search context represents the state of an active search by a disk interface based class. The - * context is used to continue a search across multiple requests. - */ -public abstract class SearchContext -{ - - // Maximum number of files to return per search request. - - private int m_maxFiles; - - // Tree identifier that this search is associated with - - private int m_treeId; - - // Search string - - private String m_searchStr; - - // Flags - - private int m_flags; - - /** - * Default constructor. - */ - public SearchContext() - { - } - - /** - * Construct a new search context. - * - * @param maxFiles int - * @param treeId int - */ - protected SearchContext(int maxFiles, int treeId) - { - m_maxFiles = maxFiles; - m_treeId = treeId; - } - - /** - * Close the search. - */ - public void closeSearch() - { - } - - /** - * Return the search context flags. - * - * @return int - */ - public final int getFlags() - { - return m_flags; - } - - /** - * Return the maximum number of files that should be returned per search request. - * - * @return int - */ - public final int getMaximumFiles() - { - return m_maxFiles; - } - - /** - * Return the resume id for the current file/directory in the search. - * - * @return int - */ - public abstract int getResumeId(); - - /** - * Return the search string, used for resume keys in some SMB dialects. - * - * @return java.lang.String - */ - public final String getSearchString() - { - return m_searchStr != null ? m_searchStr : ""; - } - - /** - * Return the tree identifier of the tree connection that this search is associated with. - * - * @return int - */ - public final int getTreeId() - { - return m_treeId; - } - - /** - * Determine if there are more files for the active search. - * - * @return boolean - */ - public abstract boolean hasMoreFiles(); - - /** - * Return file information for the next file in the active search. Returns false if the search - * is complete. - * - * @param info FileInfo to return the file information. - * @return true if the file information is valid, else false - */ - public abstract boolean nextFileInfo(FileInfo info); - - /** - * Return the file name of the next file in the active search. Returns null is the search is - * complete. - * - * @return java.lang.String - */ - public abstract String nextFileName(); - - /** - * Return the total number of file entries for this search if known, else return -1 - * - * @return int - */ - public int numberOfEntries() - { - return -1; - } - - /** - * Restart a search at the specified resume point. - * - * @param resumeId Resume point id. - * @return true if the search can be restarted, else false. - */ - public abstract boolean restartAt(int resumeId); - - /** - * Restart the current search at the specified file. - * - * @param info File to restart the search at. - * @return true if the search can be restarted, else false. - */ - public abstract boolean restartAt(FileInfo info); - - /** - * Set the search context flags. - * - * @param flg int - */ - public final void setFlags(int flg) - { - m_flags = flg; - } - - /** - * Set the maximum files to return per request packet. - * - * @param maxFiles int - */ - public final void setMaximumFiles(int maxFiles) - { - m_maxFiles = maxFiles; - } - - /** - * Set the search string. - * - * @param str java.lang.String - */ - public final void setSearchString(String str) - { - m_searchStr = str; - } - - /** - * Set the tree connection id that the search is associated with. - * - * @param id int - */ - public final void setTreeId(int id) - { - m_treeId = id; - } - - /** - * Return the search context as a string. - * - * @return java.lang.String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(getSearchString()); - str.append(":"); - str.append(getMaximumFiles()); - str.append(","); - str.append("0x"); - str.append(Integer.toHexString(getFlags())); - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/ShareListener.java b/source/java/org/alfresco/filesys/server/filesys/ShareListener.java deleted file mode 100644 index aa128a621c..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/ShareListener.java +++ /dev/null @@ -1,52 +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.server.filesys; - -import org.alfresco.filesys.server.SrvSession; - -/** - *

- * The share listener interface provides a hook into the server so that an application is notified - * when a session connects/disconnects from a particular share. - */ -public interface ShareListener -{ - - /** - * Called when a session connects to a share - * - * @param sess SrvSession - * @param tree TreeConnection - */ - public void shareConnect(SrvSession sess, TreeConnection tree); - - /** - * Called when a session disconnects from a share - * - * @param sess SrvSession - * @param tree TreeConnection - */ - public void shareDisconnect(SrvSession sess, TreeConnection tree); -} diff --git a/source/java/org/alfresco/filesys/server/filesys/SrvDiskInfo.java b/source/java/org/alfresco/filesys/server/filesys/SrvDiskInfo.java deleted file mode 100644 index e11cc19f52..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/SrvDiskInfo.java +++ /dev/null @@ -1,203 +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.server.filesys; - -import org.alfresco.filesys.smb.PCShare; - -/** - *

- * The class extends the client side version of the disk information class to allow values to be set - * after construction by a disk interface implementation. - *

- * The class contains information about the total, free and used blocks on a disk device, and the - * block size and blocks per allocation unit of the device. - */ -public class SrvDiskInfo extends DiskInfo -{ - - /** - * Create an empty disk information object. - */ - public SrvDiskInfo() - { - } - - /** - * Construct a disk information object. - * - * @param totunits int - * @param blkunit int - * @param blksiz int - * @param freeunit int - */ - public SrvDiskInfo(int totunits, int blkunit, int blksiz, int freeunit) - { - super(null, (long) totunits, blkunit, blksiz, (long) freeunit); - } - - /** - * Construct a disk information object. - * - * @param totunits long - * @param blkunit long - * @param blksiz long - * @param freeunit long - */ - public SrvDiskInfo(long totunits, long blkunit, long blksiz, long freeunit) - { - super(null, totunits, (int) blkunit, (int) blksiz, freeunit); - } - - /** - * Class constructor - * - * @param shr PCShare - * @param totunits int - * @param blkunit int - * @param blksiz int - * @param freeunit int - */ - protected SrvDiskInfo(PCShare shr, int totunits, int blkunit, int blksiz, int freeunit) - { - super(shr, totunits, blkunit, blksiz, freeunit); - } - - /** - * Set the block size, in bytes. - * - * @param siz int - */ - public final void setBlockSize(int siz) - { - m_blocksize = siz; - } - - /** - * Set the number of blocks per filesystem allocation unit. - * - * @param blks int - */ - public final void setBlocksPerAllocationUnit(int blks) - { - m_blockperunit = blks; - } - - /** - * Set the number of free units on this shared disk device. - * - * @param units int - */ - public final void setFreeUnits(int units) - { - m_freeunits = units; - } - - /** - * Set the total number of units on this shared disk device. - * - * @param units int - */ - public final void setTotalUnits(int units) - { - m_totalunits = units; - } - - /** - * Set the block size, in bytes. - * - * @param siz long - */ - public final void setBlockSize(long siz) - { - m_blocksize = siz; - } - - /** - * Set the number of blocks per filesystem allocation unit. - * - * @param blks long - */ - public final void setBlocksPerAllocationUnit(long blks) - { - m_blockperunit = blks; - } - - /** - * Set the number of free units on this shared disk device. - * - * @param units long - */ - public final void setFreeUnits(long units) - { - m_freeunits = units; - } - - /** - * Set the total number of units on this shared disk device. - * - * @param units long - */ - public final void setTotalUnits(long units) - { - m_totalunits = units; - } - - /** - * Set the node name. - * - * @param name java.lang.String - */ - protected final void setNodeName(String name) - { - m_nodename = name; - } - - /** - * Set the shared device name. - * - * @param name java.lang.String - */ - protected final void setShareName(String name) - { - m_share = name; - } - - /** - * Copy the disk information details - * - * @param disk SrvDiskInfo - */ - public final void copyFrom(SrvDiskInfo disk) - { - - // Copy the details to this object - - setBlockSize(disk.getBlockSize()); - setBlocksPerAllocationUnit(disk.getBlocksPerAllocationUnit()); - - setFreeUnits(disk.getFreeUnits()); - setTotalUnits(disk.getTotalUnits()); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/SymbolicLinkInterface.java b/source/java/org/alfresco/filesys/server/filesys/SymbolicLinkInterface.java deleted file mode 100644 index f2f26782f0..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/SymbolicLinkInterface.java +++ /dev/null @@ -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.server.filesys; - -import org.alfresco.filesys.server.SrvSession; - -/** - * Symbolic Link Interface - * - *

Optional interface that a filesystem driver can implement to indicate that symbolic links are supported. - */ -public interface SymbolicLinkInterface { - - /** - * Read the link data for a symbolic link - * - * @param sess SrvSession - * @param tree TreeConnection - * @param path String - * @return String - * @exception AccessDeniedException - */ - public String readSymbolicLink( SrvSession sess, TreeConnection tree, String path) - throws AccessDeniedException; -} diff --git a/source/java/org/alfresco/filesys/server/filesys/TooManyConnectionsException.java b/source/java/org/alfresco/filesys/server/filesys/TooManyConnectionsException.java deleted file mode 100644 index 6a9edb34a8..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/TooManyConnectionsException.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * This error indicates that too many tree connections are currently open on a session. The new tree - * connection request will be rejected by the server. - */ -public class TooManyConnectionsException extends Exception -{ - private static final long serialVersionUID = 3257845497929414961L; - - /** - * TooManyConnectionsException constructor. - */ - public TooManyConnectionsException() - { - super(); - } - - /** - * TooManyConnectionsException constructor. - * - * @param s java.lang.String - */ - public TooManyConnectionsException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/TooManyFilesException.java b/source/java/org/alfresco/filesys/server/filesys/TooManyFilesException.java deleted file mode 100644 index 4d6ad36e7a..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/TooManyFilesException.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * This error is generated when a tree connection has no free file slots. The new file open request - * will be rejected by the server. - */ -public class TooManyFilesException extends Exception -{ - private static final long serialVersionUID = 4051332218943060273L; - - /** - * TooManyFilesException constructor. - */ - public TooManyFilesException() - { - super(); - } - - /** - * TooManyFilesException constructor. - * - * @param s java.lang.String - */ - public TooManyFilesException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/TreeConnection.java b/source/java/org/alfresco/filesys/server/filesys/TreeConnection.java deleted file mode 100644 index 0164203583..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/TreeConnection.java +++ /dev/null @@ -1,375 +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.server.filesys; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.DeviceContext; -import org.alfresco.filesys.server.core.DeviceInterface; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.SharedDevice; - -/** - * The tree connection class holds the details of a single SMB tree connection. A tree connection is - * a connection to a shared device. - */ -public class TreeConnection -{ - - // Maximum number of open files allowed per connection. - - public static final int MAXFILES = 8192; - - // Number of initial file slots to allocate. Number of allocated slots will be doubled - // when required until MAXFILES is reached. - - public static final int INITIALFILES = 32; - - // Shared device that the connection is associated with - - private SharedDevice m_shareDev; - - // List of open files on this connection. Count of open file slots used. - - private NetworkFile[] m_files; - private int m_fileCount; - - // Access permission that the user has been granted - - private int m_permission; - - /** - * Construct a tree connection using the specified shared device. - * - * @param shrDev SharedDevice - */ - public TreeConnection(SharedDevice shrDev) - { - m_shareDev = shrDev; - m_shareDev.incrementConnectionCount(); - } - - /** - * Add a network file to the list of open files for this connection. - * - * @param file NetworkFile - * @param sess SrvSession - * @return int - */ - public final int addFile(NetworkFile file, SrvSession sess) throws TooManyFilesException - { - - // Check if the file array has been allocated - - if (m_files == null) - m_files = new NetworkFile[INITIALFILES]; - - // Find a free slot for the network file - - int idx = 0; - - while (idx < m_files.length && m_files[idx] != null) - idx++; - - // Check if we found a free slot - - if (idx == m_files.length) - { - - // The file array needs to be extended, check if we reached the limit. - - if (m_files.length >= MAXFILES) - throw new TooManyFilesException(); - - // Extend the file array - - NetworkFile[] newFiles = new NetworkFile[m_files.length * 2]; - System.arraycopy(m_files, 0, newFiles, 0, m_files.length); - m_files = newFiles; - } - - // Store the network file, update the open file count and return the index - - m_files[idx] = file; - m_fileCount++; - return idx; - } - - /** - * Close the tree connection, release resources. - * - * @param sess SrvSession - */ - public final void closeConnection(SrvSession sess) - { - - // Make sure all files are closed - - if (openFileCount() > 0) - { - - // Close all open files - - for (int idx = 0; idx < m_files.length; idx++) - { - - // Check if the file is active - - if (m_files[idx] != null) - removeFile(idx, sess); - } - } - - // Decrement the active connection count for the shared device - - m_shareDev.decrementConnectionCount(); - } - - /** - * Return the specified network file. - * - * @return NetworkFile - */ - public final NetworkFile findFile(int fid) - { - - // Check if the file id and file array are valid - - if (m_files == null || fid >= m_files.length) - return null; - - // Get the required file details - - return m_files[fid]; - } - - /** - * Return the length of the file table - * - * @return int - */ - public final int getFileTableLength() - { - if (m_files == null) - return 0; - return m_files.length; - } - - /** - * Determine if the shared device has an associated context - * - * @return boolean - */ - public final boolean hasContext() - { - if (m_shareDev != null) - return m_shareDev.getContext() != null ? true : false; - return false; - } - - /** - * Return the interface specific context object. - * - * @return Device interface context object. - */ - public final DeviceContext getContext() - { - if (m_shareDev == null) - return null; - return m_shareDev.getContext(); - } - - /** - * Return the share access permissions that the user has been granted. - * - * @return int - */ - public final int getPermission() - { - return m_permission; - } - - /** - * Deterimine if the access permission for the shared device allows read access - * - * @return boolean - */ - public final boolean hasReadAccess() - { - if (m_permission == FileAccess.ReadOnly || m_permission == FileAccess.Writeable) - return true; - return false; - } - - /** - * Determine if the access permission for the shared device allows write access - * - * @return boolean - */ - public final boolean hasWriteAccess() - { - if (m_permission == FileAccess.Writeable) - return true; - return false; - } - - /** - * Return the shared device that this tree connection is using. - * - * @return SharedDevice - */ - public final SharedDevice getSharedDevice() - { - return m_shareDev; - } - - /** - * Return the shared device interface - * - * @return DeviceInterface - */ - public final DeviceInterface getInterface() - { - if (m_shareDev == null) - return null; - try - { - return m_shareDev.getInterface(); - } - catch (InvalidDeviceInterfaceException ex) - { - } - return null; - } - - /** - * Check if the user has been granted the required access permission for this share. - * - * @param perm int - * @return boolean - */ - public final boolean hasPermission(int perm) - { - if (m_permission >= perm) - return true; - return false; - } - - /** - * Return the count of open files on this tree connection. - * - * @return int - */ - public final int openFileCount() - { - return m_fileCount; - } - - /** - * Remove all files from the tree connection. - */ - public final void removeAllFiles() - { - - // Check if the file array has been allocated - - if (m_files == null) - return; - - // Clear the file list - - for (int idx = 0; idx < m_files.length; m_files[idx++] = null) - ; - m_fileCount = 0; - } - - /** - * Remove a network file from the list of open files for this connection. - * - * @param idx int - * @param sess SrvSession - */ - public final void removeFile(int idx, SrvSession sess) - { - - // Range check the file index - - if (m_files == null || idx >= m_files.length) - return; - - // Make sure the files is closed - - if (m_files[idx] != null && m_files[idx].isClosed() == false) - { - - // Close the file - - try - { - - // Access the disk interface and close the file - - DiskInterface disk = (DiskInterface) m_shareDev.getInterface(); - disk.closeFile(sess, this, m_files[idx]); - m_files[idx].setClosed(true); - } - catch (Exception ex) - { - } - } - - // Remove the file and update the open file count. - - m_files[idx] = null; - m_fileCount--; - } - - /** - * Set the access permission for this share that the user has been granted. - * - * @param perm int - */ - public final void setPermission(int perm) - { - m_permission = perm; - } - - /** - * Return the tree connection as a string. - * - * @return java.lang.String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(m_shareDev.toString()); - str.append(","); - str.append(m_fileCount); - str.append(":"); - str.append(FileAccess.asString(m_permission)); - str.append("]"); - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/TreeConnectionHash.java b/source/java/org/alfresco/filesys/server/filesys/TreeConnectionHash.java deleted file mode 100644 index 02f350f2e6..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/TreeConnectionHash.java +++ /dev/null @@ -1,127 +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.server.filesys; - -import java.util.Enumeration; -import java.util.Hashtable; - -/** - * Tree Connection Hash Class - *

- * Hashtable of TreeConnections for the available disk shared devices. TreeConnections are indexed - * using the hash of the share name to allow mounts to be persistent across server restarts. - */ -public class TreeConnectionHash -{ - - // Share name hash to tree connection - - private Hashtable m_connections; - - /** - * Class constructor - */ - public TreeConnectionHash() - { - m_connections = new Hashtable(); - } - - /** - * Return the number of tree connections in the hash table - * - * @return int - */ - public final int numberOfEntries() - { - return m_connections.size(); - } - - /** - * Add a connection to the list of available connections - * - * @param tree TreeConnection - */ - public final void addConnection(TreeConnection tree) - { - m_connections.put(tree.getSharedDevice().getName().hashCode(), tree); - } - - /** - * Delete a connection from the list - * - * @param shareName String - * @return TreeConnection - */ - public final TreeConnection deleteConnection(String shareName) - { - return (TreeConnection) m_connections.get(shareName.hashCode()); - } - - /** - * Find a connection for the specified share name - * - * @param shareName String - * @return TreeConnection - */ - public final TreeConnection findConnection(String shareName) - { - - // Get the tree connection for the associated share name - - TreeConnection tree = m_connections.get(shareName.hashCode()); - - // Return the tree connection - - return tree; - } - - /** - * Find a connection for the specified share name hash code - * - * @param hashCode int - * @return TreeConnection - */ - public final TreeConnection findConnection(int hashCode) - { - - // Get the tree connection for the associated share name - - TreeConnection tree = m_connections.get(hashCode); - - // Return the tree connection - - return tree; - } - - /** - * Enumerate the connections - * - * @return Enumeration - */ - public final Enumeration enumerateConnections() - { - return m_connections.elements(); - } -} diff --git a/source/java/org/alfresco/filesys/server/filesys/UnsupportedInfoLevelException.java b/source/java/org/alfresco/filesys/server/filesys/UnsupportedInfoLevelException.java deleted file mode 100644 index dd16132165..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/UnsupportedInfoLevelException.java +++ /dev/null @@ -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.server.filesys; - -/** - *

- * This error is generated when a request is made for an information level that is not currently - * supported by the SMB server. - */ -public class UnsupportedInfoLevelException extends Exception -{ - private static final long serialVersionUID = 3762538905790395444L; - - /** - * Class constructor. - */ - public UnsupportedInfoLevelException() - { - super(); - } - - /** - * Class constructor. - * - * @param str java.lang.String - */ - public UnsupportedInfoLevelException(String str) - { - super(str); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/filesys/VolumeInfo.java b/source/java/org/alfresco/filesys/server/filesys/VolumeInfo.java deleted file mode 100644 index 528d2200ea..0000000000 --- a/source/java/org/alfresco/filesys/server/filesys/VolumeInfo.java +++ /dev/null @@ -1,177 +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.server.filesys; - -import java.util.Date; - -/** - * Disk Volume Information Class - */ -public class VolumeInfo -{ - - // Volume label - - private String m_label; - - // Serial number - - private int m_serno = -1; - - // Creation date/time - - private Date m_created; - - /** - * Default constructor - */ - public VolumeInfo() - { - } - - /** - * Class constructor - * - * @param label String - */ - public VolumeInfo(String label) - { - setVolumeLabel(label); - } - - /** - * Class constructor - * - * @param label String - * @param serno int - * @param created Date - */ - public VolumeInfo(String label, int serno, Date created) - { - setVolumeLabel(label); - setSerialNumber(serno); - setCreationDateTime(created); - } - - /** - * Return the volume label - * - * @return String - */ - public final String getVolumeLabel() - { - return m_label; - } - - /** - * Determine if the serial number is valid - * - * @return boolean - */ - public final boolean hasSerialNumber() - { - return m_serno != -1 ? true : false; - } - - /** - * Return the serial number - * - * @return int - */ - public final int getSerialNumber() - { - return m_serno; - } - - /** - * Determine if the creation date/time is valid - * - * @return boolean - */ - public final boolean hasCreationDateTime() - { - return m_created != null ? true : false; - } - - /** - * Return the volume creation date/time - * - * @return Date - */ - public final Date getCreationDateTime() - { - return m_created; - } - - /** - * Set the volume label - * - * @param label - */ - public final void setVolumeLabel(String label) - { - m_label = label; - } - - /** - * Set the serial number - * - * @param serno int - */ - public final void setSerialNumber(int serno) - { - m_serno = serno; - } - - /** - * Set the volume creation date/time - * - * @param created Date - */ - public final void setCreationDateTime(Date created) - { - m_created = created; - } - - /** - * Return the volume information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getVolumeLabel()); - str.append(","); - str.append(getSerialNumber()); - str.append(","); - str.append(getCreationDateTime()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/locking/FileLockListener.java b/source/java/org/alfresco/filesys/server/locking/FileLockListener.java deleted file mode 100644 index 1410d9f5aa..0000000000 --- a/source/java/org/alfresco/filesys/server/locking/FileLockListener.java +++ /dev/null @@ -1,65 +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.server.locking; - -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.NetworkFile; - -/** - * File Lock Listener Interface. - *

- * The file lock listener receives events when file locks are granted, released and denied. - */ -public interface FileLockListener -{ - - /** - * Lock has been granted on the specified file. - * - * @param sess SrvSession - * @param file NetworkFile - * @param lock FileLock - */ - void lockGranted(SrvSession sess, NetworkFile file, FileLock lock); - - /** - * Lock has been released on the specified file. - * - * @param sess SrvSession - * @param file NetworkFile - * @param lock FileLock - */ - void lockReleased(SrvSession sess, NetworkFile file, FileLock lock); - - /** - * Lock has been denied on the specified file. - * - * @param sess SrvSession - * @param file NetworkFile - * @param lock FileLock - */ - void lockDenied(SrvSession sess, NetworkFile file, FileLock lock); -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/locking/FileLockingInterface.java b/source/java/org/alfresco/filesys/server/locking/FileLockingInterface.java deleted file mode 100644 index 1b43b1b1e3..0000000000 --- a/source/java/org/alfresco/filesys/server/locking/FileLockingInterface.java +++ /dev/null @@ -1,46 +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.server.locking; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.TreeConnection; - -/** - * File Locking Interface - *

- * Optional interface that a DiskInterface driver can implement to provide file locking support. - */ -public interface FileLockingInterface -{ - - /** - * Return the lock manager implementation associated with this virtual filesystem - * - * @param sess SrvSession - * @param tree TreeConnection - * @return LockManager - */ - public LockManager getLockManager(SrvSession sess, TreeConnection tree); -} diff --git a/source/java/org/alfresco/filesys/server/locking/LockManager.java b/source/java/org/alfresco/filesys/server/locking/LockManager.java deleted file mode 100644 index 54bcb17018..0000000000 --- a/source/java/org/alfresco/filesys/server/locking/LockManager.java +++ /dev/null @@ -1,93 +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.server.locking; - -import java.io.IOException; - -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.locking.LockConflictException; -import org.alfresco.filesys.locking.NotLockedException; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.TreeConnection; - -/** - * Lock Manager Interface - *

- * A lock manager implementation provides file locking support for a virtual filesystem. - */ -public interface LockManager -{ - - /** - * Lock a byte range within a file, or the whole file. - * - * @param sess SrvSession - * @param tree TreeConnection - * @param file NetworkFile - * @param lock FileLock - * @exception LockConflictException - * @exception IOException - */ - public void lockFile(SrvSession sess, TreeConnection tree, NetworkFile file, FileLock lock) - throws LockConflictException, IOException; - - /** - * Unlock a byte range within a file, or the whole file - * - * @param sess SrvSession - * @param tree TreeConnection - * @param file NetworkFile - * @param lock FileLock - * @exception NotLockedException - * @exception IOException - */ - public void unlockFile(SrvSession sess, TreeConnection tree, NetworkFile file, FileLock lock) - throws NotLockedException, IOException; - - /** - * Create a lock object, allows the FileLock object to be extended - * - * @param sess SrvSession - * @param tree TreeConnection - * @param file NetworkFile - * @param offset long - * @param len long - * @param pid int - * @return FileLock - */ - public FileLock createLockObject(SrvSession sess, TreeConnection tree, NetworkFile file, long offset, long len, - int pid); - - /** - * Release all locks that a session has on a file. This method is called to perform cleanup if a - * file is closed that has active locks or if a session abnormally terminates. - * - * @param sess SrvSession - * @param tree TreeConnection - * @param file NetworkFile - */ - public void releaseLocksForFile(SrvSession sess, TreeConnection tree, NetworkFile file); -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/AuthType.java b/source/java/org/alfresco/filesys/server/oncrpc/AuthType.java deleted file mode 100644 index 61edd047e3..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/AuthType.java +++ /dev/null @@ -1,54 +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.server.oncrpc; - -/** - * Authentication Types Class - * - * @author GKSpencer - */ -public final class AuthType { - - // Authentication type contants - - public static final int Null = 0; - public static final int Unix = 1; - public static final int Short = 2; - public static final int DES = 3; - - // Authentication type strings - - private static final String[] _authTypes = { "Null", "Unix", "Short", "DES" }; - - /** - * Return the authentication type as string - * - * @param type int - * @return String - */ - public static final String getTypeAsString(int type) { - if ( type < 0 || type >= _authTypes.length) - return "" + type; - return _authTypes[type]; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/DefaultRpcAuthenticator.java b/source/java/org/alfresco/filesys/server/oncrpc/DefaultRpcAuthenticator.java deleted file mode 100644 index 9b56773180..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/DefaultRpcAuthenticator.java +++ /dev/null @@ -1,213 +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.server.oncrpc; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.config.InvalidConfigurationException; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Default RPC Authenticator Class - * - *

RPC authenticator implementation that allows any client to access the RPC servers. - * - * @author GKSpencer - */ -public class DefaultRpcAuthenticator implements RpcAuthenticator { - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.nfs.protocol.auth"); - - // Authentication types aupported by this implementation - - private int[] _authTypes = { AuthType.Null, AuthType.Unix }; - - /** - * Authenticate an RPC client and create a unique session id key. - * - * @param authType int - * @param rpc RpcPacket - * @return Object - * @throws RpcAuthenticationException - */ - public Object authenticateRpcClient(int authType, RpcPacket rpc) - throws RpcAuthenticationException { - - // Create a unique session key depending on the authentication type - - Object sessKey = null; - - switch (authType) { - - // Null authentication - - case AuthType.Null: - sessKey = new Integer(rpc.getClientAddress().hashCode()); - break; - - // Unix authentication - - case AuthType.Unix: - - // Get the gid and uid from the credentials data in the request - - rpc.positionAtCredentialsData(); - rpc.skipBytes(4); - int nameLen = rpc.unpackInt(); - rpc.skipBytes(nameLen); - - int gid = rpc.unpackInt(); - int uid = rpc.unpackInt(); - - // Check if the Unix authentication session table is valid - - sessKey = new Long((((long) rpc.getClientAddress().hashCode()) << 32) + (gid << 16) + uid); - break; - } - - // Check if the session key is valid, if not then the authentication - // type is unsupported - - if (sessKey == null) - throw new RpcAuthenticationException(Rpc.AuthBadCred, "Unsupported auth type, " + authType); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcAuth: RPC from " + rpc.getClientDetails() - + ", authType=" + AuthType.getTypeAsString(authType) - + ", sessKey=" + sessKey); - - // Return the session key - - return sessKey; - } - - /** - * Return the authentication types that are supported by this - * implementation. - * - * @return int[] - */ - public int[] getRpcAuthenticationTypes() { - return _authTypes; - } - - /** - * Return the client information for the specified RPC request - * - * @param sessKey - * Object - * @param rpc - * RpcPacket - * @return ClientInfo - */ - public ClientInfo getRpcClientInformation(Object sessKey, RpcPacket rpc) { - - // Create a client information object to hold the client details - - ClientInfo cInfo = new ClientInfo("", null); - - // Get the authentication type - - int authType = rpc.getCredentialsType(); - cInfo.setNFSAuthenticationType(authType); - - // Unpack the client details from the RPC request - - switch (authType) { - - // Null authentication - - case AuthType.Null: - cInfo.setClientAddress(rpc.getClientAddress().getHostAddress()); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcAuth: Client info, type=" + AuthType.getTypeAsString(authType) + ", addr=" - + rpc.getClientAddress().getHostAddress()); - break; - - // Unix authentication - - case AuthType.Unix: - - // Unpack the credentials data - - rpc.positionAtCredentialsData(); - rpc.skipBytes(4); // stamp id - - cInfo.setClientAddress(rpc.unpackString()); - cInfo.setUid(rpc.unpackInt()); - cInfo.setGid(rpc.unpackInt()); - - // Check for an additional groups list - - int grpLen = rpc.unpackInt(); - if (grpLen > 0) { - int[] groups = new int[grpLen]; - rpc.unpackIntArray(groups); - - cInfo.setGroupsList(groups); - } - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcAuth: Client info, type=" + AuthType.getTypeAsString(authType) + ", name=" - + cInfo.getClientAddress() + ", uid=" + cInfo.getUid() + ", gid=" + cInfo.getGid() + ", groups=" + grpLen); - break; - } - - // Return the client information - - return cInfo; - } - - /** - * Initialize the RPC authenticator - * - * @param config ServerConfiguration - * @param params NameValueList - * @throws InvalidConfigurationException - */ - public void initialize(ServerConfiguration config, ConfigElement params) - throws InvalidConfigurationException { - } - - /** - * Set the current authenticated user context for this thread - * - * @param sess SrvSession - * @param client ClientInfo - */ - public void setCurrentUser( SrvSession sess, ClientInfo client) - { - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcPacketHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcPacketHandler.java deleted file mode 100644 index da432a470c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcPacketHandler.java +++ /dev/null @@ -1,124 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -/** - * Multi-Threaded Tcp Rpc Packet Handler Class - * - *

Adds multi-threaded processing of RPC requests to the standard TCP RPC handler. - * - * @author GKSpencer - */ -public class MultiThreadedTcpRpcPacketHandler extends TcpRpcPacketHandler implements RpcPacketHandler { - - /** - * Class constructor to create a TCP RPC handler for a server. - * - * @param handler TcpRpcSessionHandler - * @param sessId int - * @param server RpcProcessor - * @param socket Socket - * @param maxRpcSize int - * @throws IOException - */ - public MultiThreadedTcpRpcPacketHandler(TcpRpcSessionHandler handler, int sessId, RpcProcessor server, - Socket socket, int maxRpcSize) throws IOException - { - super(handler, sessId, server, socket, maxRpcSize); - } - - /** - * Return the multi-threaded RPC session handler - * - * @return MultiThreadedTcpRpcSessionHandler - */ - protected final MultiThreadedTcpRpcSessionHandler getSessionHandler() - { - return (MultiThreadedTcpRpcSessionHandler) getHandler(); - } - - /** - * Allocate an RPC packet from the packet pool - * - * @param maxSize int - * @return RpcPacket - */ - protected RpcPacket allocateRpcPacket(int maxSize) - { - - // Use the session handler to allocate the RPC packet - - return getSessionHandler().allocateRpcPacket(maxSize); - } - - /** - * Deallocate an RPC packet, return the packet to the pool. - * - * @param pkt RpcPacket - */ - protected void deallocateRpcPacket(RpcPacket pkt) - { - - // Return the packet to the pool - - if (pkt.isAllocatedFromPool()) - pkt.getOwnerPacketPool().releasePacket(pkt); - } - - /** - * Process an RPC request by passing the request to a pool of worker threads. - * - * @param rpc RpcPacket - * @throws IOException - */ - protected void processRpc(RpcPacket rpc) - throws IOException - { - - // Link the RPC request to this handler - - rpc.setPacketHandler(this); - - // Queue the RPC request to the session handlers thread pool for processing - - getSessionHandler().queueRpcRequest(rpc); - } - - /** - * Send an RPC response using the TCP socket connection - * - * @param rpc RpcPacket - * @throws IOException - */ - public void sendRpcResponse(RpcPacket rpc) - throws IOException - { - - // Send the RPC response - - sendRpc(rpc); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcSessionHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcSessionHandler.java deleted file mode 100644 index 1291393e94..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedTcpRpcSessionHandler.java +++ /dev/null @@ -1,233 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -import org.alfresco.filesys.server.NetworkServer; - -/** - * Multi-threaded TCP RPC Session Handler Class - * - *

Extend the basic TCP RPC handler class to process RPC requests using a thread pool. - * - * @author GKSpencer - */ -public class MultiThreadedTcpRpcSessionHandler extends TcpRpcSessionHandler { - - // Constants - // - // Default packet pool size - - public static final int DefaultPacketPoolSize = 50; - public static final int DefaultSmallPacketSize = 512; - - // RPC packet pool - - private RpcPacketPool m_packetPool; - - // Request handler thread pool - - private RpcRequestThreadPool m_threadPool; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param rpcServer RpcProcessor - * @param server NetworkServer - * @param addr InetAddress - * @param port int - * @param maxSize int - */ - public MultiThreadedTcpRpcSessionHandler(String name, String protocol, RpcProcessor rpcServer, - NetworkServer server, InetAddress addr, int port, int maxSize) - { - super(name, protocol, rpcServer, server, addr, port, maxSize); - } - - /** - * Initialize the session socket handler - * - * @param server - * @throws IOException - */ - public void initializeSessionHandler(NetworkServer server) - throws IOException - { - - // If the packet pool has not been created, create a default packet pool - - if (m_packetPool == null) - m_packetPool = new RpcPacketPool(DefaultSmallPacketSize, DefaultPacketPoolSize, getMaximumRpcSize(), - DefaultPacketPoolSize); - - // Create the RPC request handling thread pool, if not already created - - if (m_threadPool == null) - m_threadPool = new RpcRequestThreadPool(getHandlerName(), getRpcProcessor()); - - // Call the base class initialization - - super.initializeSessionHandler(server); - } - - /** - * Allocate an RPC packet from the packet pool - * - * @param size int - * @return RpcPacket - */ - protected final RpcPacket allocateRpcPacket(int size) - { - - // Allocate an RPC packet from the packet pool - - return m_packetPool.allocatePacket(size); - } - - /** - * Queue an RPC request to the thread pool for processing - * - * @param rpc RpcPacket - */ - protected final void queueRpcRequest(RpcPacket rpc) - { - - // DEBUG - - // Debug.println("MTRpcSessHandler Queue rpc=" + rpc.toString()); - - // Queue the RPC request to the thread pool for processing - - m_threadPool.queueRpcRequest(rpc); - } - - /** - * Create a multi-threaded packet handler for the new session - * - * @param sessId int - * @param sock Socket - * @return TcpRpcPacketHandler - * @throws IOException - */ - protected TcpRpcPacketHandler createPacketHandler(int sessId, Socket sock) - throws IOException - { - - // Create a multi-threaded packet handler to use the session handlers thread pool to - // process the RPC requests - - return new MultiThreadedTcpRpcPacketHandler(this, sessId, getRpcProcessor(), sock, getMaximumRpcSize()); - } - - /** - * Set the packet pool size - * - * @param smallSize int - * @param smallPool int - * @param largeSize int - * @param largePool int - */ - public final void setPacketPool(int smallSize, int smallPool, int largeSize, int largePool) - { - - // Create the packet pool, if not already initialized - - if (m_packetPool == null) - { - - // Create the packet pool - - m_packetPool = new RpcPacketPool(smallSize, smallPool, largeSize, largePool); - } - } - - /** - * Set the packet pool size - * - * @param poolSize int - */ - public final void setPacketPool(int poolSize) - { - - // Create the packet pool, if not already initialized - - if (m_packetPool == null) - { - - // Create the packet pool - - m_packetPool = new RpcPacketPool(DefaultSmallPacketSize, poolSize, getMaximumRpcSize(), poolSize); - } - } - - /** - * Set the packet pool - * - * @param pktPool RpcPacketPool - */ - public final void setPacketPool(RpcPacketPool pktPool) - { - - // Set the packet pool, if not already initialized - - if (m_packetPool == null) - m_packetPool = pktPool; - } - - /** - * Set the thread pool size - * - * @param numThreads int - */ - public final void setThreadPool(int numThreads) - { - - // Create the thread pool, if not already initialized - - if (m_threadPool == null) - { - - // Create the thread pool - - m_threadPool = new RpcRequestThreadPool(getHandlerName(), numThreads, getRpcProcessor()); - } - } - - /** - * Set the thread pool - * - * @param threadPool RpcRequestThreadPool - */ - public final void setThreadPool(RpcRequestThreadPool threadPool) - { - - // Set the thread pool, if not already initialized - - if (m_threadPool == null) - m_threadPool = threadPool; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedUdpRpcDatagramHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedUdpRpcDatagramHandler.java deleted file mode 100644 index 607deb0b8e..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/MultiThreadedUdpRpcDatagramHandler.java +++ /dev/null @@ -1,426 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -import org.alfresco.filesys.server.NetworkServer; - -/** - * Multi-Threaded UDP RPC Datagram Handler Class - * - *

Extend the basic UDP RPC handler class to process RPC requests using a thread pool. - * - * @author GKSpencer - */ -public class MultiThreadedUdpRpcDatagramHandler extends UdpRpcDatagramHandler implements RpcPacketHandler { - - // Constants - // - // Default packet pool size - - public static final int DefaultPacketPoolSize = 50; - public static final int DefaultSmallPacketSize = 512; - - // RPC packet pool - - private RpcPacketPool m_packetPool; - - // Request handler thread pool - - private RpcRequestThreadPool m_threadPool; - - // RPC response queue - - private RpcRequestQueue m_txQueue; - - // Datagram sender thread - - private DatagramSender m_txThread; - - // Current receive RPC packet - - private RpcPacket m_rxPkt; - - /** - * Datagram Sender Thread Inner Class - */ - protected class DatagramSender implements Runnable - { - - // Worker thread - - private Thread mi_thread; - - // RPC sender thread datagram packet - - private DatagramPacket mi_txPkt; - - // Shutdown flag - - private boolean mi_shutdown = false; - - /** - * Class constructor - * - * @param name String - */ - public DatagramSender(String name) - { - - // Create the worker thread - - mi_thread = new Thread(this); - mi_thread.setName(name); - mi_thread.setDaemon(true); - mi_thread.start(); - } - - /** - * Request the worker thread to shutdown - */ - public final void shutdownRequest() - { - mi_shutdown = true; - try - { - mi_thread.interrupt(); - } catch (Exception ex) - { - } - } - - /** - * Run the thread - */ - public void run() - { - - // Allocate the datagram packet for sending the RPC responses - - mi_txPkt = new DatagramPacket(new byte[4], 4); - - // Loop until shutdown - - RpcPacket rpc = null; - - while (mi_shutdown == false) - { - - try - { - - // Wait for an RPC response to be queued - - rpc = m_txQueue.removeRequest(); - } catch (InterruptedException ex) - { - - // Check for shutdown - - if (mi_shutdown == true) - break; - } - - // If the request is valid process it - - if (rpc != null) - { - - try - { - - // Initialize the datagram packet for this response - - mi_txPkt.setAddress(rpc.getClientAddress()); - mi_txPkt.setPort(rpc.getClientPort()); - mi_txPkt.setData(rpc.getBuffer(), rpc.getOffset(), rpc.getLength()); - - // Send the RPC response - - getDatagramSocket().send(mi_txPkt); - } catch (Throwable ex) - { - - // Do not display errors if shutting down - - if (mi_shutdown == false) - { - logger.debug("DatagramSender " + Thread.currentThread().getName() + ":"); - logger.debug(ex); - } - } finally - { - - // Release the RPC packet back to the packet pool - - if (rpc.isAllocatedFromPool()) - rpc.getOwnerPacketPool().releasePacket(rpc); - } - } - } - } - }; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param rpcServer RpcProcessor - * @param server NetworkServer - * @param addr InetAddress - * @param port int - * @param maxSize int - */ - public MultiThreadedUdpRpcDatagramHandler(String name, String protocol, RpcProcessor rpcServer, - NetworkServer server, InetAddress addr, int port, int maxSize) - { - super(name, protocol, rpcServer, server, addr, port, maxSize); - } - - /** - * Initialize the session handler - * - * @param server NetworkServer - * @throws IOException - */ - public void initializeSessionHandler(NetworkServer server) - throws IOException - { - - // Create the RPC response queue - - m_txQueue = new RpcRequestQueue(); - - // Create the datagram sender thread - - m_txThread = new DatagramSender("UDP_Tx_" + getProtocolName()); - - // If the packet pool has not been created, create a default packet pool - - if (m_packetPool == null) - m_packetPool = new RpcPacketPool(DefaultSmallPacketSize, DefaultPacketPoolSize, getMaximumDatagramSize(), - DefaultPacketPoolSize); - - // Create the RPC request handling thread pool, if not already created - - if (m_threadPool == null) - m_threadPool = new RpcRequestThreadPool(getHandlerName(), getRpcProcessor()); - - // Call the base class initialization - - super.initializeSessionHandler(server); - } - - /** - * Process the RPC request - * - * @param pkt DatagramPacket - * @return boolean - * @throws IOException - */ - protected boolean processDatagram(DatagramPacket pkt) - throws IOException - { - - // Make sure that the received data is using the same buffer that we allocated in the - // allocateBuffer() method, if not the buffer did not come from the packet pool. - - if (pkt.getData() != m_rxPkt.getBuffer()) - throw new IOException("Received datagram is not in expected buffer"); - - // Update the RPC packet details - - m_rxPkt.setBuffer(pkt.getData(), 0, pkt.getLength()); - - // Set the client details - - m_rxPkt.setClientDetails(pkt.getAddress(), pkt.getPort(), Rpc.UDP); - - // Set the packet handler interface to be used to send the RPC reply - - m_rxPkt.setPacketHandler(this); - - // Queue the request to the thread pool for processing - - queueRpcRequest(m_rxPkt); - - // Indicate that the datagram buffer cannot be re-used, the main datagram receiving thread must - // allocate a new buffer for the next request. - - return false; - } - - /** - * Queue an RPC request to the thread pool for processing - * - * @param rpc RpcPacket - */ - protected final void queueRpcRequest(RpcPacket rpc) - { - - // Queue the RPC request to the thread pool for processing - - m_threadPool.queueRpcRequest(rpc); - } - - /** - * Allocate a buffer for the next datagram - * - * @param bufSize int - * @return byte[] - */ - protected byte[] allocateBuffer(int bufSize) - { - - // Allocate an RPC packet from the packet pool - - m_rxPkt = m_packetPool.allocatePacket(bufSize); - - // Return the buffer from the RPC packet - - return m_rxPkt.getBuffer(); - } - - /** - * Send an RPC response using the datagram socket - * - * @param rpc RpcPacket - * @throws IOException - */ - public void sendRpcResponse(RpcPacket rpc) - throws IOException - { - - // Queue the RPC response to the datagram sender thread - - m_txQueue.addRequest(rpc); - } - - /** - * Set the packet pool size - * - * @param smallSize int - * @param smallPool int - * @param largeSize int - * @param largePool int - */ - public final void setPacketPool(int smallSize, int smallPool, int largeSize, int largePool) - { - - // Create the packet pool, if not already initialized - - if (m_packetPool == null) - { - - // Create the packet pool - - m_packetPool = new RpcPacketPool(smallSize, smallPool, largeSize, largePool); - } - } - - /** - * Set the packet pool size - * - * @param poolSize int - */ - public final void setPacketPool(int poolSize) - { - - // Create the packet pool, if not already initialized - - if (m_packetPool == null) - { - - // Create the packet pool - - m_packetPool = new RpcPacketPool(DefaultSmallPacketSize, poolSize, getMaximumDatagramSize(), poolSize); - } - } - - /** - * Set the packet pool - * - * @param pktPool RpcPacketPool - */ - public final void setPacketPool(RpcPacketPool pktPool) - { - - // Set the packet pool, if not already initialized - - if (m_packetPool == null) - m_packetPool = pktPool; - } - - /** - * Set the thread pool size - * - * @param numThreads int - */ - public final void setThreadPool(int numThreads) - { - - // Create the thread pool, if not already initialized - - if (m_threadPool == null) - { - - // Create the thread pool - - m_threadPool = new RpcRequestThreadPool(getHandlerName(), numThreads, getRpcProcessor()); - } - } - - /** - * Set the thread pool - * - * @param threadPool RpcRequestThreadPool - */ - public final void setThreadPool(RpcRequestThreadPool threadPool) - { - - // Set the thread pool, if not already initialized - - if (m_threadPool == null) - m_threadPool = threadPool; - } - - /** - * Close the session handler - * - * @param server NetworkServer - */ - public void closeSessionHandler(NetworkServer server) - { - - // Shutdown the datagram sender thread - - m_txThread.shutdownRequest(); - - // Call the base class - - super.closeSessionHandler(server); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/PortMapping.java b/source/java/org/alfresco/filesys/server/oncrpc/PortMapping.java deleted file mode 100644 index 34bd8f989f..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/PortMapping.java +++ /dev/null @@ -1,151 +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.server.oncrpc; - -/** - * Port Details Class - * - *

Contains the details of an RPC service registered with the PortMapper service. - * - * @author GKSpencer - */ -public class PortMapping { - - // Program id and version - - private int m_programId; - private int m_versionId; - - // Protocol type (UDP or TCP) - - private int m_protocol; - - // Port - - private int m_port; - - /** - * Class constructor - * - * @param progId int - * @param verId int - * @param protocol int - * @param port int - */ - public PortMapping(int progId, int verId, int protocol, int port) - { - m_programId = progId; - m_versionId = verId; - m_protocol = protocol; - m_port = port; - } - - /** - * Return the program id - * - * @return int - */ - public final int getProgramId() - { - return m_programId; - } - - /** - * Return the version id - * - * @return int - */ - public final int getVersionId() - { - return m_versionId; - } - - /** - * Return the protocol type - * - * @return int - */ - public final int getProtocol() - { - return m_protocol; - } - - /** - * Return the port number - * - * @return int - */ - public final int getPort() - { - return m_port; - } - - /** - * Return a hash code for the port mapping - * - * @return int - */ - public int hashCode() - { - - // Create a hash code from the program id + version + protocol - - return generateHashCode(m_programId, m_versionId, m_protocol); - } - - /** - * Generate a hash code for the specified program, version and protocol - * - * @param progId int - * @param verId int - * @param proto int - * @return int - */ - public final static int generateHashCode(int progId, int verId, int proto) - { - - // Create a hash code from the program id + version + protocol - - return (progId << 16) + (verId << 8) + proto; - } - - /** - * Return the port details as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(64); - - str.append("["); - str.append(getProgramId()); - str.append(":"); - str.append(getVersionId()); - str.append(getProtocol() == Rpc.TCP ? ",TCP," : ",UDP,"); - str.append(getPort()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/Rpc.java b/source/java/org/alfresco/filesys/server/oncrpc/Rpc.java deleted file mode 100644 index 1ce4c48c6c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/Rpc.java +++ /dev/null @@ -1,110 +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.server.oncrpc; - -/** - * ONC/RPC Constants Class - * - * @author GKSpencer - */ -public class Rpc { - - // RPC length/flags - - public static final int LastFragment = 0x80000000; - public static final int LengthMask = 0x7FFFFFFF; - - // RPC message types - - public static final int Call = 0; - public static final int Reply = 1; - - // Call status - - public static final int CallAccepted = 0; - public static final int CallDenied = 1; - - // Required RPC version - - public static final int RpcVersion = 2; - - // Call accepted status codes - - public static final int StsSuccess = 0; // RPC executed successfully - public static final int StsProgUnavail = 1; // program not available - public static final int StsProgMismatch = 2; // program version mismatch - public static final int StsProcUnavail = 3; // program does not support procedure - public static final int StsBadArgs = 4; // bad arguments in request - - // Call rejected status codes - - public static final int StsRpcMismatch = 0; // RPC version number does not equal 2 - public static final int StsAuthError = 1; // authentication error - - // Authentication failure status codes - - public static final int AuthBadCred = 1; // bad credentials - public static final int AuthRejectCred = 2; // client must begin new session - public static final int AuthBadVerf = 3; // bad verifier - public static final int AuthRejectedVerf = 4; // verifier rejected or replayed - public static final int AuthTooWeak = 5; // rejected for security reasons - - // True/false values - - public static final int True = 1; - public static final int False = 0; - - // Protocol ids - - public static final int TCP = 6; - public static final int UDP = 17; - - /** - * Return a program id as a service name - * - * @param progId int - * @return String - */ - public final static String getServiceName(int progId) - { - String svcName = null; - - switch (progId) - { - case 100005: - svcName = "Mount"; - break; - case 100003: - svcName = "NFS"; - break; - case 100000: - svcName = "Portmap"; - break; - default: - svcName = "" + progId; - break; - } - - return svcName; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticationException.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticationException.java deleted file mode 100644 index 9fb10d3ed7..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticationException.java +++ /dev/null @@ -1,71 +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.server.oncrpc; - -/** - * RPC Authentication Exception Class - * - * @author GKSpencer - */ -public class RpcAuthenticationException extends Exception { - - // Object version id - - private static final long serialVersionUID = 7599358351809146330L; - - // Authentication failure error code - - private int m_authError; - - /** - * Class constructor - * - * @param authError int - */ - public RpcAuthenticationException(int authError) - { - m_authError = authError; - } - - /** - * Class constructor - * - * @param authError int - * @param msg String - */ - public RpcAuthenticationException(int authError, String msg) - { - super(msg); - m_authError = authError; - } - - /** - * Get the authentication error code - * - * @return int - */ - public final int getAuthenticationErrorCode() - { - return m_authError; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticator.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticator.java deleted file mode 100644 index 6417f42213..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcAuthenticator.java +++ /dev/null @@ -1,92 +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.server.oncrpc; - -import org.alfresco.config.ConfigElement; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.config.InvalidConfigurationException; -import org.alfresco.filesys.server.config.ServerConfiguration; - -/** - * RPC Authenticator Interface - * - *

Provides authentication support for ONC/RPC requests. - * - * @author GKSpencer - */ -public interface RpcAuthenticator -{ - /** - * Initialize the RPC authenticator - * - * @param config ServerConfiguration - * @param params NameValueList - * @exception InvalidConfigurationException - */ - public void initialize(ServerConfiguration config, ConfigElement params) - throws InvalidConfigurationException; - - /** - * Authenticate an RPC client using the credentials within the RPC request. - * The object that is returned is used as the key to find the associated - * session object. - * - * @param authType int - * @param rpc RpcPacket - * @return Object - * @exception RpcAuthenticationException - */ - public Object authenticateRpcClient(int authType, RpcPacket rpc) - throws RpcAuthenticationException; - - /** - * Get RPC client information from the RPC request. - * - *

- * This method is called when a new session object is created by an RPC - * server. - * - * @param sessKey Object - * @param rpc RpcPacket - * @return ClientInfo - */ - public ClientInfo getRpcClientInformation(Object sessKey, RpcPacket rpc); - - /** - * Return a list of the authentication types that the RPC authenticator - * implementation supports. The authentication types are specified in the - * AuthType class. - * - * @return int[] - */ - public int[] getRpcAuthenticationTypes(); - - /** - * Set the current authenticated user context for this thread - * - * @param sess SrvSession - * @param client ClientInfo - */ - public void setCurrentUser( SrvSession sess, ClientInfo client); -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcClient.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcClient.java deleted file mode 100644 index e0ea4c543b..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcClient.java +++ /dev/null @@ -1,152 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -/** - * RPC Client Class - * - *

Provides either a socket or datagram connection to an RPC server. - * - * @author GKSpencer - */ -public abstract class RpcClient { - - // Network address and port to connect to on the remote RPC server - - private InetAddress m_server; - private int m_port; - - // Protocol type - - private int m_protocol; - - // Maximum RPC size to send/receive - - private int m_maxRpcSize; - - /** - * Class constructor - * - * @param addr InetAddress - * @param port int - * @param proto int - * @param maxRpcSize int - * @throws IOException - * @throws SocketException - */ - protected RpcClient(InetAddress addr, int port, int proto, int maxRpcSize) throws IOException, SocketException - { - - // Save the server address, port and the protocol type - - m_server = addr; - m_port = port; - - m_protocol = proto; - - // Set the maximum RPC size to send/recieve - - m_maxRpcSize = maxRpcSize; - } - - /** - * Return the maximum RPC size - * - * @return int - */ - public final int getMaximumRpcSize() - { - return m_maxRpcSize; - } - - /** - * Return the server address - * - * @return InetAddress - */ - public final InetAddress getServerAddress() - { - return m_server; - } - - /** - * Return the server port - * - * @return int - */ - public final int getServerPort() - { - return m_port; - } - - /** - * Return the protocol type - * - * @return int - */ - public final int isProtocol() - { - return m_protocol; - } - - /** - * Send an RPC request to the server - * - * @param rpc RpcPacket - * @param rxRpc RpcPacket - * @return RpcPacket - * @throws IOException - */ - public abstract RpcPacket sendRPC(RpcPacket rpc, RpcPacket rxRpc) - throws IOException; - - /** - * Close the connection to the remote RPC server - */ - public abstract void closeConnection(); - - /** - * Return the RPC connection details as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(isProtocol() == Rpc.TCP ? "TCP:" : "UDP:"); - str.append(getServerAddress().getHostAddress()); - str.append(":"); - str.append(getServerPort()); - - str.append(","); - str.append(getMaximumRpcSize()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcNetworkServer.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcNetworkServer.java deleted file mode 100644 index d35f274a43..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcNetworkServer.java +++ /dev/null @@ -1,209 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.oncrpc.portmap.PortMapper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * RPC Network Server Abstract Class - * - *

Provides the base class for RPC servers (such as mount and NFS). - * - * @author GKSpencer - */ -public abstract class RpcNetworkServer extends NetworkServer implements RpcProcessor { - - // Debug logging - - protected static final Log logger = LogFactory.getLog("org.alfresco.nfs.protocol"); - - /** - * Class constructor - * - * @param name String - * @param config ServerConfiguration - */ - public RpcNetworkServer(String name, ServerConfiguration config) - { - super(name, config); - } - - /** - * Register a port/protocol for the RPC server - * - * @param mapping PortMapping - * @throws IOException - */ - protected final void registerRPCServer(PortMapping mapping) - throws IOException - { - - // Call the main registration method - - PortMapping[] mappings = new PortMapping[1]; - mappings[0] = mapping; - - registerRPCServer(mappings); - } - - /** - * Register a set of ports/protocols for the RPC server - * - * @param mappings PortMapping[] - * @throws IOException - */ - protected final void registerRPCServer(PortMapping[] mappings) - throws IOException - { - - // Connect to the local portmapper service to register the RPC service - - InetAddress localHost = InetAddress.getByName("127.0.0.1"); - - TcpRpcClient rpcClient = new TcpRpcClient(localHost, PortMapper.DefaultPort, 512); - - // Allocate RPC request and response packets - - RpcPacket setPortRpc = new RpcPacket(512); - RpcPacket rxRpc = new RpcPacket(512); - - // Loop through the port mappings and register each port with the portmapper service - - for (int i = 0; i < mappings.length; i++) - { - - // Build the RPC request header - - setPortRpc.buildRequestHeader(PortMapper.ProgramId, PortMapper.VersionId, PortMapper.ProcSet, 0, null, 0, - null); - - // Pack the request parameters and set the request length - - setPortRpc.packPortMapping(mappings[i]); - setPortRpc.setLength(); - - // Send the RPC request and receive a response - - rxRpc = rpcClient.sendRPC(setPortRpc, rxRpc); - } - } - - /** - * Unregister a port/protocol for the RPC server - * - * @param mapping PortMapping - * @throws IOException - */ - protected final void unregisterRPCServer(PortMapping mapping) - throws IOException - { - - // Call the main unregister ports method - - PortMapping[] mappings = new PortMapping[1]; - mappings[0] = mapping; - - unregisterRPCServer(mappings); - } - - /** - * Unregister a set of ports/protocols for the RPC server - * - * @param mappings PortMapping[] - * @throws IOException - */ - protected final void unregisterRPCServer(PortMapping[] mappings) - throws IOException - { - - // Connect to the local portmapper service to unregister the RPC service - - InetAddress localHost = InetAddress.getByName("127.0.0.1"); - - TcpRpcClient rpcClient = new TcpRpcClient(localHost, PortMapper.DefaultPort, 512); - - // Allocate RPC request and response packets - - RpcPacket setPortRpc = new RpcPacket(512); - RpcPacket rxRpc = new RpcPacket(512); - - // Loop through the port mappings and unregister each port with the portmapper service - - for (int i = 0; i < mappings.length; i++) - { - - // Build the RPC request header - - setPortRpc.buildRequestHeader(PortMapper.ProgramId, PortMapper.VersionId, PortMapper.ProcUnSet, 0, null, 0, - null); - - // Pack the request parameters and set the request length - - setPortRpc.packPortMapping(mappings[i]); - setPortRpc.setLength(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] UnRegister server RPC " + setPortRpc.toString()); - - // Send the RPC request and receive a response - - rxRpc = rpcClient.sendRPC(setPortRpc, rxRpc); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] UnRegister response " + rxRpc.toString()); - } - } - - /** - * Start the RPC server - */ - public abstract void startServer(); - - /** - * Shutdown the RPC server - * - * @param immediate boolean - */ - public abstract void shutdownServer(boolean immediate); - - /** - * Process an RPC request - * - * @param rpc RpcPacket - * @return RpcPacket - * @throws IOException - */ - public abstract RpcPacket processRpc(RpcPacket rpc) - throws IOException; -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacket.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcPacket.java deleted file mode 100644 index a58c1e9005..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacket.java +++ /dev/null @@ -1,1325 +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.server.oncrpc; - -import java.net.*; - -import org.alfresco.filesys.util.DataPacker; - -/** - * ONC/RPC Request/Response Packet Class - * - * @author GKSpencer - */ -public class RpcPacket { - - // Constants - // - // Default buffer size to allocate - - private static final int DefaultBufferSize = 8192; - - // Fragment header length - - public static final int FragHeaderLen = 4; - - // Fixed packet lengths - - public static final int ResponseMismatchLen = 24; - public static final int ResponseAuthFailLen = 20; - - // RPC data buffer - - private byte[] m_buffer; - private int m_offset; - - // Current buffer pack/unpack position and end of buffer position - - private int m_pos; - private int m_endPos; - - // Callers address, port and protocol - - private InetAddress m_clientAddr; - private int m_clientPort; - private int m_protocol; - - // RPC packet handler interface used to send an RPC response - - private RpcPacketHandler m_pktHandler; - - // Packet pool that owns this packet, if allocated from a pool - - private RpcPacketPool m_ownerPool; - - /** - * Default constructor - */ - public RpcPacket() - { - // Allocate the RPC buffer - - m_buffer = new byte[DefaultBufferSize]; - m_offset = FragHeaderLen; - - m_pos = FragHeaderLen; - m_endPos = m_buffer.length; - } - - /** - * Class constructor - * - * @param len int - */ - public RpcPacket(int len) - { - // Allocate the RPC buffer - - m_buffer = new byte[len + FragHeaderLen]; - m_offset = FragHeaderLen; - - m_pos = FragHeaderLen; - m_endPos = m_buffer.length; - } - - /** - * Class constructor - * - * @param len int - * @param owner RpcPacketPool - */ - protected RpcPacket(int len, RpcPacketPool owner) - { - this(len); - - // Set the owner - - setOwnerPacketPool(owner); - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public RpcPacket(byte[] buf) - { - m_buffer = buf; - m_offset = FragHeaderLen; - m_pos = FragHeaderLen; - m_endPos = buf.length; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public RpcPacket(byte[] buf, int offset, int len) - { - m_buffer = buf; - m_offset = offset; - m_pos = offset; - m_endPos = offset + len; - } - - /** - * Determine if the packet handler is valid - * - * @return boolean - */ - public final boolean hasPacketHandler() - { - return m_pktHandler != null ? true : false; - } - - /** - * Return the packet handler interface used to send/receive a packet - * - * @return RpcPacketHandler - */ - public final RpcPacketHandler getPacketHandler() - { - return m_pktHandler; - } - - /** - * Detemrine if the packet is allocated from a packet pool - * - * @return boolean - */ - public final boolean isAllocatedFromPool() - { - return m_ownerPool != null ? true : false; - } - - /** - * Return the packet pool that owns this packet - * - * @return RpcPacketPool - */ - public final RpcPacketPool getOwnerPacketPool() - { - return m_ownerPool; - } - - /** - * Determine if the client address has been set - * - * @return boolean - */ - public final boolean hasClientAddress() - { - return m_clientAddr != null ? true : false; - } - - /** - * Return the client network address - * - * @return InetAddress - */ - public final InetAddress getClientAddress() - { - return m_clientAddr; - } - - /** - * Return the client port - * - * @return int - */ - public final int getClientPort() - { - return m_clientPort; - } - - /** - * Return the client protocol - * - * @return int - */ - public final int getClientProtocol() - { - return m_protocol; - } - - /** - * Return the client details as a string - * - * @return String - */ - public final String getClientDetails() - { - if (hasClientAddress() == false) - return ""; - - StringBuffer str = new StringBuffer(32); - str.append(getClientProtocol() == Rpc.TCP ? "T" : "U"); - str.append(getClientAddress().getHostAddress()); - str.append(":"); - str.append(getClientPort()); - - return str.toString(); - } - - /** - * Return the current buffer position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Return the buffer - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_buffer; - } - - /** - * Return the available buffer size - * - * @return int - */ - public final int getAvailableLength() - { - return m_buffer.length - m_pos; - } - - /** - * Return the used buffer length - * - * @return int - */ - public final int getLength() - { - return m_endPos - m_offset; - } - - /** - * Return the RPC + fragment header length - * - * @return int - */ - public final int getTxLength() - { - if (m_offset == 0) - return m_endPos; - else - return (m_endPos - m_offset) + FragHeaderLen; - } - - /** - * Return the start of data offset - * - * @return int - */ - public final int getOffset() - { - return m_offset; - } - - /** - * Return the message type - * - * @return int - */ - public final int getMessageType() - { - return DataPacker.getInt(m_buffer, m_offset + 4); - } - - /** - * Return the RPC version - * - * @return int - */ - public final int getRpcVersion() - { - return DataPacker.getInt(m_buffer, m_offset + 8); - } - - /** - * Return the program id - * - * @return int - */ - public final int getProgramId() - { - return DataPacker.getInt(m_buffer, m_offset + 12); - } - - /** - * Return the program version - * - * @return int - */ - public final int getProgramVersion() - { - return DataPacker.getInt(m_buffer, m_offset + 16); - } - - /** - * Return the procedure id - * - * @return int - */ - public final int getProcedureId() - { - return DataPacker.getInt(m_buffer, m_offset + 20); - } - - /** - * Return the credentials type - * - * @return int - */ - public final int getCredentialsType() - { - return DataPacker.getInt(m_buffer, m_offset + 24); - } - - /** - * Return the credentials length - * - * @return int - */ - public final int getCredentialsLength() - { - return DataPacker.getInt(m_buffer, m_offset + 28); - } - - /** - * Return the verifier type - * - * @return int - */ - public final int getVerifierType() - { - return DataPacker.getInt(m_buffer, m_offset + getCredentialsLength() + 32); - } - - /** - * Return the verifier length - * - * @return int - */ - public final int getVerifierLength() - { - return DataPacker.getInt(m_buffer, m_offset + getCredentialsLength() + 36); - } - - /** - * Return the buffer offset to the verifier - * - * @return int - */ - public final int getVerifierOffset() - { - return m_offset + getCredentialsLength() + 40; - } - - /** - * Return the procedure specific parameters offset - * - * @return int - */ - public final int getProcedureParameterOffset() - { - return m_offset + getCredentialsLength() + getVerifierLength() + 40; - } - - /** - * Return the procedure parameters length - * - * @return int - */ - public final int getProcedureParameterLength() - { - return m_endPos - getProcedureParameterOffset(); - } - - /** - * Return the XID - * - * @return int - */ - public final int getXID() - { - return DataPacker.getInt(m_buffer, m_offset); - } - - /** - * Check if the response has a success status - * - * @return boolean - */ - public final boolean hasSuccessStatus() - { - return getAcceptStatus() == Rpc.StsSuccess ? true : false; - } - - /** - * Return the reply state - * - * @return int - */ - public final int getReplyState() - { - return DataPacker.getInt(m_buffer, 8); - } - - /** - * Return the reject reply status - * - * @return int - */ - public final int getRejectStatus() - { - return DataPacker.getInt(m_buffer, 12); - } - - /** - * Return the version mismatch low version - * - * @return int - */ - public final int getMismatchVersionLow() - { - return DataPacker.getInt(m_buffer, 16); - } - - /** - * Return the version mismatch high version - * - * @return int - */ - public final int getMismatchVersionHigh() - { - return DataPacker.getInt(m_buffer, 20); - } - - /** - * Return the authentication failure status - * - * @return int - */ - public final int getAuthFailStatus() - { - return DataPacker.getInt(m_buffer, 16); - } - - /** - * Return the accept status for the RPC response - * - * @return int - */ - public final int getAcceptStatus() - { - int pos = DataPacker.getInt(m_buffer, 16) + 20; - return DataPacker.getInt(m_buffer, pos); - } - - /** - * Align the buffer position on a longword/32bit boundary - * - * @param ival - */ - protected final void alignPosition() - { - - // Align the buffer position on the required boundary - - m_pos = (m_pos + 3) & 0xFFFFFFFC; - } - - /** - * Pack a byte value - * - * @param bval int - */ - public final void packByte(int bval) - { - m_buffer[m_pos++] = (byte) (bval & 0xFF); - } - - /** - * Pack nulls - * - * @param len int - */ - public final void packNulls(int len) - { - for (int i = 0; i < len; i++) - m_buffer[m_pos++] = (byte) 0; - } - - /** - * Pack an integer value - * - * @param ival int - */ - public final void packInt(int ival) - { - DataPacker.putInt(ival, m_buffer, m_pos); - m_pos += 4; - } - - /** - * Pack a long value - * - * @param lval long - */ - public final void packLong(long lval) - { - DataPacker.putLong(lval, m_buffer, m_pos); - m_pos += 8; - } - - /** - * Pack a byte array with a length - * - * @param buf byte[] - */ - public final void packByteArrayWithLength(byte[] buf) - { - DataPacker.putInt(buf.length, m_buffer, m_pos); - m_pos += 4; - System.arraycopy(buf, 0, m_buffer, m_pos, buf.length); - m_pos += buf.length; - alignPosition(); - } - - /** - * Pack a byte array - * - * @param buf byte[] - */ - public final void packByteArray(byte[] buf) - { - System.arraycopy(buf, 0, m_buffer, m_pos, buf.length); - m_pos += buf.length; - alignPosition(); - } - - /** - * Pack an integer array - * - * @param iarray int[] - */ - public final void packIntArrayWithLength(int[] iarray) - { - DataPacker.putInt(iarray.length, m_buffer, m_pos); - m_pos += 4; - for (int i = 0; i < iarray.length; i++) - { - DataPacker.putInt(iarray[i], m_buffer, m_pos); - m_pos += 4; - } - } - - /** - * Pack a string - * - * @param str String - */ - public final void packString(String str) - { - DataPacker.putInt(str != null ? str.length() : 0, m_buffer, m_pos); - m_pos += 4; - if (str != null) - { - m_pos = DataPacker.putString(str, m_buffer, m_pos, false); - alignPosition(); - } - } - - /** - * Pack a port mapping structure - * - * @param portMap PortMapping - */ - public final void packPortMapping(PortMapping portMap) - { - DataPacker.putInt(portMap.getProgramId(), m_buffer, m_pos); - DataPacker.putInt(portMap.getVersionId(), m_buffer, m_pos + 4); - DataPacker.putInt(portMap.getProtocol(), m_buffer, m_pos + 8); - DataPacker.putInt(portMap.getPort(), m_buffer, m_pos + 12); - - m_pos += 16; - } - - /** - * Unpack an integer value - * - * @return int - */ - public final int unpackInt() - { - int val = DataPacker.getInt(m_buffer, m_pos); - m_pos += 4; - return val; - } - - /** - * Unpack a long value - * - * @return long - */ - public final long unpackLong() - { - long val = DataPacker.getLong(m_buffer, m_pos); - m_pos += 8; - return val; - } - - /** - * Unpack a string - * - * @return String - */ - public final String unpackString() - { - int len = unpackInt(); - - String str = ""; - if (len > 0) - { - str = DataPacker.getString(m_buffer, m_pos, len); - m_pos += len; - alignPosition(); - } - - return str; - } - - /** - * Unpack a byte array with a length - * - * @param buf byte[] - */ - public final void unpackByteArrayWithLength(byte[] buf) - { - int len = DataPacker.getInt(m_buffer, m_pos); - m_pos += 4; - if (len > 0) - { - System.arraycopy(m_buffer, m_pos, buf, 0, len); - m_pos += len; - } - alignPosition(); - } - - /** - * Unpack a byte array, using the buffer length - * - * @param buf byte[] - */ - public final void unpackByteArray(byte[] buf) - { - System.arraycopy(m_buffer, m_pos, buf, 0, buf.length); - m_pos += buf.length; - alignPosition(); - } - - /** - * Unpack an integer array, using the buffer length - * - * @param buf int[] - */ - public final void unpackIntArray(int[] buf) - { - for (int i = 0; i < buf.length; i++) - buf[i] = unpackInt(); - } - - /** - * Position the read pointer at the credentials data - */ - public final void positionAtCredentialsData() - { - m_pos = m_offset + 32; - } - - /** - * Position the read pointer at the verifier data - */ - public final void positionAtVerifierData() - { - m_pos = getVerifierOffset(); - } - - /** - * Position the read pointer at the procedure specific parameters - */ - public final void positionAtParameters() - { - m_pos = getProcedureParameterOffset(); - } - - /** - * Skip a number of bytes in the buffer, rounded to the next int boundary - * - * @param cnt int - */ - public final void skipBytes(int cnt) - { - m_pos += (cnt + 3) & 0xFFFC; - } - - /** - * Set the client details - * - * @param addr InetAddress - * @param port int - * @param protocol int - */ - public final void setClientDetails(InetAddress addr, int port, int protocol) - { - m_clientAddr = addr; - m_clientPort = port; - m_protocol = protocol; - } - - /** - * Reset the buffer details - * - * @param buf byte[] - * @param offset int - * @param len int - */ - public final void setBuffer(byte[] buf, int offset, int len) - { - m_buffer = buf; - m_offset = offset; - m_pos = offset; - m_endPos = offset + len; - } - - /** - * Reset the buffer details - * - * @param offset int - * @param len int - */ - public final void setBuffer(int offset, int len) - { - m_offset = offset; - m_pos = offset; - m_endPos = offset + len; - } - - /** - * Set the used buffer length - * - * @param len int - */ - public final void setLength(int len) - { - m_endPos = len + m_offset; - - // Set the fragment header, if the offset is non-zero - - if (m_offset == FragHeaderLen) - DataPacker.putInt(getLength() + Rpc.LastFragment, m_buffer, 0); - } - - /** - * Set the used buffer length - */ - public final void setLength() - { - m_endPos = m_pos; - - // Set the fragment header, if the offset is non-zero - - if (m_offset == FragHeaderLen) - DataPacker.putInt(getLength() + Rpc.LastFragment, m_buffer, 0); - } - - /** - * Set the buffer position - * - * @param pos int - */ - public final void setPosition(int pos) - { - m_pos = pos; - } - - /** - * Set the message type - * - * @param msgType int - */ - public final void setMessageType(int msgType) - { - DataPacker.putInt(msgType, m_buffer, m_offset + 4); - } - - /** - * Set the RPC version - * - * @param rpcVer int - */ - public final void setRpcVersion(int rpcVer) - { - DataPacker.putInt(rpcVer, m_buffer, m_offset + 8); - } - - /** - * Set the program id - * - * @param progId int - */ - public final void setProgramId(int progId) - { - DataPacker.putInt(progId, m_buffer, m_offset + 12); - } - - /** - * Set the program version - * - * @param progVer int - */ - public final void setProgramVersion(int progVer) - { - DataPacker.putInt(progVer, m_buffer, m_offset + 16); - } - - /** - * Set the procedure id - * - * @param procId int - */ - public final void setProcedureId(int procId) - { - DataPacker.putInt(procId, m_buffer, m_offset + 20); - } - - /** - * Set the credentials type - * - * @param credtype int - */ - public final void setCredentialsType(int credtype) - { - DataPacker.putInt(credtype, m_buffer, m_offset + 24); - } - - /** - * Set the credentials length - * - * @param credlen int - */ - public final void setCredentialsLength(int credlen) - { - DataPacker.putInt(credlen, m_buffer, m_offset + 28); - } - - /** - * Set the reply state - * - * @param replySts int - */ - public final void setReplyState(int replySts) - { - DataPacker.putInt(replySts, m_buffer, m_offset + 8); - } - - /** - * Set the reject status - * - * @param rejSts int - */ - public final void setRejectStatus(int rejSts) - { - DataPacker.putInt(rejSts, m_buffer, m_offset + 8); - } - - /** - * Set the RPC mismatch values - * - * @param rpcLow int - * @param rpcHigh int - */ - public final void setRpcMismatch(int rpcLow, int rpcHigh) - { - DataPacker.putInt(rpcLow, m_buffer, m_offset + 12); - DataPacker.putInt(rpcHigh, m_buffer, m_offset + 16); - } - - /** - * Set the authentication failure status - * - * @param authSts int - */ - public final void setAuthFailStatus(int authSts) - { - DataPacker.putInt(authSts, m_buffer, m_offset + 8); - } - - /** - * Set the verifier type - * - * @param verftype int - */ - public final void setVerifierType(int verftype) - { - DataPacker.putInt(verftype, m_buffer, m_offset + getCredentialsLength() + 32); - } - - /** - * Set the verifier length - * - * @param verflen int - */ - public final void setVerifierLength(int verflen) - { - DataPacker.putInt(verflen, m_buffer, m_offset + getCredentialsLength() + 36); - } - - /** - * Set the associated packet handler interface for the packet - * - * @param pktHandler RpcPacketHandler - */ - public final void setPacketHandler(RpcPacketHandler pktHandler) - { - m_pktHandler = pktHandler; - } - - /** - * Set the XID - * - * @param xid int - */ - public final void setXID(int xid) - { - DataPacker.putInt(xid, m_buffer, m_offset); - } - - /** - * Set the owner packet pool, if the packet was allocated from a pool - * - * @param pool RpcPacketPool - */ - protected final void setOwnerPacketPool(RpcPacketPool pool) - { - m_ownerPool = pool; - } - - /** - * Build an RPC request header, and set the buffer pointer ready to stream data into the parameter - * area of the request - * - * @param progId int - * @param verId int - * @param procId int - * @param credType int - * @param cred byte[] - * @param verfType int - * @param verf byte[] - */ - public final void buildRequestHeader(int progId, int verId, int procId, int credType, byte[] cred, int verfType, - byte[] verf) - { - - // Generate an id for the request - - setXID((int) (System.currentTimeMillis() & 0xFFFFFFFFL)); - - // Set the message type and RPC version (always version 2) - - setMessageType(Rpc.Call); - setRpcVersion(Rpc.RpcVersion); - - // Set the request details - - setProgramId(progId); - setProgramVersion(verId); - setProcedureId(procId); - - // Set the credentials type, length and value - - setCredentialsType(credType); - setCredentialsLength(cred != null ? cred.length : 0); - if (cred != null) - System.arraycopy(cred, 0, m_buffer, m_offset + 32, cred.length); - - // Set the verifier type, length and value - - setVerifierType(verfType); - setVerifierLength(verf != null ? verf.length : 0); - if (verf != null) - { - int pos = getVerifierOffset(); - System.arraycopy(verf, 0, m_buffer, pos, verf.length); - } - - // Position the buffer pointer at the request parameter area - - positionAtParameters(); - } - - /** - * Build a response header for a valid RPC response and set the buffer pointer ready to stream data - * into the parameter area of the response. - */ - public final void buildResponseHeader() - { - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallAccepted); - - // Copy the verifier from the request - - DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12); - - int verfLen = getVerifierLength(); - DataPacker.putInt(verfLen, m_buffer, m_offset + 16); - - if (verfLen > 0) - System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen); - - // Indicate a success status - - DataPacker.putInt(Rpc.StsSuccess, m_buffer, m_offset + 20 + verfLen); - - // Set the buffer pointer for streaming the response parameters - - m_pos = m_offset + 24 + verfLen; - setLength(); - } - - /** - * Build an error response packet where the RPC has been accepted but returns a status code in the parameter area. - * - * @param stsCode int - */ - public final void buildErrorResponse(int stsCode) - { - - // Check if the RPC is a request or reply - - boolean isReply = getMessageType() == Rpc.Reply; - - // Set the reply header - - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallAccepted); - - // Copy the verifier from the request - - int verfLen = 0; - - if (isReply == false) - { - DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12); - - verfLen = getVerifierLength(); - DataPacker.putInt(verfLen, m_buffer, m_offset + 16); - - if (verfLen > 0) - System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen); - } else - { - - // Get the verifier length from the reply - - verfLen = DataPacker.getInt(m_buffer, m_offset + 16); - } - - // Indicate a success status - - DataPacker.putInt(Rpc.StsSuccess, m_buffer, m_offset + 20 + verfLen); - - // Set the buffer pointer for streaming the response parameters - - m_pos = m_offset + 24 + verfLen; - - // Pack the service status code - - DataPacker.putInt(stsCode, m_buffer, m_pos); - m_pos += 4; - setLength(); - } - - /** - * Build an RPC version mismatch response - */ - public final void buildRpcMismatchResponse() - { - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallDenied); - setRejectStatus(Rpc.StsRpcMismatch); - setRpcMismatch(Rpc.RpcVersion, Rpc.RpcVersion); - - setLength(ResponseMismatchLen); - } - - /** - * Build an RPC authentication failure response - * - * @param stsCode int - */ - public final void buildAuthFailResponse(int stsCode) - { - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallDenied); - setRejectStatus(Rpc.StsAuthError); - setAuthFailStatus(stsCode); - - setLength(ResponseAuthFailLen); - } - - /** - * Build an RPC accept error response - * - * @param stsCode int - */ - public final void buildAcceptErrorResponse(int stsCode) - { - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallAccepted); - - // Copy the verifier from the request - - DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12); - - int verfLen = getVerifierLength(); - DataPacker.putInt(verfLen, m_buffer, m_offset + 16); - - if (verfLen > 0) - System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen); - - // Pack the status code - - DataPacker.putInt(stsCode, m_buffer, m_offset + 20 + verfLen); - - // Set the response length - - setLength(m_offset + 24 + verfLen); - } - - /** - * Build a program mismatch error response - * - * @param verLow int - * @param verHigh int - */ - public final void buildProgramMismatchResponse(int verLow, int verHigh) - { - setMessageType(Rpc.Reply); - setReplyState(Rpc.CallAccepted); - - // Copy the verifier from the request - - DataPacker.putInt(getVerifierType(), m_buffer, m_offset + 12); - - int verfLen = getVerifierLength(); - DataPacker.putInt(verfLen, m_buffer, m_offset + 16); - - if (verfLen > 0) - System.arraycopy(m_buffer, getVerifierOffset(), m_buffer, m_offset + 20, verfLen); - - // Pack the status code, and low/high version numbers - - int pos = m_offset + 20 + verfLen; - DataPacker.putInt(Rpc.StsProgMismatch, m_buffer, pos); - DataPacker.putInt(verLow, m_buffer, pos + 4); - DataPacker.putInt(verHigh, m_buffer, pos + 8); - - // Set the response length - - setLength(pos + 12); - } - - /** - * Return the RPC packet as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(128); - - // Dump the client details - - str.append("["); - if (hasClientAddress()) - { - str.append(getClientProtocol() == Rpc.TCP ? "T" : "U"); - str.append(getClientAddress().getHostAddress()); - str.append(":"); - str.append(getClientPort()); - } else - str.append(""); - - // Dump the call/response header - - if (getMessageType() == Rpc.Call) - { - - // Request packet - - str.append("-Call,XID=0x"); - str.append(Integer.toHexString(getXID())); - - str.append(",RpcVer="); - str.append(getRpcVersion()); - - str.append(",ProgId="); - str.append(getProgramId()); - str.append(",ProgVer="); - str.append(getProgramVersion()); - - str.append(",Proc="); - str.append(getProcedureId()); - - str.append(",CredType="); - str.append(getCredentialsType()); - str.append(",CredLen="); - str.append(getCredentialsLength()); - - str.append(",VerfType"); - str.append(getVerifierType()); - str.append(",VerfLen="); - str.append(getVerifierLength()); - - str.append(",ParamLen="); - str.append(getProcedureParameterLength()); - } else - { - - // Response packet - - str.append("-Reply,XID=0x"); - str.append(Integer.toHexString(getXID())); - - if (getReplyState() == Rpc.CallAccepted) - { - - // Request accepted response - - str.append(",Accepted"); - } else - { - - // Request denied response - - str.append(",Denied"); - - if (getRejectStatus() == Rpc.StsRpcMismatch) - { - str.append(",RpcMismatch, Low="); - str.append(getMismatchVersionLow()); - str.append("/High="); - str.append(getMismatchVersionHigh()); - } else - { - str.append(",AuthError, Status="); - ; - str.append(getAuthFailStatus()); - } - } - } - - // Check if the packet is allocated from a pool - - if (isAllocatedFromPool()) - str.append(",Pool"); - str.append("]"); - - // Return the string - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketHandler.java deleted file mode 100644 index 1cc015e5b4..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketHandler.java +++ /dev/null @@ -1,44 +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.server.oncrpc; - -import java.io.*; - -/** - * RPC Packet Handler Interface - * - *

Interface used by an RpcPacket to send a response RPC via either TCP or UDP. - * - * @author GKSpencer - */ -public interface RpcPacketHandler { - - /** - * Send an RPC response - * - * @param rpc RpcPacket - * @exception IOException - */ - public void sendRpcResponse(RpcPacket rpc) - throws IOException; -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketPool.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketPool.java deleted file mode 100644 index 2fc748053c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcPacketPool.java +++ /dev/null @@ -1,445 +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.server.oncrpc; - -import java.util.*; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Rpc Packet Pool Class - * - *

Contains a pool of small and large RpcPacket objects for use by multi-threaded RPC servers. - * - * @author GKSpencer - */ -public class RpcPacketPool { - - // Debug logging - - private static final Log logger = LogFactory.getLog(RpcPacketPool.class); - - // Constants - // - // Default small/large packet sizes - - public static final int DefaultSmallSize = 512; - public static final int DefaultLargeSize = 32768; - public static final int DefaultSmallLimit = -1; // no allocation limit - public static final int DefaultLargeLimit = -1; // " " " - - // Small/large packet lists - - private Vector m_smallPackets; - private Vector m_largePackets; - - // Small packet size and maximum allowed packets - - private int m_smallPktSize; - private int m_smallPktLimit; - - // Large packet size and maximum allowed packets - - private int m_largePktSize; - private int m_largePktLimit; - - // Count of allocated small/large packets - - private int m_smallPktCount; - private int m_largePktCount; - - /** - * Default constructor - */ - public RpcPacketPool() - { - - // Create the small/large packet lists - - m_smallPackets = new Vector(); - m_largePackets = new Vector(); - - // Set the packet sizes/limits - - m_smallPktSize = DefaultSmallSize; - m_smallPktLimit = DefaultSmallLimit; - - m_largePktSize = DefaultLargeSize; - m_largePktLimit = DefaultLargeLimit; - - } - - /** - * Class constructor - * - * @param smallSize int - * @param smallLimit int - * @param largeSize int - * @param largeLimit int - */ - public RpcPacketPool(int smallSize, int smallLimit, int largeSize, int largeLimit) - { - - // Create the small/large packet lists - - m_smallPackets = new Vector(); - m_largePackets = new Vector(); - - // Save the packet sizes/limits - - m_smallPktSize = smallSize; - m_smallPktLimit = smallLimit; - - m_largePktSize = largeSize; - m_largePktLimit = largeLimit; - } - - /** - * Class constructor - * - * @param largeSize int - * @param largeLimit int - */ - public RpcPacketPool(int largeSize, int largeLimit) - { - - // Create the small/large packet lists - - m_smallPackets = new Vector(); - m_largePackets = new Vector(); - - // Save the packet sizes/limits - - m_smallPktSize = DefaultSmallSize; - m_smallPktLimit = largeLimit; - - m_largePktSize = largeSize; - m_largePktLimit = largeLimit; - } - - /** - * Return the small packet size - * - * @return int - */ - public final int getSmallPacketSize() - { - return m_smallPktSize; - } - - /** - * Return the count of allocated small packets - * - * @return int - */ - public final int getSmallPacketCount() - { - return m_smallPktCount; - } - - /** - * Return the small packet allocation limit - * - * @return int - */ - public final int getSmallPacketAllocationLimit() - { - return m_smallPktLimit; - } - - /** - * Return the count of available large packets - * - * @return int - */ - public final int availableLargePackets() - { - return m_largePackets.size(); - } - - /** - * Return the large packet size - * - * @return int - */ - public final int getLargePacketSize() - { - return m_largePktSize; - } - - /** - * Return the count of allocated large packets - * - * @return int - */ - public final int getLargePacketCount() - { - return m_largePktCount; - } - - /** - * Return the large packet allocation limit - * - * @return int - */ - public final int getLargePacketAllocationLimit() - { - return m_largePktLimit; - } - - /** - * Return the count of available small packets - * - * @return int - */ - public final int availableSmallPackets() - { - return m_smallPackets.size(); - } - - /** - * Allocate a packet from the packet pool - * - * @param reqSize int - * @return RpcPacket - */ - public final RpcPacket allocatePacket(int reqSize) - { - - // Check if the packet should come from the small or large packet list - - RpcPacket pkt = null; - - if (reqSize <= m_smallPktSize) - { - - // Allocate a packet from the small packet list - - pkt = allocateSmallPacket(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcPacketPool Allocated (small) " + pkt.getBuffer() + ", len=" + pkt.getBuffer().length - + ", list=" + m_smallPackets.size() + "/" + m_smallPktLimit); - } else - { - - // Allocate a packet from the large packet list - - pkt = allocateLargePacket(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcPacketPool Allocated (large) " + pkt.getBuffer() + ", len=" + pkt.getBuffer().length - + ", list=" + m_largePackets.size() + "/" + m_largePktLimit); - } - - // Return the allocated packet - - return pkt; - } - - /** - * Release an RPC packet back to the pool - * - * @param pkt RpcPacket - */ - public final void releasePacket(RpcPacket pkt) - { - - // Check if the packet should be released to the small or large list - - if (pkt.getBuffer().length >= m_largePktSize) - { - - // Release the packet to the large packet list - - synchronized (m_largePackets) - { - - // Add the packet back to the free list - - m_largePackets.addElement(pkt); - - // Signal any waiting threads that there are packets available - - m_largePackets.notify(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcPacketPool Released (large) " + pkt.getBuffer() + ", len=" - + pkt.getBuffer().length + ", list=" + m_largePackets.size()); - } - } else - { - - // Release the packet to the small packet list - - synchronized (m_smallPackets) - { - - // Add the packet back to the free list - - m_smallPackets.addElement(pkt); - - // Signal any waiting threads that there are packets available - - m_smallPackets.notify(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("RpcPacketPool Released (small) " + pkt.getBuffer() + ", len=" - + pkt.getBuffer().length); - } - } - } - - /** - * Allocate, or create, a small RPC packet - * - * @return RpcPacket - */ - private final RpcPacket allocateSmallPacket() - { - - RpcPacket pkt = null; - - synchronized (m_smallPackets) - { - - // Check if there is a packet available from the small packet list - - if (m_smallPackets.size() > 0) - { - - // Remove a packet from the head of the free list - - pkt = (RpcPacket) m_smallPackets.elementAt(0); - m_smallPackets.removeElementAt(0); - } else if (m_smallPktLimit == -1 || m_smallPktCount < m_smallPktLimit) - { - - // Allocate a new packet - - pkt = new RpcPacket(m_smallPktSize, this); - m_smallPktCount++; - } else - { - - // Wait for a packet to be released to the small packet list - - try - { - - // Wait for a packet - - m_smallPackets.wait(); - - // Try to get the packet from the small packet list again - - if (m_smallPackets.size() > 0) - { - - // Remove a packet from the head of the free list - - pkt = (RpcPacket) m_smallPackets.elementAt(0); - m_smallPackets.removeElementAt(0); - } - } catch (InterruptedException ex) - { - } - } - } - - // Return the allocated packet - - return pkt; - } - - /** - * Allocate, or create, a large RPC packet - * - * @return RpcPacket - */ - private final RpcPacket allocateLargePacket() - { - - RpcPacket pkt = null; - - synchronized (m_largePackets) - { - - // Check if there is a packet available from the large packet list - - if (m_largePackets.size() > 0) - { - - // Remove a packet from the head of the free list - - pkt = (RpcPacket) m_largePackets.elementAt(0); - m_largePackets.removeElementAt(0); - } else if (m_largePktLimit == -1 || m_largePktCount < m_largePktLimit) - { - - // Allocate a new packet - - pkt = new RpcPacket(m_largePktSize, this); - m_largePktCount++; - } else - { - - // Wait for a packet to be released to the large packet list - - try - { - - // Wait for a packet - - m_largePackets.wait(); - - // Try to get the packet from the large packet list again - - if (m_largePackets.size() > 0) - { - - // Remove a packet from the head of the free list - - pkt = (RpcPacket) m_largePackets.elementAt(0); - m_largePackets.removeElementAt(0); - } - } catch (InterruptedException ex) - { - } - } - } - - // Return the allocated packet - - return pkt; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcProcessor.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcProcessor.java deleted file mode 100644 index c7c0f49195..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcProcessor.java +++ /dev/null @@ -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.server.oncrpc; - -import java.io.*; - -/** - * RPC Processor Interface - * - * @author GKSpencer - */ -public interface RpcProcessor { - - /** - * Process an RPC request - * - * @param rpc RpcPacket - * @return RpcPacket - * @throws IOException - */ - public RpcPacket processRpc(RpcPacket rpc) - throws IOException; -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestQueue.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestQueue.java deleted file mode 100644 index 44bc425131..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestQueue.java +++ /dev/null @@ -1,123 +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.server.oncrpc; - -import java.util.*; - -/** - * RPC Request Queue Class - * - *

Provides a request queue for a thread pool of worker threads. - * - * @author GKSpencer - */ -public class RpcRequestQueue { - - // List of RPC requests - - private LinkedList m_queue; - - /** - * Class constructor - */ - public RpcRequestQueue() - { - m_queue = new LinkedList(); - } - - /** - * Return the number of requests in the queue - * - * @return int - */ - public final synchronized int numberOfRequests() - { - return m_queue.size(); - } - - /** - * Add a request to the queue - * - * @param req RpcPacket - */ - public final synchronized void addRequest(RpcPacket req) - { - - // Add the request to the queue - - m_queue.add(req); - - // Notify workers that there is a request to process - - notifyAll(); - } - - /** - * Remove a request from the head of the queue - * - * @return RpcPacket - * @exception InterruptedException - */ - public final synchronized RpcPacket removeRequest() - throws InterruptedException - { - - // Wait until there is a request - - waitWhileEmpty(); - - // Get the request from the head of the queue - - return (RpcPacket) m_queue.removeFirst(); - } - - /** - * Wait for a request to be added to the queue - * - * @exception InterruptedException - */ - public final synchronized void waitWhileEmpty() - throws InterruptedException - { - - // Wait until some work arrives on the queue - - while (m_queue.size() == 0) - wait(); - } - - /** - * Wait for the request queue to be emptied - * - * @exception InterruptedException - */ - public final synchronized void waitUntilEmpty() - throws InterruptedException - { - - // Wait until the request queue is empty - - while (m_queue.size() != 0) - wait(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestThreadPool.java b/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestThreadPool.java deleted file mode 100644 index 5376fe603f..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/RpcRequestThreadPool.java +++ /dev/null @@ -1,261 +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.server.oncrpc; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * ONC/RPC Request Thread Pool Class - * - *

Processes RPC requests using a pool of worker threads. - * - * @author GKSpencer - */ -public class RpcRequestThreadPool { - - // Debug logging - - private static final Log logger = LogFactory.getLog(RpcRequestThreadPool.class); - - // Default/minimum/maximum number of worker threads to use - - public static final int DefaultWorkerThreads = 8; - public static final int MinimumWorkerThreads = 4; - public static final int MaximumWorkerThreads = 50; - - // Queue of RPC requests - - private RpcRequestQueue m_queue; - - // Worker threads - - private ThreadWorker[] m_workers; - - // RPC dispatcher - - private RpcProcessor m_rpcProcessor; - - /** - * Thread Worker Inner Class - */ - protected class ThreadWorker implements Runnable - { - - // Worker thread - - private Thread mi_thread; - - // Worker unique id - - private int mi_id; - - // Shutdown flag - - private boolean mi_shutdown = false; - - /** - * Class constructor - * - * @param name String - * @param id int - */ - public ThreadWorker(String name, int id) - { - - // Save the thread id - - mi_id = id; - - // Create the worker thread - - mi_thread = new Thread(this); - mi_thread.setName(name); - mi_thread.setDaemon(true); - mi_thread.start(); - } - - /** - * Request the worker thread to shutdown - */ - public final void shutdownRequest() - { - mi_shutdown = true; - try - { - mi_thread.interrupt(); - } catch (Exception ex) - { - } - } - - /** - * Run the thread - */ - public void run() - { - - // Loop until shutdown - - RpcPacket rpc = null; - RpcPacket response = null; - - while (mi_shutdown == false) - { - - try - { - - // Wait for an RPC request to be queued - - rpc = m_queue.removeRequest(); - } catch (InterruptedException ex) - { - - // Check for shutdown - - if (mi_shutdown == true) - break; - } - - // If the request is valid process it - - if (rpc != null) - { - - try - { - - // Process the request - - response = m_rpcProcessor.processRpc(rpc); - if (response != null) - response.getPacketHandler().sendRpcResponse(response); - } catch (Throwable ex) - { - - // Do not display errors if shutting down - - if (mi_shutdown == false) - { - if ( logger.isDebugEnabled()) { - logger.debug("Worker " + Thread.currentThread().getName() + ":"); - logger.debug(ex); - } - } - } finally - { - - // Release the RPC packet(s) back to the packet pool - - if (rpc.getClientProtocol() == Rpc.TCP && rpc.isAllocatedFromPool()) - rpc.getOwnerPacketPool().releasePacket(rpc); - - if (response != null && response.getClientProtocol() == Rpc.TCP - && response.getBuffer() != rpc.getBuffer() && response.isAllocatedFromPool()) - response.getOwnerPacketPool().releasePacket(response); - - } - } - } - } - }; - - /** - * Class constructor - * - * @param threadName String - * @param rpcServer RpcProcessor - * @param pktHandler PacketHandlerInterface - */ - public RpcRequestThreadPool(String threadName, RpcProcessor rpcServer) - { - this(threadName, DefaultWorkerThreads, rpcServer); - } - - /** - * Class constructor - * - * @param threadName String - * @param poolSize int - * @param rpcServer RpcProcessor - */ - public RpcRequestThreadPool(String threadName, int poolSize, RpcProcessor rpcServer) - { - - // Save the RPC handler - - m_rpcProcessor = rpcServer; - - // Create the request queue - - m_queue = new RpcRequestQueue(); - - // Check that we have at least minimum worker threads - - if (poolSize < MinimumWorkerThreads) - poolSize = MinimumWorkerThreads; - - // Create the worker threads - - m_workers = new ThreadWorker[poolSize]; - - for (int i = 0; i < m_workers.length; i++) - m_workers[i] = new ThreadWorker(threadName + (i + 1), i); - } - - /** - * Return the number of requests in the queue - * - * @return int - */ - public final int getNumberOfRequests() - { - return m_queue.numberOfRequests(); - } - - /** - * Queue an RPC request to the thread pool for processing - * - * @param rpc RpcPacket - */ - public final void queueRpcRequest(RpcPacket pkt) - { - m_queue.addRequest(pkt); - } - - /** - * Shutdown the thread pool and release all resources - */ - public void shutdownThreadPool() - { - - // Shutdown the worker threads - - if (m_workers != null) - { - for (int i = 0; i < m_workers.length; i++) - m_workers[i].shutdownRequest(); - } - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcClient.java b/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcClient.java deleted file mode 100644 index 07b841fd9a..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcClient.java +++ /dev/null @@ -1,103 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -/** - * TCP RPC Client Connection Class - * - * @author GKSpencer - */ -public class TcpRpcClient extends RpcClient { - - // TCP RPC client connection - - private TcpRpcPacketHandler m_client; - - /** - * Class constructor - * - * @param addr InetAddress - * @param port int - * @param maxRpcSize int - * @throws IOException - */ - public TcpRpcClient(InetAddress addr, int port, int maxRpcSize) throws IOException - { - super(addr, port, Rpc.TCP, maxRpcSize); - - // Connect a socket to the remote server - - Socket sock = new Socket(getServerAddress(), getServerPort()); - - // Create the TCP RPC packet handler for the client connection - - m_client = new TcpRpcPacketHandler(sock, maxRpcSize); - } - - /** - * Send an RPC request using the socket connection, and receive a response - * - * @param rpc RpcPacket - * @param rxRpc RpcPacket - * @return RpcPacket - * @throws IOException - */ - public RpcPacket sendRPC(RpcPacket rpc, RpcPacket rxRpc) - throws IOException - { - - // Use the TCP packet handler to send the RPC - - m_client.sendRpc(rpc); - - // Receive a response RPC - - RpcPacket rxPkt = rxRpc; - if (rxPkt == null) - rxPkt = new RpcPacket(getMaximumRpcSize()); - - m_client.receiveRpc(rxPkt); - - // Return the RPC response - - return rxPkt; - } - - /** - * Close the connection to the remote RPC server - */ - public void closeConnection() - { - - // Close the packet handler - - if (m_client != null) - { - m_client.closePacketHandler(); - m_client = null; - } - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcPacketHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcPacketHandler.java deleted file mode 100644 index d6aabb28e2..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcPacketHandler.java +++ /dev/null @@ -1,456 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -import org.alfresco.filesys.server.SocketPacketHandler; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * TCP RPC Packet Handler Class - * - *

Processes RPC requests received via TCP session. - * - * @author GKSpencer - */ -public class TcpRpcPacketHandler extends SocketPacketHandler implements Runnable { - - // Debug logging - - private static final Log logger = LogFactory.getLog(TcpRpcPacketHandler.class); - - // Session handler that owns this session - - private TcpRpcSessionHandler m_handler; - - // RPC server implementation used to process the requests - - private RpcProcessor m_rpcProcessor; - - // Session id - - private int m_sessId; - - // RPC processing thread shutdown flag - - private boolean m_shutdown; - - // Maximum RPC size accepted - - private int m_maxRpcSize; - - // Packet buffer for receiving incoming RPC requests - - private RpcPacket m_rxPkt; - - // Fragment header buffer - - private byte[] m_fragBuf; - - /** - * Class constructor to create a TCP RPC handler for a server. - * - * @param handler TcpRpcSessionHandler - * @param sessId int - * @param server RpcProcessor - * @param socket Socket - * @param maxRpcSize int - * @throws IOException - */ - public TcpRpcPacketHandler(TcpRpcSessionHandler handler, int sessId, RpcProcessor server, Socket socket, - int maxRpcSize) throws IOException - { - super(socket); - - // Set the session handler that owns this session - - m_handler = handler; - - // set the session id - - m_sessId = sessId; - - // Set the RPC server to be used to process requests - - m_rpcProcessor = server; - - // Set the maximum RPC size accepted - - m_maxRpcSize = maxRpcSize; - - // Allocate the RPC fragment header buffer - - m_fragBuf = new byte[4]; - - // Create a thread to run the RPC processing for this session - - Thread th = new Thread(this); - th.setName(handler.getProtocolName() + "_" + getSessionId()); - th.start(); - } - - /** - * Class constructor to create a TCP RPC handler for a client. - * - * @param socket Socket - * @param maxRpcSize int - * @throws IOException - */ - public TcpRpcPacketHandler(Socket socket, int maxRpcSize) throws IOException - { - super(socket); - - // Allocate the RPC fragment header buffer - - m_maxRpcSize = maxRpcSize; - m_fragBuf = new byte[4]; - } - - /** - * Return the protocol name - * - * @return String - */ - public String getProtocolName() - { - return "TCP RPC"; - } - - /** - * Return the session id - * - * @return int - */ - public final int getSessionId() - { - return m_sessId; - } - - /** - * Return the maximum RPC size accepted - * - * @return int - */ - public final int getMaximumRpcSize() - { - return m_maxRpcSize; - } - - /** - * Return the associated session handler - * - * @return TcpRpcSessionHandler - */ - protected final TcpRpcSessionHandler getHandler() - { - return m_handler; - } - - /** - * Thread to read and process the RPC requests for this session - */ - public void run() - { - - // Loop until shutdown - - int rxLen = 0; - RpcPacket rpcPkt = null; - - while (m_shutdown == false) - { - - try - { - - // allocate an RPC packet to receive an incoming request - - rpcPkt = allocateRpcPacket(getMaximumRpcSize()); - - // Read an RPC request - - rxLen = receiveRpc(rpcPkt); - - if (rxLen == -1) - { - - // Release the packet - - deallocateRpcPacket(rpcPkt); - - // Receive error, client has closed the socket - - m_handler.closeSession(getSessionId()); - break; - } - } catch (SocketException ex) - { - - // Release the packet - - if (rpcPkt != null) - deallocateRpcPacket(rpcPkt); - - // Socket error, close the session - - m_handler.closeSession(getSessionId()); - break; - } catch (IOException ex) - { - - // Only dump errors if not shutting down - - if (m_shutdown == false) - logger.debug(ex); - } - - // Process the RPC request - - try - { - - // Validate the RPC header - - if (rpcPkt.getRpcVersion() != Rpc.RpcVersion) - { - - // Build/send an error response - - rpcPkt.buildRpcMismatchResponse(); - sendRpc(rpcPkt); - } else - { - - // Process the RPC request - - processRpc(rpcPkt); - } - } catch (IOException ex) - { - - // Only dump errors if not shutting down - - if (m_shutdown == false) - logger.debug(ex); - } - } - } - - /** - * Close the session - */ - public void closePacketHandler() - { - - // Request the RPC processing thread to shutdown - - m_shutdown = true; - - // Close the input/output streams and socket - - super.closePacketHandler(); - } - - /** - * Send an RPC request/response packet - * - * @param rpc RpcPacket - * @exception IOException - */ - protected final void sendRpc(RpcPacket rpc) - throws IOException - { - - // Write the RPC response, this includes the fragment header - // - // If the fragment header is written seperately to the main RPC response packet trace tools - // such as Ethereal will not display the details properly. - - writePacket(rpc.getBuffer(), 0, rpc.getTxLength()); - } - - /** - * Read an RPC request/response - * - * @param rpc RpcPacket - * @return int - * @throws IOException - */ - protected final int receiveRpc(RpcPacket rpc) - throws IOException - { - - // Use the main receive method - - int rxLen = receiveRpc(rpc.getBuffer(), RpcPacket.FragHeaderLen, rpc.getBuffer().length - - RpcPacket.FragHeaderLen); - if (rxLen > 0) - { - - // Set the received length - - rpc.setBuffer(RpcPacket.FragHeaderLen, rxLen + RpcPacket.FragHeaderLen); - - // Set the client details - - rpc.setClientDetails(getSocket().getInetAddress(), getSocket().getPort(), Rpc.TCP); - } - - // Return the received data length - - return rxLen; - } - - /** - * Read an RPC request/response - * - * @param buffer byte[] - * @param offset int - * @param maxLen int - * @return int - * @throws IOException - */ - protected final int receiveRpc(byte[] buffer, int offset, int maxLen) - throws IOException - { - - // Fill the buffer until the last fragment is received - - int rxLen = 0; - int totLen = 0; - int rxOffset = offset; - int fragLen = 0; - boolean lastFrag = false; - - while (lastFrag == false) - { - - // Read in a header to get the fragment length - - rxLen = readPacket(m_fragBuf, 0, 4); - if (rxLen == -1) - return rxLen; - - // Check if we received the last fragment - - fragLen = DataPacker.getInt(m_fragBuf, 0); - - if ((fragLen & Rpc.LastFragment) != 0) - { - lastFrag = true; - fragLen = fragLen & Rpc.LengthMask; - } - - // Check if the buffer is large enough to receive the request - - if (fragLen > (buffer.length - rxOffset)) - throw new IOException("Receive RPC buffer overflow, fragment len = " + fragLen); - - // Read the data part of the packet into the users buffer, this may take - // several reads - - while (fragLen > 0) - { - - // Read the data - - rxLen = readPacket(buffer, offset, fragLen); - - // Check if the connection has been closed - - if (rxLen == -1) - return -1; - - // Update the received length and remaining data length - - totLen += rxLen; - fragLen -= rxLen; - - // Update the user buffer offset as more reads will be required - // to complete the data read - - offset += rxLen; - - } // end while reading data - - } // end while fragments - - // Return the total length read - - return totLen; - } - - /** - * Allocate an RPC packet for receiving an incoming request. This method must be overridden for - * multi-threaded implementations. - * - * @param maxSize int - * @return RpcPacket - */ - protected RpcPacket allocateRpcPacket(int maxSize) - { - - // Check if the receive packet has been allocated - - if (m_rxPkt == null) - m_rxPkt = new RpcPacket(maxSize); - - // Return the RPC receive packet - - return m_rxPkt; - } - - /** - * Deallocate an RPC packet, default method does nothing but a pooled implementation may - * return the packet to the pool. - * - * @param pkt RpcPacket - */ - protected void deallocateRpcPacket(RpcPacket pkt) - { - } - - /** - * Process an RPC request. This method must be overridden for multi-threaded implementations. - * - * @param rpc RpcPacket - * @exception IOException - */ - protected void processRpc(RpcPacket rpc) - throws IOException - { - - // Process the RPC request in the current thread - - RpcPacket response = m_rpcProcessor.processRpc(rpc); - - // Send the RPC response - - if (response != null) - sendRpc(response); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcSessionHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcSessionHandler.java deleted file mode 100644 index 150361daa3..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/TcpRpcSessionHandler.java +++ /dev/null @@ -1,212 +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.server.oncrpc; - -import java.io.*; -import java.net.*; -import java.util.*; - -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.PacketHandlerInterface; -import org.alfresco.filesys.server.SocketSessionHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * TCP RPC Session Handler Class - * - *

Receives session requests via a TCP socketRPC requests via a datagram and passes the request to the registered RPC server. - * - * @author GKSpencer - */ -public class TcpRpcSessionHandler extends SocketSessionHandler { - - // Debug logging - - private static final Log logger = LogFactory.getLog(TcpRpcSessionHandler.class); - - // RPC server implementation that handles the RPC processing - - private RpcProcessor m_rpcProcessor; - - // Maximum request size allowed - - private int m_maxRpcSize; - - // List of active sessions - - private Hashtable m_sessions; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param rpcServer RpcProcessor - * @param server NetworkServer - * @param addr InetAddress - * @param port int - * @param maxSize int - */ - public TcpRpcSessionHandler(String name, String protocol, RpcProcessor rpcServer, NetworkServer server, - InetAddress addr, int port, int maxSize) - { - super(name, protocol, server, addr, port); - - // Set the RPC server implementation that will handle the actual requests - - m_rpcProcessor = rpcServer; - - // Set the maximum RPC request size allowed - - m_maxRpcSize = maxSize; - - // Create the active session list - - m_sessions = new Hashtable(); - } - - /** - * Return the maximum RPC size allowed - * - * @return int - */ - protected int getMaximumRpcSize() - { - return m_maxRpcSize; - } - - /** - * Return the RPC server used to process the requests - * - * @return RpcProcessor - */ - protected final RpcProcessor getRpcProcessor() - { - return m_rpcProcessor; - } - - /** - * Accept an incoming session request - * - * @param sock Socket - */ - protected void acceptConnection(Socket sock) - { - - try - { - - // Set the socket for no delay - - sock.setTcpNoDelay(true); - - // Create a packet handler for the new session and add to the active session list - - int sessId = getNextSessionId(); - TcpRpcPacketHandler pktHandler = createPacketHandler(sessId, sock); - - // Add the packet handler to the active session table - - m_sessions.put(new Integer(sessId), pktHandler); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[" + getProtocolName() + "] Created new session id = " + sessId + ", from = " - + sock.getInetAddress().getHostAddress() + ":" + sock.getPort()); - } catch (IOException ex) - { - } - } - - /** - * Remove a session from the active session list - * - * @param sessId int - */ - protected final void closeSession(int sessId) - { - - // Remove the specified session from the active session table - - PacketHandlerInterface pktHandler = (PacketHandlerInterface) m_sessions.remove(new Integer(sessId)); - if (pktHandler != null) - { - - // Close the session - - pktHandler.closePacketHandler(); - } - } - - /** - * Close the session handler, close all active sessions. - * - * @param server NetworkServer - */ - public void closeSessionHandler(NetworkServer server) - { - super.closeSessionHandler(server); - - // Close all active sessions - - if (m_sessions.size() > 0) - { - - // Enumerate the sessions - - Enumeration enm = m_sessions.elements(); - - while (enm.hasMoreElements()) - { - - // Get the current packet handler - - PacketHandlerInterface handler = (PacketHandlerInterface) enm.nextElement(); - handler.closePacketHandler(); - } - - // Clear the session list - - m_sessions.clear(); - } - } - - /** - * Create a packet handler for a new session - * - * @param sessId int - * @param sock Socket - * @return TcpRpcPacketHandler - * @exception IOException - */ - protected TcpRpcPacketHandler createPacketHandler(int sessId, Socket sock) - throws IOException - { - - // Create a single threaded TCP RPC packet handler - - return new TcpRpcPacketHandler(this, sessId, m_rpcProcessor, sock, getMaximumRpcSize()); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/UdpRpcDatagramHandler.java b/source/java/org/alfresco/filesys/server/oncrpc/UdpRpcDatagramHandler.java deleted file mode 100644 index 094f37e3fe..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/UdpRpcDatagramHandler.java +++ /dev/null @@ -1,140 +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.server.oncrpc; - -import java.io.*; -import java.net.*; - -import org.alfresco.filesys.server.DatagramSessionHandler; -import org.alfresco.filesys.server.NetworkServer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * UDP RPC Datagram Handler Class - * - *

Receives RPC requests via a datagram and passes the request to the registered RPC server. - * - * @author GKSpencer - */ -public class UdpRpcDatagramHandler extends DatagramSessionHandler -{ - // Debug logging - - protected static final Log logger = LogFactory.getLog(UdpRpcDatagramHandler.class); - - // RPC server implementation that handles the RPC processing - - private RpcProcessor m_rpcProcessor; - - /** - * Class constructor - * - * @param name String - * @param protocol String - * @param rpcServer RpcProcessor - * @param server NetworkServer - * @param addr InetAddress - * @param port int - * @param maxSize int - */ - public UdpRpcDatagramHandler(String name, String protocol, RpcProcessor rpcServer, NetworkServer server, - InetAddress addr, int port, int maxSize) - { - super(name, protocol, server, addr, port); - - // Set the RPC server implementation that will handle the actual requests - - m_rpcProcessor = rpcServer; - - // Set the maximum RPC request size allowed - - setMaximumDatagramSize(maxSize); - } - - /** - * Return the RPC server used to process the requests - * - * @return RpcProcessor - */ - protected final RpcProcessor getRpcProcessor() - { - return m_rpcProcessor; - } - - /** - * Process the RPC datagram - * - * @param pkt DatagramPacket - * @return boolean - * @throws IOException - */ - protected boolean processDatagram(DatagramPacket pkt) - throws IOException - { - - // The default implementation processes the RPC immediately then returns to the main datagram handler - // to wait for the next datagram to be received. In this case the datagram packet can be re-used as - // processing is done sequentially. - - // Wrap the datagram data up as an RPC request - - RpcPacket rpcPkt = new RpcPacket(pkt.getData(), 0, pkt.getLength()); - - // Set the client details - - rpcPkt.setClientDetails(pkt.getAddress(), pkt.getPort(), Rpc.UDP); - - // Validate the RPC header - - if (rpcPkt.getRpcVersion() != Rpc.RpcVersion) - { - - // Build/send an error response - - rpcPkt.buildRpcMismatchResponse(); - pkt.setData(rpcPkt.getBuffer(), rpcPkt.getOffset(), RpcPacket.ResponseMismatchLen); - - sendDatagram(pkt); - } - else - { - - // Pass the request to the registered RPC server to process - - RpcPacket response = m_rpcProcessor.processRpc(rpcPkt); - - // Send the RPC response - - if (response != null) - { - pkt.setData(response.getBuffer(), response.getOffset(), response.getLength()); - sendDatagram(pkt); - } - } - - // Indicate that the existing datagram packet can be re-used for the next request - - return true; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/mount/Mount.java b/source/java/org/alfresco/filesys/server/oncrpc/mount/Mount.java deleted file mode 100644 index ba9c6345eb..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/mount/Mount.java +++ /dev/null @@ -1,94 +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.server.oncrpc.mount; - -/** - * Mount Server Constants Class - * - * @author GKSpencer - */ -public final class Mount { - - // Program and version id - - public static final int ProgramId = 100005; - public static final int VersionId1 = 1; - public static final int VersionId3 = 3; - - // RPC procedure ids (version 1) - - public static final int ProcNull1 = 0; - public static final int ProcMnt1 = 1; - public static final int ProcDump1 = 2; - public static final int ProcUMnt1 = 3; - public static final int ProcUMntAll1 = 4; - public static final int ProcExport1 = 5; - public static final int ProcExportAll1 = 6; - public static final int ProcMax1 = 6; - - // RPC procedure ids (version 3) - - public static final int ProcNull3 = 0; - public static final int ProcMnt3 = 1; - public static final int ProcDump3 = 2; - public static final int ProcUMnt3 = 3; - public static final int ProcUMntAll3 = 4; - public static final int ProcExport3 = 5; - public static final int ProcMax3 = 5; - - // Mount server status codes - - public static final int StsSuccess = 0; - public static final int StsPerm = 1; - public static final int StsNoEnt = 2; - public static final int StsIO = 5; - public static final int StsAccess = 13; - public static final int StsNotDir = 20; - public static final int StsInval = 22; - public static final int StsNameTooLong = 63; - public static final int StsNotSupp = 10004; - public static final int StsServerFault = 10006; - - // Data structure limits - - public static final int FileHandleSize1 = 32; - public static final int FileHandleSize3 = 32; // can be 64 for v3 - - // RPC procedure names - - private static final String[] _procNames = { "Null", "Mount", "Dump", - "UnMount", "UnMountAll", "Export", "ExportAll" }; - - /** - * Return a procedure id as a name - * - * @param id - * int - * @return String - */ - public final static String getProcedureName(int id) { - if (id < 0 || id > ProcMax1) - return null; - return _procNames[id]; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntry.java b/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntry.java deleted file mode 100644 index 07b21e64bb..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntry.java +++ /dev/null @@ -1,87 +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.server.oncrpc.mount; - -/** - * Mount Entry Class - * - *

Contains the details of an active NFS mount. - * - * @author GKSpencer - */ -public class MountEntry { - - // Remote host name/address - - private String m_host; - - // Mount path - - private String m_path; - - /** - * Class constructor - * - * @param host String - * @param path String - */ - public MountEntry(String host, String path) { - m_host = host; - m_path = path; - } - - /** - * Return the host name/address - * - * @return String - */ - public final String getHost() { - return m_host; - } - - /** - * Return the mount path - * - * @return String - */ - public final String getPath() { - return m_path; - } - - /** - * Return the mount entry as a string - * - * @return String - */ - public String toString() { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getHost()); - str.append(":"); - str.append(getPath()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntryList.java b/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntryList.java deleted file mode 100644 index deff771cff..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountEntryList.java +++ /dev/null @@ -1,160 +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.server.oncrpc.mount; - -import java.util.*; - -/** - * Mount Entry List Class - * - *

Contains a list of active mount entries. - * - * @author GKSpencer - */ -public class MountEntryList { - - // Mount entry list - - private Vector m_mounts; - - /** - * Default constructor - */ - public MountEntryList() { - m_mounts = new Vector(); - } - - /** - * Ad an entry to the list - * - * @param entry MountEntry - */ - public synchronized final void addEntry(MountEntry entry) { - m_mounts.addElement(entry); - } - - /** - * Return the number of entries in the list - * - * @return int - */ - public synchronized final int numberOfEntries() { - return m_mounts.size(); - } - - /** - * Return the specified entry - * - * @param idx - * @return MountEntry - */ - public synchronized final MountEntry getEntryAt(int idx) { - if ( idx < 0 || idx >= m_mounts.size()) - return null; - return (MountEntry) m_mounts.elementAt(idx); - } - - /** - * Find an entry in the list - * - * @param path String - * @param host String - * @return MountEntry - */ - public synchronized final MountEntry findEntry(String path, String host) { - for ( int i = 0; i < m_mounts.size(); i++) { - MountEntry entry = (MountEntry) m_mounts.elementAt(i); - - if ( host.compareTo(entry.getHost()) == 0 && path.compareTo(entry.getPath()) == 0) - return entry; - } - return null; - } - - /** - * Remove an entry from the list - * - * @param path String - * @param host String - * @return MountEntry - */ - public synchronized final MountEntry removeEntry(String path, String host) { - for ( int i = 0; i < m_mounts.size(); i++) { - MountEntry entry = (MountEntry) m_mounts.elementAt(i); - - if ( host.compareTo(entry.getHost()) == 0 && path.compareTo(entry.getPath()) == 0) { - m_mounts.removeElementAt(i); - return entry; - } - } - return null; - } - - /** - * Remove all entries from the list for the specified host - * - * @param host String - */ - public synchronized final void removeHostEntries(String host) { - for ( int i = 0; i < m_mounts.size(); i++) { - MountEntry entry = (MountEntry) m_mounts.elementAt(i); - - if ( host.compareTo(entry.getHost()) == 0) - m_mounts.removeElementAt(i); - } - } - - /** - * Find all items for the specified host and return as a new list - * - * @param host String - * @return MountEntryList - */ - public synchronized final MountEntryList findSessionEntries(String host) { - - // Allocate the list to hold the matching entries - - MountEntryList list = new MountEntryList(); - - // Find the matching entries - - for ( int i = 0; i < m_mounts.size(); i++) { - MountEntry entry = (MountEntry) m_mounts.elementAt(i); - if ( host.compareTo(entry.getHost()) == 0) - list.addEntry(entry); - } - - // Check if the list is empty, return the list - - if ( list.numberOfEntries() == 0) - list = null; - return list; - } - - /** - * Remote all entries from the list - */ - public synchronized final void removeAllItems() { - m_mounts.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountServer.java b/source/java/org/alfresco/filesys/server/oncrpc/mount/MountServer.java deleted file mode 100644 index 12c122265c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/mount/MountServer.java +++ /dev/null @@ -1,891 +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.server.oncrpc.mount; - -import java.io.*; -import java.util.*; - -import org.alfresco.filesys.server.ServerListener; -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.config.ServerConfiguration; -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.DiskInterface; -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.TreeConnectionHash; -import org.alfresco.filesys.server.oncrpc.PortMapping; -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.RpcNetworkServer; -import org.alfresco.filesys.server.oncrpc.RpcPacket; -import org.alfresco.filesys.server.oncrpc.RpcProcessor; -import org.alfresco.filesys.server.oncrpc.TcpRpcSessionHandler; -import org.alfresco.filesys.server.oncrpc.UdpRpcDatagramHandler; -import org.alfresco.filesys.server.oncrpc.nfs.NFSHandle; -import org.alfresco.filesys.server.oncrpc.nfs.NFSSrvSession; - -/** - * Mount Server Class - * - *

Contains the NFS mount server. - * - * @author GKSpencer - */ -public class MountServer extends RpcNetworkServer implements RpcProcessor { - - // Constants - // - // Maximum request size to accept - - public final static int MaxRequestSize = 8192; - - // Unix path seperator - - public static final String UNIX_SEPERATOR = "/"; - public static final char UNIX_SEPERATOR_CHAR = '/'; - public static final String DOS_SEPERATOR = "\\"; - public static final char DOS_SEPERATOR_CHAR = '\\'; - - // Incoming datagram handler for UDP requests - - private UdpRpcDatagramHandler m_udpHandler; - - // Incoming session handler for TCP requests - - private TcpRpcSessionHandler m_tcpHandler; - - // Tree connection hash - - private TreeConnectionHash m_connections; - - // List of active mounts - - private MountEntryList m_mounts; - - // Port number to listen on (UDP and TCP) - - private int m_port; - - /** - * Class constructor - * - * @param config - * ServerConfiguration - */ - public MountServer(ServerConfiguration config) { - super("Mount", config); - - // Enable/disable debug output - - setDebug(config.hasMountServerDebug()); - - // Set the port to bind the server to - - setPort(config.getMountServerPort()); - } - - /** - * Return the port to bind to - * - * @return int - */ - public final int getPort() { - return m_port; - } - - /** - * Set the port to use - * - * @param port - * int - */ - public final void setPort(int port) { - m_port = port; - } - - /** - * Start the mount server - */ - public void startServer() { - - try { - - // Create the UDP handler for accepting incoming requests - - m_udpHandler = new UdpRpcDatagramHandler("Mountd", "Mnt", this, this, null, getPort(), MaxRequestSize); - m_udpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread udpThread = new Thread(m_udpHandler); - udpThread.setName("Mountd_UDP"); - udpThread.start(); - - // Create the TCP handler for accepting incoming requests - - m_tcpHandler = new TcpRpcSessionHandler("Mountd", "Mnt", this, this, null, getPort(), MaxRequestSize); - m_tcpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread tcpThread = new Thread(m_tcpHandler); - tcpThread.setName("Mountd_TCP"); - tcpThread.start(); - - // Register the mount server with the portmapper - - PortMapping[] mappings = new PortMapping[4]; - mappings[0] = new PortMapping(Mount.ProgramId, Mount.VersionId1, Rpc.UDP, m_udpHandler.getPort()); - mappings[1] = new PortMapping(Mount.ProgramId, Mount.VersionId3, Rpc.UDP, m_udpHandler.getPort()); - mappings[2] = new PortMapping(Mount.ProgramId, Mount.VersionId1, Rpc.TCP, m_tcpHandler.getPort()); - mappings[3] = new PortMapping(Mount.ProgramId, Mount.VersionId3, Rpc.TCP, m_tcpHandler.getPort()); - - registerRPCServer(mappings); - } - catch (Exception ex) { - logger.error(ex); - } - - // Allocate the tree connection hash list and populate with the - // available share names - - m_connections = new TreeConnectionHash(); - - SharedDeviceList shareList = getConfiguration().getShareMapper() - .getShareList(getConfiguration().getServerName(), null, false); - Enumeration shares = shareList.enumerateShares(); - - while (shares.hasMoreElements()) { - - // Get the shared device - - SharedDevice share = (SharedDevice) shares.nextElement(); - - // Check if it is a disk type shared device, if so then add a - // connection to the tree connection hash - - if (share != null && share.getType() == ShareType.DISK) - m_connections.addConnection(new TreeConnection(share)); - } - - // Allocate the active mount list - - m_mounts = new MountEntryList(); - } - - /** - * Shutdown the mount server - * - * @param immediate - * boolean - */ - public void shutdownServer(boolean immediate) { - - // Unregister the mount server with the portmapper - - try { - PortMapping[] mappings = new PortMapping[4]; - mappings[0] = new PortMapping(Mount.ProgramId, Mount.VersionId1, - Rpc.UDP, m_udpHandler.getPort()); - mappings[1] = new PortMapping(Mount.ProgramId, Mount.VersionId3, - Rpc.UDP, m_udpHandler.getPort()); - mappings[2] = new PortMapping(Mount.ProgramId, Mount.VersionId1, - Rpc.TCP, m_tcpHandler.getPort()); - mappings[3] = new PortMapping(Mount.ProgramId, Mount.VersionId3, - Rpc.TCP, m_tcpHandler.getPort()); - - unregisterRPCServer(mappings); - } - catch (IOException ex) { - logger.debug(ex); - } - - // Stop the RPC handlers - - if (m_udpHandler != null) { - m_udpHandler.closeSessionHandler(this); - m_udpHandler = null; - } - - if (m_tcpHandler != null) { - m_tcpHandler.closeSessionHandler(this); - m_tcpHandler = null; - } - - // Fire a shutdown notification event - - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Process an RPC request - * - * @param rpc - * RpcPacket - * @return RpcPacket - * @throws IOException - */ - public RpcPacket processRpc(RpcPacket rpc) throws IOException { - - // Validate the request - - int version = rpc.getProgramVersion(); - - if (rpc.getProgramId() != Mount.ProgramId) { - - // Request is not for us - - rpc.buildAcceptErrorResponse(Rpc.StsProgUnavail); - return rpc; - } - else if (version != Mount.VersionId1 && version != Mount.VersionId3) { - - // Request is not for this version of mount - - rpc.buildProgramMismatchResponse(Mount.VersionId1, Mount.VersionId3); - return rpc; - } - - // Authenticate the request - - NFSSrvSession sess = null; - - try { - - // Create a temporary session for the request - - sess = createTemporarySession(rpc); - } - catch (RpcAuthenticationException ex) { - - // Failed to authenticate the RPC client - - rpc.buildAuthFailResponse(ex.getAuthenticationErrorCode()); - return rpc; - } - - // Position the RPC buffer pointer at the start of the call parameters - - rpc.positionAtParameters(); - - // Process the RPC request - - RpcPacket response = null; - - if (version == Mount.VersionId1) { - - // Version 1 requests - - switch (rpc.getProcedureId()) { - - // Null request - - case Mount.ProcNull1: - response = procNull(rpc); - break; - - // Mount request - - case Mount.ProcMnt1: - response = procMount(sess, rpc, version); - break; - - // Dump request - - case Mount.ProcDump1: - response = procDump(sess, rpc, version); - break; - - // Unmount request - - case Mount.ProcUMnt1: - response = procUnMount(sess, rpc, version); - break; - - // Unmount all request - - case Mount.ProcUMntAll1: - response = procUnMountAll(sess, rpc, version); - break; - - // Export request - - case Mount.ProcExport1: - response = procExport(sess, rpc, version); - break; - - // Export all request - - case Mount.ProcExportAll1: - response = procExportAll(sess, rpc); - break; - } - } else if (version == Mount.VersionId3) { - - // Version 1 requests - - switch (rpc.getProcedureId()) { - - // Null request - - case Mount.ProcNull3: - response = procNull(rpc); - break; - - // Mount request - - case Mount.ProcMnt3: - response = procMount(sess, rpc, version); - break; - - // Dump request - - case Mount.ProcDump3: - response = procDump(sess, rpc, version); - break; - - // Unmount request - - case Mount.ProcUMnt3: - response = procUnMount(sess, rpc, version); - break; - - // Unmount all request - - case Mount.ProcUMntAll3: - response = procUnMountAll(sess, rpc, version); - break; - - // Export request - - case Mount.ProcExport3: - response = procExport(sess, rpc, version); - break; - } - } - - // Return the RPC response - - return response; - } - - /** - * Process the null request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procNull(RpcPacket rpc) { - - // Build the response - - rpc.buildResponseHeader(); - return rpc; - } - - /** - * Process the mount request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @param version - * int - * @return RpcPacket - */ - private final RpcPacket procMount(NFSSrvSession sess, RpcPacket rpc, - int version) { - - // Get the request parameters - - String mountPath = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[Mount] Mount request from " + rpc.getClientDetails() + " path=" + mountPath); - - // Allocate the file handle - - byte[] handle = allocateFileHandle(version); - - // Mount the path - - int sts = mountPath(sess, mountPath, handle); - - // Pack mount the response - - rpc.buildResponseHeader(); - - // Pack the file handle status structure, version 1 format - - if (version == 1) { - - // Version 1 response format - - rpc.packInt(sts); - if (sts == Mount.StsSuccess) - rpc.packByteArray(handle); - } - else if (version == 3) { - - // Version 3 response format - - rpc.packInt(sts); - if (sts == Mount.StsSuccess) - rpc.packByteArrayWithLength(handle); - - // Create an authentication flavours array - - rpc.packIntArrayWithLength(getConfiguration().getRpcAuthenticator() - .getRpcAuthenticationTypes()); - } - - // Return the mount response - - rpc.setLength(); - return rpc; - } - - /** - * Process the dump request, return the list of active mounts - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @param version - * int - * @return RpcPacket - */ - private final RpcPacket procDump(NFSSrvSession sess, RpcPacket rpc, - int version) { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[Mount] Dump request from " + rpc.getClientDetails()); - - // Take a snapshot of the active mount list - - MountEntryList activeList = null; - - synchronized (m_mounts) { - - // Check if there are active mounts, if so then copy the mount list - - if (m_mounts.numberOfEntries() > 0) { - activeList = new MountEntryList(); - for (int i = 0; i < m_mounts.numberOfEntries(); i++) - activeList.addEntry(m_mounts.getEntryAt(i)); - } - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Pack the mount list structures into the response - - if (activeList != null) { - - // Pack the active mount entry details - - for (int i = 0; i < activeList.numberOfEntries(); i++) { - - // Get the current entry - - MountEntry mntEntry = activeList.getEntryAt(i); - - rpc.packInt(Rpc.True); - rpc.packString(mntEntry.getPath()); - rpc.packString(mntEntry.getHost()); - } - } - - // Mark the end of the mount list and set the response length - - rpc.packInt(Rpc.False); - rpc.setLength(); - - // Return the RPC response - - return rpc; - } - - /** - * Process the unmount request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @param version - * int - * @return RpcPacket - */ - private final RpcPacket procUnMount(NFSSrvSession sess, RpcPacket rpc, - int version) { - - // Get the request parameters - - String mountPath = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[Mount] UnMount request from " + rpc.getClientDetails() + " path=" + mountPath); - - // Remove the mount details from the active mount list - - m_mounts.removeEntry(mountPath, sess.getRemoteName()); - - // Build the RPC response - - rpc.buildResponseHeader(); - - // Return the RPC response - - return rpc; - } - - /** - * Process the unmoount all request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @param version - * int - * @return RpcPacket - */ - private final RpcPacket procUnMountAll(NFSSrvSession sess, RpcPacket rpc, - int version) { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[Mount] UnMountAll request from " + rpc.getClientDetails()); - - // Remove all the mount details for the specified host - - m_mounts.removeHostEntries(sess.getRemoteName()); - - // Build the RPC response - - rpc.buildResponseHeader(); - - // Return the RPC response - - return rpc; - } - - /** - * Process the export request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @param version - * int - * @return RpcPacket - */ - private final RpcPacket procExport(NFSSrvSession sess, RpcPacket rpc, - int version) { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[Mount] Export request from " + rpc.getClientDetails()); - - // Get the share list from the server - - SharedDeviceList shareList = sess.getServer().getShareMapper() - .getShareList(getConfiguration().getServerName(), sess, false); - - // Check if there is an access control manager configured - - if (sess.getServer().hasAccessControlManager()) { - - // Filter the list of available shares by applying any access - // control rules - - AccessControlManager aclMgr = sess.getServer().getAccessControlManager(); - - shareList = aclMgr.filterShareList(sess, shareList); - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Add the visible shares to the export list - - Enumeration enm = shareList.enumerateShares(); - - while (enm.hasMoreElements()) { - - // Get the current share - - SharedDevice share = (SharedDevice) enm.nextElement(); - - // Add to the list of exports if it is a disk type share - - if (share.getType() == ShareType.DISK) { - - // Pack the share details - - rpc.packInt(Rpc.True); - rpc.packString("/" + share.getName()); - - // No group information - - rpc.packInt(Rpc.False); - } - } - - // Mark the end of the list - - rpc.packInt(Rpc.False); - rpc.setLength(); - - // Return the response - - return rpc; - } - - /** - * Process the export all request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procExportAll(NFSSrvSession sess, RpcPacket rpc) { - return null; - } - - /** - * Create a temporary session for a request. There is no need to cache - * sessions in the mount server as usually only single requests are made. - * - * @param rpc - * RpcPacket - * @return NFSSrvSession - * @exception RpcAuthenticationException - */ - private final NFSSrvSession createTemporarySession(RpcPacket rpc) - throws RpcAuthenticationException { - - // Authenticate the request - - RpcAuthenticator rpcAuth = getConfiguration().getRpcAuthenticator(); - Object sessKey = rpcAuth.authenticateRpcClient( rpc.getCredentialsType(), rpc); - - // Create an NFS session for the request - - NFSSrvSession nfsSess = new NFSSrvSession(this, rpc.getClientAddress(), rpc.getClientPort(), rpc.getClientProtocol()); - - // Set the client information for the request - - nfsSess.setClientInformation(rpcAuth.getRpcClientInformation(sessKey, rpc)); - - // Return the session - - return nfsSess; - } - - /** - * Mount a path. Used by the mount server to validate a path and initialize - * any NFS resources - * - * @param sess - * NFSSrvSession - * @param path - * String - * @param handle - * byte[] - * @return int - */ - protected final int mountPath(NFSSrvSession sess, String path, byte[] handle) { - - // Debug - - if (logger.isDebugEnabled()) - logger.debug("MountPath path=" + path); - - // Parse the path into share and additional path components - - if (path.startsWith(UNIX_SEPERATOR) && path.length() >= 2) { - - // Split the path into share and any additional path - - String shareName = null; - String extraPath = null; - int shareId = -1; - - int pos = path.indexOf(UNIX_SEPERATOR, 1); - if (pos != -1) { - shareName = path.substring(1, pos); - extraPath = path.substring(pos); - } else { - shareName = path.substring(1); - } - - // Search for a share with the specified name - - SharedDevice share = null; - - try { - share = getConfiguration().getShareMapper().findShare( - getConfiguration().getServerName(), shareName, - ShareType.DISK, sess, false); - } - catch (Exception ex) { - } - - // Check if the share exists - - if (share != null) { - - // Check if there is an access control manager configured - - if (getConfiguration().hasAccessControlManager()) { - - // Check the access control to the shared filesystem - - AccessControlManager aclMgr = getConfiguration().getAccessControlManager(); - - if (aclMgr.checkAccessControl(sess, share) == AccessControl.NoAccess) { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Failed to mount path=" + path + ", access denied"); - - // Return a does not exist type error - - return Mount.StsNoEnt; - } - } - - // The share id is the hash of the share name - - shareId = shareName.hashCode(); - - // Check if there is an extra path to validate - - if (extraPath != null) { - - // Convert the path to an SMB share relative path - - extraPath = extraPath.replace(UNIX_SEPERATOR_CHAR, DOS_SEPERATOR_CHAR); - if (extraPath.endsWith(DOS_SEPERATOR)) - extraPath = extraPath.substring(0, extraPath.length() - 2); - - try { - - // Get the disk shared device - - TreeConnection conn = m_connections.findConnection(shareId); - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Validate the path - - FileInfo finfo = disk.getFileInformation(sess, conn, extraPath); - - if (finfo == null) - return Mount.StsNoEnt; - else if (finfo.isDirectory() == false) - return Mount.StsNotDir; - - // Fill in the handle for the directory - - NFSHandle.packDirectoryHandle(shareId, finfo.getFileId(), handle); - } - catch (Exception ex) { - } - } - else { - - // Fill in the handle using a share type handle - - NFSHandle.packShareHandle(share.getName(), handle); - } - - // Add a new entry to the active mount list - - m_mounts.addEntry(new MountEntry(sess.getRemoteName(), path)); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Mounted path=" + path + ", handle=" + NFSHandle.asString(handle)); - - // Return a success status - - return Mount.StsSuccess; - } else { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Failed to mount path=" + path); - - // Indicate that the share does not exist - - return Mount.StsNoEnt; - } - } - - // Return an invalid path error - - return Mount.StsNoEnt; - } - - /** - * Allocate a buffer for a file handle, the size depends on the RPC version - * - * @param version - * int - * @return byte[] - */ - private final byte[] allocateFileHandle(int version) { - byte[] handle = null; - if (version == 1) - handle = new byte[Mount.FileHandleSize1]; - else if (version == 3) - handle = new byte[Mount.FileHandleSize3]; - return handle; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadCookieException.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadCookieException.java deleted file mode 100644 index 68bfea1326..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadCookieException.java +++ /dev/null @@ -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.server.oncrpc.nfs; - -/** - * Bad Cookie Exception Class - * - * @author GKSpencer - */ -public class BadCookieException extends Exception { - - // Object version id - - private static final long serialVersionUID = -6689748925525944869L; - - /** - * Default constructor - */ - public BadCookieException() { - super(); - } - - /** - * Class constructor - * - * @param msg String - */ - public BadCookieException(String msg) { - super(msg); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadHandleException.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadHandleException.java deleted file mode 100644 index 4be2ee6a4c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/BadHandleException.java +++ /dev/null @@ -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.server.oncrpc.nfs; - -/** - * Bad Handle Exception Class - * - * @author GKSpencer - */ -public class BadHandleException extends Exception { - - // Object version id - - private static final long serialVersionUID = 5928520475130958599L; - - /** - * Default constructor - */ - public BadHandleException() { - super(); - } - - /** - * Class constructor - * - * @param msg String - */ - public BadHandleException(String msg) { - super(msg); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/FileIdCache.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/FileIdCache.java deleted file mode 100644 index 3b0f96c930..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/FileIdCache.java +++ /dev/null @@ -1,75 +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.server.oncrpc.nfs; - -import java.util.*; - -/** - * File Id Cache Class - * - *

Converts a file/directory id to a share relative path. - * - * @author GKSpencer - */ -public class FileIdCache { - - // File id to path cache - - private Hashtable m_idCache; - - /** - * Default constructor - */ - public FileIdCache() { - m_idCache = new Hashtable(); - } - - /** - * Add an entry to the cache - * - * @param fid int - * @param path String - */ - public final void addPath(int fid, String path) { - m_idCache.put(new Integer(fid), path); - } - - /** - * Convert a file id to a path - * - * @param fid int - * @return String - */ - public final String findPath(int fid) { - return (String) m_idCache.get(new Integer(fid)); - } - - /** - * Delete an entry from the cache - * - * @param fid int - */ - public final void deletePath(int fid) { - m_idCache.remove(new Integer(fid)); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFS.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFS.java deleted file mode 100644 index 62cb163c6f..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFS.java +++ /dev/null @@ -1,273 +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.server.oncrpc.nfs; - -/** - * NFS Server Constants Class - * - * @author GKSpencer - */ -public final class NFS { - - // Default NFS server port - - public static final int DefaultPort = 2049; - - // Program and version id - - public static final int ProgramId = 100003; - public static final int VersionId = 3; - - // RPC procedure ids - - public static final int ProcNull = 0; - public static final int ProcGetAttr = 1; - public static final int ProcSetAttr = 2; - public static final int ProcLookup = 3; - public static final int ProcAccess = 4; - public static final int ProcReadLink = 5; - public static final int ProcRead = 6; - public static final int ProcWrite = 7; - public static final int ProcCreate = 8; - public static final int ProcMkDir = 9; - public static final int ProcSymLink = 10; - public static final int ProcMkNode = 11; - public static final int ProcRemove = 12; - public static final int ProcRmDir = 13; - public static final int ProcRename = 14; - public static final int ProcLink = 15; - public static final int ProcReadDir = 16; - public static final int ProcReadDirPlus = 17; - public static final int ProcFsStat = 18; - public static final int ProcFsInfo = 19; - public static final int ProcPathConf = 20; - public static final int ProcCommit = 21; - public static final int ProcMax = 21; - - // NFS server status codes - - public static final int StsSuccess = 0; - public static final int StsPerm = 1; - public static final int StsNoEnt = 2; - public static final int StsIO = 5; - public static final int StsNxIO = 6; - public static final int StsAccess = 13; - public static final int StsExist = 17; - public static final int StsXDev = 18; - public static final int StsNoDev = 19; - public static final int StsNotDir = 20; - public static final int StsIsDir = 21; - public static final int StsInVal = 22; - public static final int StsFBig = 27; - public static final int StsNoSpc = 28; - public static final int StsROFS = 30; - public static final int StsMLink = 31; - public static final int StsNameTooLong = 63; - public static final int StsNotEmpty = 66; - public static final int StsDQuot = 69; - public static final int StsStale = 70; - public static final int StsRemote = 71; - public static final int StsBadHandle = 10001; - public static final int StsNotSync = 10002; - public static final int StsBadCookie = 10003; - public static final int StsNotSupp = 10004; - public static final int StsTooSmall = 10005; - public static final int StsServerFault = 10006; - public static final int StsBadType = 10007; - public static final int StsJukeBox = 10008; - - // Data structure limits - - public static final int FileHandleSize = 32; // can be 64 for NFS v3 - public static final int WriteVerfSize = 8; - public static final int CreateVerfSize = 8; - public static final int CookieVerfSize = 8; - - // File types - - public static final int FileTypeReg = 1; - public static final int FileTypeDir = 2; - public static final int FileTypeBlk = 3; - public static final int FileTypeChr = 4; - public static final int FileTypeLnk = 5; - public static final int FileTypeSock = 6; - public static final int FileTypeFifo = 7; - - // Filesystem properties - - public static final int FileSysLink = 0x0001; // supports hard links - public static final int FileSysSymLink = 0x0002; // supports symbolic links - public static final int FileSysHomogeneuos = 0x0004; // PATHCONF valid for all files - public static final int FileSysCanSetTime = 0x0008; // can set time on server side - - // Access mask - - public static final int AccessRead = 0x0001; - public static final int AccessLookup = 0x0002; - public static final int AccessModify = 0x0004; - public static final int AccessExtend = 0x0008; - public static final int AccessDelete = 0x0010; - public static final int AccessExecute = 0x0020; - public static final int AccessAll = 0x003F; - - // Create mode values - - public static final int CreateUnchecked = 1; - public static final int CreateGuarded = 2; - public static final int CreateExclusive = 3; - - // Write request stable values - - public static final int WriteUnstable = 0; - public static final int WriteDataSync = 1; - public static final int WriteFileSync = 2; - - // Set attributes file timestamp settings - - public static final int DoNotSetTime = 0; - public static final int SetTimeServer = 1; - public static final int SetTimeClient = 2; - - // RPC procedure names - - private static final String[] _procNames = { "Null", "GetAttr", "SetAttr", - "Lookup", "Access", "ReadLink", "Read", "Write", "Create", "MkDir", - "SymLink", "MkNode", "Remove", "RmDir", "Rename", "Link", - "ReadDir", "ReadDirPlus", "FsStat", "FsInfo", "PathConf", "Commit" }; - - /** - * Return a procedure id as a name - * - * @param id - * int - * @return String - */ - public final static String getProcedureName(int id) { - if (id < 0 || id > ProcMax) - return null; - return _procNames[id]; - } - - /** - * Return an error status string for the specified status code - * - * @param sts - * int - * @return String - */ - public static final String getStatusString(int sts) { - String str = null; - - switch (sts) { - case StsSuccess: - str = "Success status"; - break; - case StsAccess: - str = "Access denied"; - break; - case StsBadCookie: - str = "Bad cookie"; - break; - case StsBadHandle: - str = "Bad handle"; - break; - case StsBadType: - str = "Bad type"; - break; - case StsDQuot: - str = "Quota exceeded"; - break; - case StsPerm: - str = "No permission"; - break; - case StsExist: - str = "Already exists"; - break; - case StsFBig: - str = "File too large"; - break; - case StsInVal: - str = "Invalid argument"; - break; - case StsIO: - str = "I/O error"; - break; - case StsIsDir: - str = "Is directory"; - break; - case StsJukeBox: - str = "Jukebox"; - break; - case StsMLink: - str = "Too many hard links"; - break; - case StsNameTooLong: - str = "Name too long"; - break; - case StsNoDev: - str = "No such device"; - break; - case StsNoEnt: - str = "No entity"; - break; - case StsNoSpc: - str = "No space left on device"; - break; - case StsNotSync: - str = "Update synchronization mismatch"; - break; - case StsNotDir: - str = "Not directory"; - break; - case StsNotEmpty: - str = "Not empty"; - break; - case StsNotSupp: - str = "Not supported"; - break; - case StsNxIO: - str = "Nxio"; - break; - case StsRemote: - str = "Too many levels of remote in path"; - break; - case StsROFS: - str = "Readonly filesystem"; - break; - case StsServerFault: - str = "Server fault"; - break; - case StsStale: - str = "Stale"; - break; - case StsTooSmall: - str = "Too small"; - break; - case StsXDev: - str = "Cross device hard link attempted"; - break; - } - - return str; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSHandle.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSHandle.java deleted file mode 100644 index dc60dc1b5e..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSHandle.java +++ /dev/null @@ -1,423 +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.server.oncrpc.nfs; - -import org.alfresco.filesys.server.oncrpc.RpcPacket; -import org.alfresco.filesys.util.DataPacker; - -/** - * NFS Handle Class - * - *

Contains constants and static methods used with NFS handles. - * - * @author GKSpencer - */ -public class NFSHandle { - - // Version - - public static final byte VERSION = 1; - public static final byte MIN_VERSION = 1; - public static final byte MAX_VERSION = 1; - - // Handle types - - public static final byte TYPE_SHARE = 1; - public static final byte TYPE_DIR = 2; - public static final byte TYPE_FILE = 3; - - // Offsets to fields within the handle - - private static final int VERSION_OFFSET = 0; - private static final int TYPE_OFFSET = 1; - private static final int SHARE_OFFSET = 2; - private static final int DIR_OFFSET = 6; - private static final int FILE_OFFSET = 10; - private static final int NAME_OFFSET = 14; - - /** - * Return the handle version - * - * @param handle byte[] - */ - public static final int isVersion(byte[] handle) - { - return (int) handle[0]; - } - - /** - * Return the handle type - * - * @param handle byte[] - * @return int - */ - public static final int isType(byte[] handle) - { - return (int) handle[1]; - } - - /** - * Check if the handle is a share type handle - * - * @param handle byte[] - * @return boolean - */ - public static final boolean isShareHandle(byte[] handle) - { - if (handle[1] == TYPE_SHARE) - return true; - return false; - } - - /** - * Check if the handle is a directory type handle - * - * @param handle byte[] - * @return boolean - */ - public static final boolean isDirectoryHandle(byte[] handle) - { - if (handle[1] == TYPE_DIR) - return true; - return false; - } - - /** - * Check if the handle is a file type handle - * - * @param handle byte[] - * @return boolean - */ - public static final boolean isFileHandle(byte[] handle) - { - if (handle[1] == TYPE_FILE) - return true; - return false; - } - - /** - * Pack a share handle - * - * @param name String - * @param handle byte[] - */ - public static final void packShareHandle(String name, byte[] handle) - { - - // Pack a share handle - - handle[0] = VERSION; - handle[1] = TYPE_SHARE; - - // Pack the hash code of the share name - - DataPacker.putInt(name.hashCode(), handle, SHARE_OFFSET); - - // Null pad the handle - - int pos = SHARE_OFFSET + 4; - - while (pos < handle.length) - handle[pos++] = 0; - } - - /** - * Pack a share handle - * - * @param name String - * @param rpc RpcPacket - * @param hlen int - */ - public static final void packShareHandle(String name, RpcPacket rpc, int hlen) - { - - // Pack a share handle - - rpc.packInt(hlen); - - rpc.packByte(VERSION); - rpc.packByte(TYPE_SHARE); - - // Pack the hash code of the share name - - rpc.packInt(name.hashCode()); - - // Null pad the handle - - rpc.packNulls(hlen - 6); - } - - /** - * Pack a directory handle - * - * @param shareId int - * @param dirId int - * @param handle byte[] - */ - public static final void packDirectoryHandle(int shareId, int dirId, byte[] handle) - { - - // Pack a directory handle - - handle[0] = VERSION; - handle[1] = TYPE_DIR; - - DataPacker.putInt(shareId, handle, 2); - DataPacker.putInt(dirId, handle, 6); - - // Null pad the handle - - for (int i = 10; i < handle.length; i++) - handle[i] = 0; - } - - /** - * Pack a directory handle - * - * @param shareId int - * @param dirId int - * @param rpc RpcPacket - * @param hlen int - */ - public static final void packDirectoryHandle(int shareId, int dirId, RpcPacket rpc, int hlen) - { - - // Pack a directory handle - - rpc.packInt(hlen); - - rpc.packByte(VERSION); - rpc.packByte(TYPE_DIR); - - rpc.packInt(shareId); - rpc.packInt(dirId); - - // Null pad the handle - - rpc.packNulls(hlen - 10); - } - - /** - * Pack a file handle - * - * @param shareId int - * @param dirId int - * @param fileId int - * @param handle byte[] - */ - public static final void packFileHandle(int shareId, int dirId, int fileId, byte[] handle) - { - - // Pack a directory handle - - handle[0] = VERSION; - handle[1] = TYPE_FILE; - - DataPacker.putInt(shareId, handle, 2); - DataPacker.putInt(dirId, handle, 6); - DataPacker.putInt(fileId, handle, 10); - - // Null pad the handle - - for (int i = 14; i < handle.length; i++) - handle[i] = 0; - } - - /** - * Pack a file handle - * - * @param shareId int - * @param dirId int - * @param fileId int - * @param rpc RpcPacket - * @param hlen int - */ - public static final void packFileHandle(int shareId, int dirId, int fileId, RpcPacket rpc, int hlen) - { - - // Pack a directory handle - - rpc.packInt(hlen); - - rpc.packByte(VERSION); - rpc.packByte(TYPE_FILE); - - rpc.packInt(shareId); - rpc.packInt(dirId); - rpc.packInt(fileId); - - // Null pad the handle - - rpc.packNulls(hlen - 14); - } - - /** - * Unpack a share id from a handle - * - * @param handle byte[] - * @return int - */ - public static final int unpackShareId(byte[] handle) - { - - // Check if the handle is a share type handle - - int shareId = -1; - - if (handle[1] == TYPE_SHARE || handle[1] == TYPE_DIR || handle[1] == TYPE_FILE) - { - - // Unpack the share id - - shareId = DataPacker.getInt(handle, 2); - } - - // Return the share id, or -1 if wrong handle type - - return shareId; - } - - /** - * Unpack a directory id from a handle - * - * @param handle byte[] - * @return int - */ - public static final int unpackDirectoryId(byte[] handle) - { - - // Check if the handle is a directory or file type handle - - int dirId = -1; - - if (handle[1] == TYPE_DIR || handle[1] == TYPE_FILE) - { - - // Unpack the directory id - - dirId = DataPacker.getInt(handle, 6); - } - - // Return the directory id, or -1 if wrong handle type - - return dirId; - } - - /** - * Unpack a file id from a handle - * - * @param handle byte[] - * @return int - */ - public static final int unpackFileId(byte[] handle) - { - - // Check if the handle is a file type handle - - int fileId = -1; - - if (handle[1] == TYPE_FILE) - { - - // Unpack the file id - - fileId = DataPacker.getInt(handle, 10); - } - - // Return the file id, or -1 if wrong handle type - - return fileId; - } - - /** - * Return an NFS handle as a string - * - * @param handle byte[] - * @return String - */ - public static final String asString(byte[] handle) - { - - // Check if the handle is a valid type - - StringBuffer str = new StringBuffer(); - str.append("["); - - switch (handle[1]) - { - - // Share/mountpoint type handle - - case TYPE_SHARE: - str.append("Share:0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 2))); - break; - - // Directory handle - - case TYPE_DIR: - str.append("Dir:share=0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 2))); - str.append(",dir=0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 6))); - break; - - // File handle - - case TYPE_FILE: - str.append("File:share=0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 2))); - str.append(",dir=0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 6))); - str.append(",file=0x"); - str.append(Integer.toHexString(DataPacker.getInt(handle, 10))); - break; - } - - // Return the handle string - - str.append("]"); - return str.toString(); - } - - /** - * Check if a handle is valid - * - * @param handle byte[] - * @return boolean - */ - public static final boolean isValid(byte[] handle) - { - - // Check if the version is valid - - if (handle[0] < MIN_VERSION || handle[0] > MAX_VERSION) - return false; - - // Check if the handle type is valid - - if (handle[1] == TYPE_SHARE || handle[1] == TYPE_DIR || handle[1] == TYPE_FILE) - return true; - return false; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSServer.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSServer.java deleted file mode 100644 index 2a2a7c9b0f..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSServer.java +++ /dev/null @@ -1,5126 +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.server.oncrpc.nfs; - -import java.io.*; -import java.util.*; - -import org.alfresco.filesys.server.ServerListener; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -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.AccessDeniedException; -import org.alfresco.filesys.server.filesys.AccessMode; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskFullException; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.DiskSizeInterface; -import org.alfresco.filesys.server.filesys.FileAction; -import org.alfresco.filesys.server.filesys.FileAttribute; -import org.alfresco.filesys.server.filesys.FileExistsException; -import org.alfresco.filesys.server.filesys.FileIdInterface; -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.FileType; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.NotifyChange; -import org.alfresco.filesys.server.filesys.SearchContext; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.SymbolicLinkInterface; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.TreeConnectionHash; -import org.alfresco.filesys.server.oncrpc.AuthType; -import org.alfresco.filesys.server.oncrpc.MultiThreadedTcpRpcSessionHandler; -import org.alfresco.filesys.server.oncrpc.MultiThreadedUdpRpcDatagramHandler; -import org.alfresco.filesys.server.oncrpc.PortMapping; -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.RpcNetworkServer; -import org.alfresco.filesys.server.oncrpc.RpcPacket; -import org.alfresco.filesys.server.oncrpc.RpcPacketPool; -import org.alfresco.filesys.server.oncrpc.RpcProcessor; -import org.alfresco.filesys.server.oncrpc.RpcRequestThreadPool; - -/** - * NFS Server Class - * - *

Contains the main NFS server. - * - * @author GKSpencer - */ -public class NFSServer extends RpcNetworkServer implements RpcProcessor { - - // Constants - // - // Debug flags - - public static final int DBG_RXDATA = 0x00000001; // Received data - public static final int DBG_TXDATA = 0x00000002; // Transmit data - public static final int DBG_DUMPDATA = 0x00000004; // Dump data packets - public static final int DBG_SEARCH = 0x00000008; // File/directory search - public static final int DBG_INFO = 0x00000010; // Information requests - public static final int DBG_FILE = 0x00000020; // File open/close/info - public static final int DBG_FILEIO = 0x00000040; // File read/write - public static final int DBG_ERROR = 0x00000080; // Errors - public static final int DBG_TIMING = 0x00000100; // Time packet processing - public static final int DBG_DIRECTORY = 0x00000200; // Directory commands - public static final int DBG_SESSION = 0x00000400; // Session creation/deletion - - // Unix path seperator - - public static final String UNIX_SEPERATOR = "/"; - public static final char UNIX_SEPERATOR_CHAR = '/'; - public static final String DOS_SEPERATOR = "\\"; - public static final char DOS_SEPERATOR_CHAR = '\\'; - - // Unix file modes - - public static final int MODE_STFILE = 0100000; - public static final int MODE_STDIR = 0040000; - public static final int MODE_STREAD = 0000555; - public static final int MODE_STWRITE = 0000333; - public static final int MODE_DIR_DEFAULT = MODE_STDIR + (MODE_STREAD | MODE_STWRITE); - public static final int MODE_FILE_DEFAULT = MODE_STFILE + (MODE_STREAD | MODE_STWRITE); - - // Readdir/Readdirplus cookie masks/shift - // - // 32bit cookies (required by Solaris) - - public static final long COOKIE_RESUMEID_MASK = 0x00FFFFFFL; - public static final long COOKIE_SEARCHID_MASK = 0xFF000000L; - public static final int COOKIE_SEARCHID_SHIFT = 24; - - // Cookie ids for . and .. directory entries - - public static final long COOKIE_DOT_DIRECTORY = 0x00FFFFFFL; - public static final long COOKIE_DOTDOT_DIRECTORY = 0x00FFFFFEL; - - // ReadDir and ReadDirPlus reply header and per file fixed structure - // lengths. - // - // Add file name length rounded to 4 byte boundary to the per file structure - // length to get the actual length. - - public final static int READDIRPLUS_HEADER_LENGTH = 108; - public final static int READDIRPLUS_ENTRY_LENGTH = 200; - public final static int READDIR_HEADER_LENGTH = 108; - public final static int READDIR_ENTRY_LENGTH = 24; - - // File id offset - - public static final long FILE_ID_OFFSET = 2L; - - // Maximum request size to accept - - public final static int MaxRequestSize = 0xFFFF; - - // Filesystem limits - - public static final int MaxReadSize = MaxRequestSize; - public static final int PrefReadSize = MaxRequestSize; - public static final int MultReadSize = 4096; - public static final int MaxWriteSize = MaxRequestSize; - public static final int PrefWriteSize = MaxRequestSize; - public static final int MultWriteSize = 4096; - public static final int PrefReadDirSize = 8192; - public static final long MaxFileSize = 0x01FFFFFFF000L; - - // Thread pool and packet pool defaults - - private static final int DefaultThreadPoolSize = 8; - private static final int DefaultPacketPoolSize = 50; - - // Incoming datagram handler for UDP requests - - private MultiThreadedUdpRpcDatagramHandler m_udpHandler; - - // Incoming session handler for TCP requests - - private MultiThreadedTcpRpcSessionHandler m_tcpHandler; - - // Share details hash - - private ShareDetailsHash m_shareDetails; - - // Tree connection hash - - private TreeConnectionHash m_connections; - - // Session tables for the various authentication types - - private NFSSessionTable m_sessAuthNull; - - private NFSSessionTable m_sessAuthUnix; - - // Session id generator - - private int m_sessId = 1; - - // Port to bind the NFS server to (UDP and TCP) - - private int m_port; - - // Shared thread pool, used by TCP and UDP request handlers - - private RpcRequestThreadPool m_threadPool; - - // Shared packet pool, usd by TCP and UDP request handlers - - private RpcPacketPool m_packetPool; - - // RPC authenticator, from the main server configuration - - private RpcAuthenticator m_rpcAuthenticator; - - // Write verifier, generated from the server start time - - private long m_writeVerifier; - - /** - * Class constructor - * - * @param config - * ServerConfiguration - */ - public NFSServer(ServerConfiguration config) { - super("NFS", config); - - // Set the debug flags - - setDebugFlags(config.getNFSDebug()); - - // Set the port to bind the server to - - if (config.getNFSServerPort() != 0) - setPort(config.getNFSServerPort()); - else - setPort(NFS.DefaultPort); - - // Set the RPC authenticator - - m_rpcAuthenticator = config.getRpcAuthenticator(); - - // Generate the write verifier - - m_writeVerifier = System.currentTimeMillis(); - } - - /** - * Return the port to bind to - * - * @return int - */ - public final int getPort() { - return m_port; - } - - /** - * Set the port to use - * - * @param port - * int - */ - public final void setPort(int port) { - m_port = port; - } - - /** - * Start the NFS server - */ - public void startServer() { - - try { - - // Allocate the share detail hash list and tree connection list, and - // populate with the available share details - - m_shareDetails = new ShareDetailsHash(); - m_connections = new TreeConnectionHash(); - - checkForNewShares(); - - // Get the thread pool and packet pool sizes - - int threadPoolSize = DefaultThreadPoolSize; - - if (getConfiguration().getNFSThreadPoolSize() > 0) - threadPoolSize = getConfiguration().getNFSThreadPoolSize(); - - int packetPoolSize = DefaultPacketPoolSize; - - if (getConfiguration().getNFSPacketPoolSize() > 0) - packetPoolSize = getConfiguration().getNFSPacketPoolSize(); - - // Create the share thread pool for RPC processing - - m_threadPool = new RpcRequestThreadPool("NFS", threadPoolSize, this); - - // Create the shared packet pool - - m_packetPool = new RpcPacketPool(MaxRequestSize, packetPoolSize); - - // Create the UDP handler for accepting incoming requests - - m_udpHandler = new MultiThreadedUdpRpcDatagramHandler("Nfsd", "Nfs", this, this, null, getPort(), MaxRequestSize); - - // Use the shared thread pool and packet pool - - m_udpHandler.setThreadPool(m_threadPool); - m_udpHandler.setPacketPool(m_packetPool); - - m_udpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread udpThread = new Thread(m_udpHandler); - udpThread.setName("NFS_UDP"); - udpThread.start(); - - // Create the TCP handler for accepting incoming requests - - m_tcpHandler = new MultiThreadedTcpRpcSessionHandler("Nfsd", "Nfs", - this, this, null, getPort(), MaxRequestSize); - - // Use the shared thread pool and packet pool - - m_tcpHandler.setThreadPool(m_threadPool); - m_tcpHandler.setPacketPool(m_packetPool); - - m_tcpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread tcpThread = new Thread(m_tcpHandler); - tcpThread.setName("NFS_TCP"); - tcpThread.start(); - - // Register the NFS server with the portmapper - - PortMapping[] mappings = new PortMapping[2]; - mappings[0] = new PortMapping(NFS.ProgramId, NFS.VersionId, Rpc.UDP, m_udpHandler.getPort()); - mappings[1] = new PortMapping(NFS.ProgramId, NFS.VersionId, Rpc.TCP, m_tcpHandler.getPort()); - - registerRPCServer(mappings); - } - catch (Exception ex) { - logger.error(ex); - } - } - - /** - * Shutdown the NFS server - * - * @param immediate - * boolean - */ - public void shutdownServer(boolean immediate) { - - // Unregister the NFS server with the portmapper - - try { - PortMapping[] mappings = new PortMapping[2]; - mappings[0] = new PortMapping(NFS.ProgramId, NFS.VersionId, Rpc.UDP, m_udpHandler.getPort()); - mappings[1] = new PortMapping(NFS.ProgramId, NFS.VersionId, Rpc.TCP, m_tcpHandler.getPort()); - - unregisterRPCServer(mappings); - } - catch (IOException ex) { - logger.error(ex); - } - - // Stop the RPC handlers - - if (m_udpHandler != null) { - m_udpHandler.closeSessionHandler(this); - m_udpHandler = null; - } - - if (m_tcpHandler != null) { - m_tcpHandler.closeSessionHandler(this); - m_tcpHandler = null; - } - - // Stop the thread pool - - m_threadPool.shutdownThreadPool(); - - // Fire a shutdown notification event - - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Process an RPC request to the NFS or mount server - * - * @param rpc - * RpcPacket - * @return RpcPacket - * @throws IOException - */ - public RpcPacket processRpc(RpcPacket rpc) throws IOException { - - // Dump the request data - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DUMPDATA)) - logger.debug("NFS Req=" + rpc.toString()); - - // Validate the request - - int version = rpc.getProgramVersion(); - - if (rpc.getProgramId() != NFS.ProgramId) { - - // Request is not for us - - rpc.buildAcceptErrorResponse(Rpc.StsProgUnavail); - return rpc; - } - else if (version != NFS.VersionId) { - - // Request is not for this version of NFS - - rpc.buildProgramMismatchResponse(NFS.VersionId, NFS.VersionId); - return rpc; - } - - // Find the associated session object for the request, or create a new - // session - - NFSSrvSession nfsSess = null; - - try { - - // Find the associated session, or create a new session - - nfsSess = findSessionForRequest(rpc); - } - catch (RpcAuthenticationException ex) { - - // Failed to authenticate the RPC client, return an error unless the request is the 'null' request - - if ( rpc.getProcedureId() != NFS.ProcNull) - { - rpc.buildAuthFailResponse(ex.getAuthenticationErrorCode()); - return rpc; - } - } - - // Position the RPC buffer pointer at the start of the call parameters - - rpc.positionAtParameters(); - - // Process the RPC request - - RpcPacket response = null; - - try - { - switch (rpc.getProcedureId()) { - - // Null request - - case NFS.ProcNull: - response = procNull(nfsSess, rpc); - break; - - // Get attributes request - - case NFS.ProcGetAttr: - response = procGetAttr(nfsSess, rpc); - break; - - // Set attributes request - - case NFS.ProcSetAttr: - response = procSetAttr(nfsSess, rpc); - break; - - // Lookup request - - case NFS.ProcLookup: - response = procLookup(nfsSess, rpc); - break; - - // Access request - - case NFS.ProcAccess: - response = procAccess(nfsSess, rpc); - break; - - // Read symbolic link request - - case NFS.ProcReadLink: - response = procReadLink(nfsSess, rpc); - break; - - // Read file request - - case NFS.ProcRead: - response = procRead(nfsSess, rpc); - break; - - // Write file request - - case NFS.ProcWrite: - response = procWrite(nfsSess, rpc); - break; - - // Create file request - - case NFS.ProcCreate: - response = procCreate(nfsSess, rpc); - break; - - // Create directory request - - case NFS.ProcMkDir: - response = procMkDir(nfsSess, rpc); - break; - - // Create symbolic link request - - case NFS.ProcSymLink: - response = procSymLink(nfsSess, rpc); - break; - - // Create special device request - - case NFS.ProcMkNode: - response = procMkNode(nfsSess, rpc); - break; - - // Delete file request - - case NFS.ProcRemove: - response = procRemove(nfsSess, rpc); - break; - - // Delete directory request - - case NFS.ProcRmDir: - response = procRmDir(nfsSess, rpc); - break; - - // Rename request - - case NFS.ProcRename: - response = procRename(nfsSess, rpc); - break; - - // Create hard link request - - case NFS.ProcLink: - response = procLink(nfsSess, rpc); - break; - - // Read directory request - - case NFS.ProcReadDir: - response = procReadDir(nfsSess, rpc); - break; - - // Read directory plus request - - case NFS.ProcReadDirPlus: - response = procReadDirPlus(nfsSess, rpc); - break; - - // Filesystem status request - - case NFS.ProcFsStat: - response = procFsStat(nfsSess, rpc); - break; - - // Filesystem information request - - case NFS.ProcFsInfo: - response = procFsInfo(nfsSess, rpc); - break; - - // Retrieve POSIX information request - - case NFS.ProcPathConf: - response = procPathConf(nfsSess, rpc); - break; - - // Commit request - - case NFS.ProcCommit: - response = procCommit(nfsSess, rpc); - break; - } - - // Dump the response - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DUMPDATA)) - logger.debug("NFS Resp=" + (rpc != null ? rpc.toString() : "")); - - // Commit, or rollback, any active user transaction - - if ( nfsSess != null) - { - try - { - // Commit or rollback the transaction - - nfsSess.endTransaction(); - } - catch ( Exception ex) - { - // Debug - - if ( logger.isDebugEnabled()) - logger.debug("Error committing transaction", ex); - } - } - } - finally - { - // If there is an active transaction then roll it back - - if ( nfsSess != null && nfsSess.hasUserTransaction()) - { - try - { - nfsSess.getUserTransaction().rollback(); - } - catch (Exception ex) - { - logger.warn("Failed to rollback transaction", ex); - } - } - } - - // Return the RPC response - - return response; - } - - /** - * Process the null request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procNull(NFSSrvSession sess, RpcPacket rpc) { - - // Build the response - - rpc.buildResponseHeader(); - return rpc; - } - - /** - * Process the get attributes request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procGetAttr(NFSSrvSession sess, RpcPacket rpc) { - - // Get the handle from the request - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("GetAttr request from " + rpc.getClientDetails() - + ", handle=" + NFSHandle.asString(handle)); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - - // Return an error status - - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Check if this is a share handle - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - // Call the disk share driver to get the file information for the path - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the file information for the specified path - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - if (finfo != null) { - - // Pack the file information into the NFS attributes structure - - rpc.packInt(NFS.StsSuccess); - packAttributes3(rpc, finfo, shareId); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("GetAttr path=" + path + ", info=" - + finfo); - } - } catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("GetAttr Exception: " + ex.toString()); - logger.debug(ex); - } - - // Error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("GetAttr error=" - + NFS.getStatusString(errorSts)); - } - - // Return the attributes - - rpc.setLength(); - return rpc; - } - - /** - * Process the set attributes request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procSetAttr(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the set attributes parameters - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("SetAttr request from " + rpc.getClientDetails()); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Check if this is a share handle - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - // Call the disk share driver to get the file information for the path - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the current file information - - FileInfo oldInfo = disk.getFileInformation(sess, conn, path); - - // Get the values to be set for the file/folder - - int setFlags = 0; - int gid = -1; - int uid = -1; - int mode = -1; - long fsize = -1L; - long atime = -1L; - long mtime = -1L; - - // Check if the file mode has been specified - - if (rpc.unpackInt() == Rpc.True) { - mode = rpc.unpackInt(); - setFlags += FileInfo.SetMode; - } - - // Check if the file owner uid has been specified - - if (rpc.unpackInt() == Rpc.True) { - uid = rpc.unpackInt(); - setFlags += FileInfo.SetUid; - } - - // Check if the file group gid has been specified - - if (rpc.unpackInt() == Rpc.True) { - gid = rpc.unpackInt(); - setFlags += FileInfo.SetGid; - } - - // Check if a new file size has been specified - - if (rpc.unpackInt() == Rpc.True) { - fsize = rpc.unpackLong(); - setFlags += FileInfo.SetFileSize; - } - - // Check if the access date/time should be set. It may be set to a - // client specified time - // or using the server time - - int setTime = rpc.unpackInt(); - - if (setTime == NFS.SetTimeClient) { - atime = (long) rpc.unpackInt(); - atime *= 1000L; - rpc.skipBytes(4); // nanoseconds - setFlags += FileInfo.SetAccessDate; - } else if (setTime == NFS.SetTimeServer) { - atime = System.currentTimeMillis(); - setFlags += FileInfo.SetAccessDate; - } - - // Check if the modify date/time should be set. It may be set to a - // client specified time - // or using the server time - - setTime = rpc.unpackInt(); - - if (setTime == NFS.SetTimeClient) { - mtime = (long) rpc.unpackInt(); - mtime *= 1000L; - rpc.skipBytes(4); // nanoseconds - setFlags += FileInfo.SetModifyDate; - } else if (setTime == NFS.SetTimeServer) { - mtime = System.currentTimeMillis(); - setFlags += FileInfo.SetModifyDate; - } - - // Check if any of the file times should be updated - - if (setFlags != 0) { - - // Set the file access/modify date/times - - FileInfo finfo = new FileInfo(); - finfo.setFileInformationFlags(setFlags); - - if (atime != -1L) - finfo.setAccessDateTime(atime); - - if (mtime != -1L) - finfo.setModifyDateTime(mtime); - - // Check if the group id should be set - - if (gid != -1) { - - // Set the group id in the file information - - finfo.setGid(gid); - } - - // Check if the user id should be set - - if (uid != -1) { - - // Set the user id in the file information - - finfo.setUid(uid); - } - - // Check if the mode should be set - - if (mode != -1) { - - // Set the mode in the file information - - finfo.setMode(mode); - } - - // Set the file information - - disk.setFileInformation(sess, conn, path, finfo); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("SetAttr handle=" - + NFSHandle.asString(handle) + ", accessTime=" - + finfo.getAccessDateTime() + ", modifyTime=" - + finfo.getModifyDateTime() + ", mode=" + mode - + ", gid/uid=" + gid + "/" + uid); - } - - // Check if the file size should be updated - - if (fsize != -1L) { - - // Open the file, may be cached - - NetworkFile netFile = getNetworkFileForHandle(sess, handle, - conn, false); - - synchronized (netFile) { - - // Open the network file - - netFile.openFile(false); - - // Change the file size - - disk.truncateFile(sess, conn, netFile, fsize); - - // Close the file - - netFile.close(); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("SetAttr handle=" + NFSHandle.asString(handle) + ", newSize=" + fsize); - } - - // Get the updated file information - - FileInfo newInfo = disk.getFileInformation(sess, conn, path); - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packWccData(rpc, oldInfo); - packPostOpAttr(sess, newInfo, shareId, rpc); - } catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } catch (DiskFullException ex) { - errorSts = NFS.StsDQuot; - } catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("SetAttr Exception: " + ex.toString()); - } - - // Check for a failure status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("SetAttr error=" - + NFS.getStatusString(errorSts)); - } - - // Return a the set status - - rpc.setLength(); - return rpc; - } - - /** - * Process the lookup request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procLookup(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the lookup arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String fileName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("Lookup request from " + rpc.getClientDetails() + ", handle=" + NFSHandle.asString(handle) + ", name=" + fileName); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Call the disk share driver to get the file information for the path - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Build the full path string - - String lookupPath = generatePath(path, fileName); - - // Check if the file/directory exists - - if (disk.fileExists(sess, conn, lookupPath) != FileStatus.NotExist) { - - // Get file information for the path - - FileInfo finfo = disk - .getFileInformation(sess, conn, lookupPath); - - if (finfo != null) { - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - // Pack the file handle - - if (finfo.isDirectory()) - NFSHandle.packDirectoryHandle(shareId, finfo.getFileId(), rpc, NFS.FileHandleSize); - else - NFSHandle.packFileHandle(shareId, getFileIdForHandle(handle), finfo.getFileId(), rpc, NFS.FileHandleSize); - - // Pack the file attributes - - packPostOpAttr(sess, finfo, shareId, rpc); - - // Add a cache entry for the path - - ShareDetails details = m_shareDetails.findDetails(shareId); - - details.getFileIdCache().addPath(finfo.getFileId(), - lookupPath); - - // Check if the file path is a file name only, if so then - // get the parent directory details - - if (pathHasDirectories(fileName) == false - || fileName.equals("..")) { - - // Get the parent directory file information - - FileInfo dirInfo = disk.getFileInformation(sess, conn, - path); - packPostOpAttr(sess, dirInfo, shareId, rpc); - - // Add the path to the file id cache, if the filesystem - // does not support id lookups - - if (details.hasFileIdSupport() == false) - details.getFileIdCache().addPath(dirInfo.getFileId(), path); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("Lookup path=" + lookupPath + ", finfo=" + finfo.toString()); - } - } else { - - // File does not exist - - errorSts = NFS.StsNoEnt; - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Lookup Exception: " + ex.toString()); - } - - // Check if an error is being returned - - if (errorSts != NFS.StsSuccess) { - - // Pack the response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Lookup error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the access request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procAccess(NFSSrvSession sess, RpcPacket rpc) { - - // Get the parameters from the request - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - int accessMode = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("Access request from " + rpc.getClientDetails() - + ", handle=" + NFSHandle.asString(handle) + ", access=0x" - + Integer.toHexString(accessMode)); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - - // Return an error status - - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Check if this is a share handle - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - // Call the disk share driver to get the file information for the path - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the specified path - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - if (finfo != null) { - - // Check the access that the session has to the filesystem - - int mask = 0; - - if (conn.hasWriteAccess()) { - - // Set the mask to allow all operations - - mask = NFS.AccessAll; - } - else if (conn.hasReadAccess()) { - - // Set the mask for read-only operations - - mask = NFS.AccessRead + NFS.AccessLookup + NFS.AccessExecute; - } - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packPostOpAttr(sess, finfo, shareId, rpc); - rpc.packInt(accessMode & mask); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("Access path=" + path + ", info=" + finfo); - } else { - - // Return an error status - - errorSts = NFS.StsNoEnt; - } - } catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Access3 Exception: " + ex.toString()); - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Access error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the read link request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procReadLink(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the read link arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Call the disk share driver to read the symbolic link data - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - - TreeConnection conn = getTreeConnection(sess, shareId); - path = getPathForHandle(sess, handle, conn); - - // Check if the filesystem supports symbolic links - - if ((conn.getInterface() instanceof SymbolicLinkInterface) == false) { - - // Symbolic links not supported on this filesystem - - rpc.buildErrorResponse(NFS.StsNotSupp); - packPostOpAttr(sess, null, 0, rpc); - packWccData(rpc, null); - - rpc.setLength(); - return rpc; - } - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the file information for the symbolic link - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - if (finfo != null && finfo.isFileType() == FileType.SymbolicLink) { - - // Get the symbolic link data - - SymbolicLinkInterface symLinkInterface = (SymbolicLinkInterface) disk; - String linkData = symLinkInterface.readSymbolicLink(sess, conn, - path); - - // Pack the read link response - - rpc.packInt(NFS.StsSuccess); - packPostOpAttr(sess, finfo, shareId, rpc); - rpc.packString(linkData); - } else { - - // Return an error status, not a symbolic link - - errorSts = NFS.StsInVal; - } - - } catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("ReadLink Exception: " + ex.toString()); - } - - // Error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("ReadLink error=" - + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the read file request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procRead(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the read parameters - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - long offset = rpc.unpackLong(); - int count = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILEIO)) - logger.debug("[NFS] Read request " + rpc.getClientDetails() - + ", count=" + count + ", pos=" + offset); - - // Call the disk share driver to read the file - - int shareId = -1; - NetworkFile netFile = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and associated shared device - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the network file, it may be cached - - netFile = getNetworkFileForHandle(sess, handle, conn, true); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Pack the start of the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - // Get file information for the path and pack into the reply - - FileInfo finfo = disk.getFileInformation(sess, conn, netFile.getFullName()); - packPostOpAttr(sess, finfo, shareId, rpc); - - // Save the current position in the response buffer to fill in the - // length and end of file flag after - // the read. - - int bufPos = rpc.getPosition(); - - // Read the network file - - int rdlen = -1; - - synchronized (netFile) { - - // Make sure the network file is open - - if (netFile.isClosed()) - netFile.openFile(false); - - // Read a block of data from the file - - rdlen = disk.readFile(sess, conn, netFile, rpc.getBuffer(), - bufPos + 12, count, offset); - } - - // Set the read length and end of file flag - - rpc.packInt(rdlen); - rpc.packInt(rdlen < count ? Rpc.True : Rpc.False); - rpc.packInt(rdlen); - - // Set the response length - - rpc.setLength(bufPos + 12 + ((rdlen + 3) & 0xFFFFFFFC)); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILEIO)) - logger.debug("Read fid=" + netFile.getFileId() + ", name=" + netFile.getName() + ", rdlen=" + rdlen); - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) { - logger.debug("Read Exception: netFile=" + netFile + ", cache=" + sess.getFileCache().numberOfEntries()); - logger.debug(ex); - } - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Read error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - return rpc; - } - - /** - * Process the write file request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procWrite(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the read parameters - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - long offset = rpc.unpackLong(); - int count = rpc.unpackInt(); - int stable = rpc.unpackInt(); - - // Skip the second write length, position at the start of the data to - // write - - rpc.skipBytes(4); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILEIO)) - logger.debug("Write request from " + rpc.getClientDetails() + " , count=" + count + ", offset=" + offset); - - // Call the disk share driver to write to the file - - int shareId = -1; - String path = null; - NetworkFile netFile = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and associated shared device - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the network file, it may be cached - - netFile = getNetworkFileForHandle(sess, handle, conn, false); - - // Get the file path - - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Check if threaded writes should be used - - FileInfo preInfo = null; - - synchronized (netFile) { - - // Make sure the network file is open - - if (netFile.isClosed()) - netFile.openFile(false); - - // Get the pre-operation file details - - preInfo = disk.getFileInformation(sess, conn, path); - - // Write to the network file - - disk.writeFile(sess, conn, netFile, rpc.getBuffer(), rpc.getPosition(), count, offset); - } - - // Get file information for the path and pack the response - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packPreOpAttr(sess, preInfo, rpc); - packPostOpAttr(sess, finfo, shareId, rpc); - - rpc.packInt(count); - rpc.packInt(stable); - rpc.packLong(m_writeVerifier); // verifier - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILEIO)) - logger.debug("Write fid=" + netFile.getFileId() + ", name=" + netFile.getName() + ", wrlen=" + count); - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (DiskFullException ex) { - errorSts = NFS.StsNoSpc; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) { - logger.debug("Write Exception: netFile=" + netFile + ", cache=" + sess.getFileCache().numberOfEntries(), ex); - } - } - - // Check for a failure status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); // before attributes - packWccData(rpc, null); // after attributes - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Write error=" - + NFS.getStatusString(errorSts)); - } - - // Return the write response - - rpc.setLength(); - return rpc; - } - - /** - * Process the create file request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procCreate(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the create arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String fileName = rpc.unpackString(); - - int createMode = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Create request from " + rpc.getClientDetails() + ", name=" + fileName); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Call the disk share driver to create the new file - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - - TreeConnection conn = getTreeConnection(sess, shareId); - path = getPathForHandle(sess, handle, conn); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the pre-operation state for the parent directory - - FileInfo preInfo = disk.getFileInformation(sess, conn, path); - - // Build the full path string - - StringBuffer str = new StringBuffer(); - str.append(path); - - if (path.endsWith("\\") == false) - str.append("\\"); - str.append(fileName); - - String filePath = str.toString(); - - // Check if the file exists - - int existSts = disk.fileExists(sess, conn, filePath); - if (existSts == FileStatus.FileExists) { - errorSts = NFS.StsExist; - } - else if (existSts == FileStatus.DirectoryExists) { - errorSts = NFS.StsIsDir; - } - else { - - // Get the file permissions - - int gid = -1; - int uid = -1; - int mode = -1; - - if (rpc.unpackInt() == Rpc.True) - mode = rpc.unpackInt(); - - if (rpc.unpackInt() == Rpc.True) - uid = rpc.unpackInt(); - - if (rpc.unpackInt() == Rpc.True) - gid = rpc.unpackInt(); - - // Create a new file - - FileOpenParams params = new FileOpenParams(filePath, FileAction.CreateNotExist, AccessMode.ReadWrite, 0, gid, uid, mode); - NetworkFile netFile = disk.createFile(sess, conn, params); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug(" Create file params=" + params); - - // Get file information for the path - - FileInfo finfo = disk.getFileInformation(sess, conn, filePath); - - if (finfo != null) { - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - if (finfo.isDirectory()) - packDirectoryHandle(shareId, finfo.getFileId(), rpc); - else - packFileHandle(shareId, getFileIdForHandle(handle), finfo.getFileId(), rpc); - - // Pack the file attributes - - packPostOpAttr(sess, finfo, shareId, rpc); - - // Add a cache entry for the path - - ShareDetails details = m_shareDetails.findDetails(shareId); - details.getFileIdCache().addPath(finfo.getFileId(), filePath); - - // Add a cache entry for the network file - - sess.getFileCache().addFile(netFile, conn, sess); - - // Pack the wcc data structure for the directory - - packPreOpAttr(sess, preInfo, rpc); - - FileInfo postInfo = disk.getFileInformation(sess, conn, path); - packPostOpAttr(sess, postInfo, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Create path=" + filePath - + ", finfo=" + finfo.toString()); - - // Notify change listeners that a new file has been created - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged( NotifyChange.ActionAdded, filePath); - } - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - - if ( logger.isDebugEnabled()) - logger.debug("Create error:", ex); - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Create Exception: " + ex.toString(), ex); - } - - // Check for a failure status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); // before attributes - packWccData(rpc, null); // after attributes - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Create error=" - + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the create directory request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procMkDir(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the mkdir arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String dirName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DIRECTORY)) - logger.debug("MkDir request from " + rpc.getClientDetails() + ", name=" + dirName); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Call the disk share driver to create the new directory - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - path = getPathForHandle(sess, handle, conn); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the pre-operation state for the parent directory - - FileInfo preInfo = disk.getFileInformation(sess, conn, path); - - // Build the full path string - - StringBuffer str = new StringBuffer(); - str.append(path); - if (path.endsWith("\\") == false) - str.append("\\"); - str.append(dirName); - String dirPath = str.toString(); - - // Check if the file exists - - int existSts = disk.fileExists(sess, conn, dirPath); - if (existSts != FileStatus.NotExist) { - errorSts = NFS.StsExist; - } else { - - // Get the user id, group id and mode for the new directory - - int gid = -1; - int uid = -1; - int mode = -1; - - if (rpc.unpackInt() == Rpc.True) - mode = rpc.unpackInt(); - - if (rpc.unpackInt() == Rpc.True) - uid = rpc.unpackInt(); - - if (rpc.unpackInt() == Rpc.True) - gid = rpc.unpackInt(); - - // Directory creation parameters - - FileOpenParams params = new FileOpenParams(dirPath, FileAction.CreateNotExist, AccessMode.ReadWrite, - FileAttribute.NTDirectory, gid, uid, mode); - - // Create a new directory - - disk.createDirectory(sess, conn, params); - - // Get file information for the new directory - - FileInfo finfo = disk.getFileInformation(sess, conn, dirPath); - - if (finfo != null) { - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packDirectoryHandle(shareId, finfo.getFileId(), rpc); - - // Pack the file attributes - - packPostOpAttr(sess, finfo, shareId, rpc); - - // Add a cache entry for the path - - ShareDetails details = m_shareDetails.findDetails(shareId); - - details.getFileIdCache().addPath(finfo.getFileId(), dirPath); - - // Pack the post operation details for the parent directory - - packWccData(rpc, preInfo); - packPostOpAttr(sess, conn, handle, rpc); - - // Notify change listeners that a new directory has been - // created - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn - .getContext(); - - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged( NotifyChange.ActionAdded, dirPath); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DIRECTORY)) - logger.debug("Mkdir path=" + dirPath + ", finfo=" + finfo.toString()); - } - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Mkdir Exception: " + ex.toString()); - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); - packWccData(rpc, null); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Mkdir error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the create symbolic link request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procSymLink(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the create symbolic link arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String fileName = rpc.unpackString(); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Call the disk share driver to create the symbolic link - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - - TreeConnection conn = getTreeConnection(sess, shareId); - path = getPathForHandle(sess, handle, conn); - - // Check if the filesystem supports symbolic links - - if ((conn.getInterface() instanceof SymbolicLinkInterface) == false) { - - // Symbolic links not supported on this filesystem - - rpc.buildErrorResponse(NFS.StsNotSupp); - packPostOpAttr(sess, null, 0, rpc); - packWccData(rpc, null); - - rpc.setLength(); - return rpc; - } - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the symbolic link attributes - - int setFlags = 0; - int gid = -1; - int uid = -1; - int mode = -1; - long fsize = -1L; - long atime = -1L; - long mtime = -1L; - - // Check if the file mode has been specified - - if (rpc.unpackInt() == Rpc.True) { - mode = rpc.unpackInt(); - setFlags += FileInfo.SetMode; - } - - // Check if the file owner uid has been specified - - if (rpc.unpackInt() == Rpc.True) { - uid = rpc.unpackInt(); - setFlags += FileInfo.SetUid; - } - - // Check if the file group gid has been specified - - if (rpc.unpackInt() == Rpc.True) { - gid = rpc.unpackInt(); - setFlags += FileInfo.SetGid; - } - - // Check if a new file size has been specified - - if (rpc.unpackInt() == Rpc.True) { - fsize = rpc.unpackLong(); - setFlags += FileInfo.SetFileSize; - } - - // Check if the access date/time should be set. It may be set to a - // client specified time - // or using the server time - - int setTime = rpc.unpackInt(); - - if (setTime == NFS.SetTimeClient) { - atime = (long) rpc.unpackInt(); - atime *= 1000L; - rpc.skipBytes(4); // nanoseconds - setFlags += FileInfo.SetAccessDate; - } - else if (setTime == NFS.SetTimeServer) { - atime = System.currentTimeMillis(); - setFlags += FileInfo.SetAccessDate; - } - - // Check if the modify date/time should be set. It may be set to a - // client specified time - // or using the server time - - setTime = rpc.unpackInt(); - - if (setTime == NFS.SetTimeClient) { - mtime = (long) rpc.unpackInt(); - mtime *= 1000L; - rpc.skipBytes(4); // nanoseconds - setFlags += FileInfo.SetModifyDate; - } - else if (setTime == NFS.SetTimeServer) { - mtime = System.currentTimeMillis(); - setFlags += FileInfo.SetModifyDate; - } - - // Get the symbolic link name - - String linkName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Symbolic link request from " + rpc.getClientDetails() + ", name=" + fileName + ", link=" + linkName); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the pre-operation state for the parent directory - - FileInfo preInfo = disk.getFileInformation(sess, conn, path); - - // Build the full path string - - StringBuffer str = new StringBuffer(); - str.append(path); - - if (path.endsWith("\\") == false) - str.append("\\"); - str.append(fileName); - - String filePath = str.toString(); - - // Check if the file exists - - int existSts = disk.fileExists(sess, conn, filePath); - if (existSts == FileStatus.FileExists) { - errorSts = NFS.StsExist; - } - else if (existSts == FileStatus.DirectoryExists) { - errorSts = NFS.StsIsDir; - } - else { - - // Create a new symbolic - - FileOpenParams params = new FileOpenParams(filePath, FileAction.CreateNotExist, AccessMode.ReadWrite, 0, gid, uid, mode); - params.setSymbolicLink(linkName); - - NetworkFile netFile = disk.createFile(sess, conn, params); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug(" Symbolic link params=" + params); - - // Get file information for the path - - FileInfo finfo = disk.getFileInformation(sess, conn, filePath); - - if (finfo != null) { - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packFileHandle(shareId, getFileIdForHandle(handle), finfo - .getFileId(), rpc); - - // Pack the file attributes - - packPostOpAttr(sess, finfo, shareId, rpc); - - // Add a cache entry for the path - - ShareDetails details = m_shareDetails.findDetails(shareId); - details.getFileIdCache().addPath(finfo.getFileId(), filePath); - - // Add a cache entry for the network file - - sess.getFileCache().addFile(netFile, conn, sess); - - // Pack the wcc data structure for the directory - - packPreOpAttr(sess, preInfo, rpc); - - FileInfo postInfo = disk.getFileInformation(sess, conn, path); - packPostOpAttr(sess, postInfo, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Symbolic link path=" + filePath + ", finfo=" + finfo.toString()); - } - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("SymbolicLink Exception: " + ex.toString()); - } - - // Error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("SymLink error=" - + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the make special device request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procMkNode(NFSSrvSession sess, RpcPacket rpc) { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DIRECTORY)) - logger.debug("MkNode request from " + rpc.getClientDetails()); - - // Return an error status - - rpc.buildErrorResponse(NFS.StsNotSupp); - packPostOpAttr(sess, null, 0, rpc); - packWccData(rpc, null); - - rpc.setLength(); - return rpc; - } - - /** - * Process the delete file request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procRemove(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the remove arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String fileName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Remove request from " + rpc.getClientDetails() + ", name=" + fileName); - - // Call the disk share driver to delete the file - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - ShareDetails details = m_shareDetails.findDetails(shareId); - TreeConnection conn = getTreeConnection(sess, shareId); - - path = getPathForHandle(sess, handle, conn); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the pre-operation details for the directory - - FileInfo preInfo = disk.getFileInformation(sess, conn, path); - - // Build the full path string - - StringBuffer str = new StringBuffer(); - str.append(path); - if (path.endsWith("\\") == false) - str.append("\\"); - str.append(fileName); - String delPath = str.toString(); - - // Check if the file exists - - int existSts = disk.fileExists(sess, conn, delPath); - if (existSts == FileStatus.NotExist) { - errorSts = NFS.StsNoEnt; - } - else if (existSts == FileStatus.DirectoryExists) { - errorSts = NFS.StsIsDir; - } - else { - - // Get the file information for the file to be deleted - - FileInfo finfo = disk.getFileInformation(sess, conn, delPath); - - // Delete the file - - disk.deleteFile(sess, conn, delPath); - - // Remove the path from the cache - - if (finfo != null) - details.getFileIdCache().deletePath(finfo.getFileId()); - - // Get the post-operation details for the directory - - FileInfo postInfo = disk.getFileInformation(sess, conn, path); - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packPreOpAttr(sess, preInfo, rpc); - packPostOpAttr(sess, postInfo, shareId, rpc); - - // Check if there are any file/directory change notify requests - // active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn - .getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged( NotifyChange.ActionRemoved, delPath); - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (SecurityException ex) { - errorSts = NFS.StsAccess; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("GetAttr Exception: " + ex.toString()); - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); - packWccData(rpc, null); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Remove error=" + NFS.getStatusString(errorSts)); - } - - // Return the remove repsonse - - rpc.setLength(); - return rpc; - } - - /** - * Process the delete directory request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procRmDir(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the rmdir arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - String dirName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_DIRECTORY)) - logger.debug("RmDir request from " + rpc.getClientDetails() + ", name=" + dirName); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - ShareDetails details = m_shareDetails.findDetails(shareId); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Build the pre-operation part of the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - // Pack the pre operation attributes for the parent directory - - packPreOpAttr(sess, conn, handle, rpc); - - // Get the path to be removed - - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Build the full path string - - StringBuffer str = new StringBuffer(); - str.append(path); - - if (path.endsWith("\\") == false) - str.append("\\"); - str.append(dirName); - - String delPath = str.toString(); - - // Check if the file exists - - int existSts = disk.fileExists(sess, conn, delPath); - if (existSts == FileStatus.NotExist) { - errorSts = NFS.StsNoEnt; - } - else if (existSts == FileStatus.FileExists) { - errorSts = NFS.StsNoEnt; - } - else { - - // Get the file information for the directory to be deleted - - FileInfo finfo = disk.getFileInformation(sess, conn, delPath); - - // Delete the directory - - disk.deleteDirectory(sess, conn, delPath); - - // Remove the path from the cache - - if (finfo != null) - details.getFileIdCache().deletePath(finfo.getFileId()); - - // Pack the post operation attributes for the parent directory - - packPostOpAttr(sess, conn, handle, rpc); - - // Check if there are any file/directory change notify requests - // active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged( NotifyChange.ActionRemoved, delPath); - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (SecurityException ex) { - errorSts = NFS.StsAccess; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Rmdir Exception: " + ex.toString()); - } - - // Check if an error status is being returned - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packWccData(rpc, null); - packWccData(rpc, null); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Rmdir error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the rename file request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procRename(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the rename arguments - - byte[] fromHandle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(fromHandle); - - String fromName = rpc.unpackString(); - - byte[] toHandle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(toHandle); - - String toName = rpc.unpackString(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) { - logger.debug("Rename request from " + rpc.getClientDetails() + ", fromHandle=" + NFSHandle.asString(fromHandle) - + ", fromname=" + fromName); - logger.debug(" tohandle=" + NFSHandle.asString(toHandle) + ", toname=" + toName); - } - - // Call the disk share driver to rename the file/directory - - int shareId = -1; - String fromPath = null; - String toPath = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(fromHandle); - ShareDetails details = m_shareDetails.findDetails(shareId); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasWriteAccess() == false) - throw new AccessDeniedException(); - - // Get paths from the handles - - fromPath = getPathForHandle(sess, fromHandle, conn); - toPath = getPathForHandle(sess, toHandle, conn); - - // Build the full path string for the old name - - StringBuffer str = new StringBuffer(); - str.append(fromPath); - - if (fromPath.endsWith("\\") == false) - str.append("\\"); - str.append(fromName); - - String oldPath = str.toString(); - - // Build the full path string for the new name - - str.setLength(0); - str.append(toPath); - - if (toPath.endsWith("\\") == false) - str.append("\\"); - str.append(toName); - - String newPath = str.toString(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice() - .getInterface(); - - // Get the pre-operation details for the parent directories - - FileInfo preFromInfo = disk.getFileInformation(sess, conn, fromPath); - FileInfo preToInfo = null; - - if (NFSHandle.unpackDirectoryId(fromHandle) == NFSHandle.unpackDirectoryId(toHandle)) - preToInfo = preFromInfo; - else - preToInfo = disk.getFileInformation(sess, conn, toPath); - - // Check if the from path exists - - int existSts = disk.fileExists(sess, conn, oldPath); - - if (existSts == FileStatus.NotExist) { - errorSts = NFS.StsNoEnt; - } else { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILE)) - logger.debug("Rename from=" + oldPath + ", to=" + newPath); - - // Get the file details for the file/folder being renamed - - FileInfo finfo = disk.getFileInformation(sess, conn, oldPath); - - // Rename the file/directory - - disk.renameFile(sess, conn, oldPath, newPath); - - // Remove the original path from the cache - - if (finfo != null && finfo.getFileId() != -1) - details.getFileIdCache().deletePath(finfo.getFileId()); - - // Get the file id for the new file/directory - - finfo = disk.getFileInformation(sess, conn, newPath); - if (finfo != null) - details.getFileIdCache().addPath(finfo.getFileId(), newPath); - - // Check if there are any file/directory change notify requests - // active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyRename(oldPath, newPath); - - // Get the post-operation details for the parent directories - - FileInfo postFromInfo = disk.getFileInformation(sess, conn, fromPath); - FileInfo postToInfo = null; - - if (NFSHandle.unpackDirectoryId(fromHandle) == NFSHandle.unpackDirectoryId(toHandle)) - postToInfo = postFromInfo; - else - postToInfo = disk.getFileInformation(sess, conn, toPath); - - // Pack the rename response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packWccData(rpc, preFromInfo); - packPostOpAttr(sess, postFromInfo, shareId, rpc); - - packWccData(rpc, preToInfo); - packPostOpAttr(sess, postToInfo, shareId, rpc); - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (SecurityException ex) { - errorSts = NFS.StsAccess; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (FileExistsException ex) { - errorSts = NFS.StsExist; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Rename Exception: " + ex.toString()); - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - - // Pack the from dir WCC data - - packWccData(rpc, null); - packWccData(rpc, null); - - // Pack the to dir WCC data - - packWccData(rpc, null); - packWccData(rpc, null); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Rename error=" + NFS.getStatusString(errorSts)); - } - - // Return the rename response - - rpc.setLength(); - return rpc; - } - - /** - * Process the create hard link request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procLink(NFSSrvSession sess, RpcPacket rpc) { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_RXDATA)) - logger.debug("Link request from " + rpc.getClientDetails()); - - // Return an error status - - rpc.buildErrorResponse(NFS.StsAccess); - packPostOpAttr(sess, null, 0, rpc); - packWccData(rpc, null); - packWccData(rpc, null); - - rpc.setLength(); - return rpc; - } - - /** - * Process the read directory request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procReadDir(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the read directory arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - long cookie = rpc.unpackLong(); - long cookieVerf = rpc.unpackLong(); - - int maxCount = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir request from " + rpc.getClientDetails() - + " handle=" + NFSHandle.asString(handle) + ", count=" - + maxCount); - - // Check if this is a share handle - - int shareId = -1; - String path = null; - - int errorSts = NFS.StsSuccess; - - // Call the disk share driver to get the file information for the path - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - ShareDetails details = m_shareDetails.findDetails(shareId); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // If the filesystem driver cannot convert file ids to relative - // paths we need to build a relative path for - // every file and sub-directory in the search - - StringBuffer pathBuf = null; - int pathLen = 0; - FileIdCache fileCache = details.getFileIdCache(); - - if (details.hasFileIdSupport() == false) { - - // Allocate the buffer for building the relative paths - - pathBuf = new StringBuffer(256); - pathBuf.append(path); - if (path.endsWith("\\") == false) - pathBuf.append("\\"); - - // Set the length of the search path portion of the string - - pathLen = pathBuf.length(); - } - - // Build the response header - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - // Get the root directory information - - FileInfo dinfo = disk.getFileInformation(sess, conn, path); - packPostOpAttr(sess, dinfo, shareId, rpc); - - // Generate the search path - - String searchPath = generatePath(path, "*"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir searchPath=" + searchPath + ", cookie=" + cookie); - - // Check if this is the start of a search - - SearchContext search = null; - long searchId = -1; - - if (cookie == 0) { - - // Start a new search, allocate a search id - - search = disk.startSearch(sess, conn, searchPath, FileAttribute.Directory + FileAttribute.Normal); - - // Allocate a search id for the new search - - searchId = sess.allocateSearchSlot(search); - - // Set the cookie verifier - - cookieVerf = dinfo.getModifyDateTime(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir allocated searchId=" + searchId); - } else { - - // Check if the cookie verifier is valid - - if (cookieVerf != 0L && cookieVerf != dinfo.getModifyDateTime()) - throw new BadCookieException(); - - // Retrieve the search from the active search cache - - searchId = (cookie & COOKIE_SEARCHID_MASK) >> COOKIE_SEARCHID_SHIFT; - - // Get the active search - - search = sess.getSearchContext((int) searchId); - - // Check if the search has been closed, if so then restart the - // search - - if (search == null) { - - // Restart the search - - search = disk.startSearch(sess, conn, searchPath, FileAttribute.Directory + FileAttribute.Normal); - - // Allocate a search id for the new search - - searchId = sess.allocateSearchSlot(search); - - // Set the cookie verifier - - cookieVerf = dinfo.getModifyDateTime(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir restarted search, searchId=" + searchId); - } - - // Check if the search is at the required restart point - - int resumeId = (int) (cookie & COOKIE_RESUMEID_MASK); - if (search.getResumeId() != resumeId) - search.restartAt(resumeId); - } - - // Pack the cookie verifier - - rpc.packLong(cookieVerf); - - // Check if the search id is valid - - if (searchId == -1) - throw new Exception("Bad search id"); - - // Search id is masked into the top of the file index to make the - // resume cookie - - long searchMask = ((long) searchId) << COOKIE_SEARCHID_SHIFT; - - // Build the return file list - - int entCnt = 0; - - // Loop until the return buffer is full or there are no more files - - FileInfo finfo = new FileInfo(); - - // Check if this is the start of a search, if so then add the '.' - // and '..' entries - - if (cookie == 0) { - - // Add the search directory details, the '.' directory - - rpc.packInt(Rpc.True); - rpc.packLong(dinfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString("."); - rpc.packLong(COOKIE_DOT_DIRECTORY); - - // Get the file information for the parent directory - - String parentPath = generatePath(path, ".."); - FileInfo parentInfo = disk.getFileInformation(sess, conn, - parentPath); - - // Add the parent of the search directory, the '..' directory - - rpc.packInt(Rpc.True); - rpc.packLong(parentInfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString(".."); - rpc.packLong(COOKIE_DOTDOT_DIRECTORY); - - // Update the entry count and current used reply buffer count - - entCnt = 2; - } - - // Add file/sub-directory entries until there are no more entries or - // the buffer is full - - boolean replyFull = false; - - while (entCnt++ < maxCount && replyFull == false && search.nextFileInfo(finfo)) { - - // Check if the new file entry will fit into the reply buffer - // without exceeding the clients maximum - // reply size - - int entryLen = READDIR_ENTRY_LENGTH + ((finfo.getFileName().length() + 3) & 0xFFFFFFFC); - - if (entryLen > rpc.getAvailableLength() || (rpc.getPosition() + entryLen > maxCount)) { - replyFull = true; - break; - } - - // Fill in the entry details - - rpc.packInt(Rpc.True); - rpc.packLong(finfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString(finfo.getFileName()); - rpc.packLong(search.getResumeId() + searchMask); - - // Check if the relative path should be added to the file id - // cache - - if (details.hasFileIdSupport() == false && fileCache.findPath(finfo.getFileId()) == null) { - - // Create a relative path for the current file/sub-directory - // and add to the file id cache - - pathBuf.setLength(pathLen); - pathBuf.append(finfo.getFileName()); - - fileCache.addPath(finfo.getFileId(), pathBuf.toString()); - } - } - - // Indicate no more file entries in this response - - rpc.packInt(Rpc.False); - - // Check if the search is complete - - if (search.hasMoreFiles()) { - - // Indicate that there are more files to be returned - - rpc.packInt(Rpc.False); - } - else { - - // Set the end of search flag - - rpc.packInt(Rpc.True); - - // Close the search, release the search slot - - search.closeSearch(); - sess.deallocateSearchSlot((int) searchId); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir released searchId=" + searchId); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir return entries=" + (entCnt - 1) + ", eof=" + search.hasMoreFiles()); - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (BadCookieException ex) { - errorSts = NFS.StsBadCookie; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) { - logger.debug("ReadDir Exception: " + ex.toString()); - logger.debug(ex); - } - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("ReadDir error=" + NFS.getStatusString(errorSts)); - } - - // Return the read directory response - - rpc.setLength(); - return rpc; - } - - /** - * Process the read directory plus request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procReadDirPlus(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the read directory arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - long cookie = rpc.unpackLong(); - long cookieVerf = rpc.unpackLong(); - - int maxDir = rpc.unpackInt(); - int maxCount = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDir request from " + rpc.getClientDetails() - + " handle=" + NFSHandle.asString(handle) + ", dir=" - + maxDir + ", count=" + maxCount); - - // Check if this is a share handle - - int shareId = -1; - String path = null; - - int errorSts = NFS.StsSuccess; - - // Call the disk share driver to get the file information for the path - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - ShareDetails details = m_shareDetails.findDetails(shareId); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // If the filesystem driver cannot convert file ids to relative - // paths we need to build a relative path for - // every file and sub-directory in the search - - StringBuffer pathBuf = null; - int pathLen = 0; - FileIdCache fileCache = details.getFileIdCache(); - - if (details.hasFileIdSupport() == false) { - - // Allocate the buffer for building the relative paths - - pathBuf = new StringBuffer(256); - pathBuf.append(path); - if (path.endsWith("\\") == false) - pathBuf.append("\\"); - - // Set the length of the search path portion of the string - - pathLen = pathBuf.length(); - } - - // Build the response header - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - // Get the root directory information - - FileInfo dinfo = disk.getFileInformation(sess, conn, path); - packPostOpAttr(sess, dinfo, shareId, rpc); - - // Generate the search path - - String searchPath = generatePath(path, "*.*"); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDirPlus searchPath=" + searchPath - + ", cookie=" + cookie); - - // Check if this is the start of a search - - SearchContext search = null; - long searchId = -1; - - if (cookie == 0L) { - - // Start a new search, allocate a search id - - search = disk.startSearch(sess, conn, searchPath, FileAttribute.Directory + FileAttribute.Normal); - - // Allocate a search id for the new search - - searchId = sess.allocateSearchSlot(search); - - // Set the cookie verifier - - cookieVerf = dinfo.getModifyDateTime(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDirPlus allocated searchId=" - + searchId); - } - else { - - // Check if the cookie verifier is valid - - if (cookieVerf != 0L && cookieVerf != dinfo.getModifyDateTime()) { - logger.debug("Bad cookie verifier, verf=0x" - + Long.toHexString(cookieVerf) + ", modTime=0x" - + Long.toHexString(dinfo.getModifyDateTime())); - throw new BadCookieException(); - } - - // Retrieve the search from the active search cache - - searchId = (cookie & COOKIE_SEARCHID_MASK) >> COOKIE_SEARCHID_SHIFT; - - // Get the active search - - search = sess.getSearchContext((int) searchId); - - // Check if the search has been closed, if so then restart the - // search - - if (search == null) { - - // Restart the search - - search = disk.startSearch(sess, conn, searchPath, FileAttribute.Directory + FileAttribute.Normal); - - // Allocate a search id for the new search - - searchId = sess.allocateSearchSlot(search); - - // Set the cookie verifier - - cookieVerf = dinfo.getModifyDateTime(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDirPlus restarted search, searchId=" + searchId); - } - - // Get the search resume id from the cookie - - int resumeId = (int) (cookie & COOKIE_RESUMEID_MASK); - if (search != null && search.getResumeId() != resumeId) - search.restartAt(resumeId); - } - - // Pack the cookie verifier - - rpc.packLong(cookieVerf); - - // Check if the search id is valid - - if (searchId == -1) - throw new Exception("Bad search id"); - - // Search id is masked into the top of the file index to make the - // resume cookie - - long searchMask = ((long) searchId) << COOKIE_SEARCHID_SHIFT; - - // Build the return file list - - int entCnt = 0; - - // Loop until the return buffer is full or there are no more files - - FileInfo finfo = new FileInfo(); - - // Check if this is the start of a search, if so then add the '.' - // and '..' entries - - if (cookie == 0) { - - // Add the search directory details, the '.' directory - - rpc.packInt(Rpc.True); - rpc.packLong(dinfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString("."); - rpc.packLong(COOKIE_DOT_DIRECTORY); - - // Fill in the file attributes - - rpc.packInt(Rpc.True); - packAttributes3(rpc, dinfo, shareId); - - // Fill in the file handle - - packDirectoryHandle(shareId, dinfo.getFileId(), rpc); - - // Get the file information for the parent directory - - String parentPath = generatePath(path, ".."); - FileInfo parentInfo = disk.getFileInformation(sess, conn, - parentPath); - - // Add the parent of the search directory, the '..' directory - - rpc.packInt(Rpc.True); - rpc.packLong(parentInfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString(".."); - rpc.packLong(COOKIE_DOTDOT_DIRECTORY); - - // Fill in the file attributes - - rpc.packInt(Rpc.True); - packAttributes3(rpc, parentInfo, shareId); - - // Fill in the file handle - - packDirectoryHandle(shareId, parentInfo.getFileId(), rpc); - - // Update the entry count and current used reply buffer count - - entCnt = 2; - } - - // Pack the file entries - - boolean replyFull = false; - - while (entCnt++ < maxDir && replyFull == false && search.nextFileInfo(finfo)) { - - // Check if the new file entry will fit into the reply buffer - // without exceeding the clients maximum - // reply size - - int entryLen = READDIRPLUS_ENTRY_LENGTH + ((finfo.getFileName().length() + 3) & 0xFFFFFFFC); - - if (entryLen > rpc.getAvailableLength() || (rpc.getPosition() + entryLen > maxCount)) { - replyFull = true; - break; - } - - // Fill in the entry details - - rpc.packInt(Rpc.True); - rpc.packLong(finfo.getFileIdLong() + FILE_ID_OFFSET); - rpc.packString(finfo.getFileName()); - rpc.packLong(search.getResumeId() + searchMask); - - // Fill in the file attributes - - rpc.packInt(Rpc.True); - packAttributes3(rpc, finfo, shareId); - - // Fill in the file or directory handle - - if (finfo.isDirectory()) - packDirectoryHandle(shareId, finfo.getFileId(), rpc); - else - packFileHandle(shareId, dinfo.getFileId(), finfo.getFileId(), rpc); - - // Check if the relative path should be added to the file id - // cache - - if (details.hasFileIdSupport() == false && fileCache.findPath(finfo.getFileId()) == null) { - - // Create a relative path for the current file/sub-directory - // and add to the file id cache - - pathBuf.setLength(pathLen); - pathBuf.append(finfo.getFileName()); - - fileCache.addPath(finfo.getFileId(), pathBuf.toString()); - } - - // Reset the file type - - finfo.setFileType(FileType.RegularFile); - } - - // Indicate that there are no more file entries in this response - - rpc.packInt(Rpc.False); - - // Check if the search is complete - - if (search.hasMoreFiles()) { - - // Indicate that there are more files to be returned - - rpc.packInt(Rpc.False); - } else { - - // Set the end of search flag - - rpc.packInt(Rpc.True); - - // Close the search, release the search slot - - search.closeSearch(); - sess.deallocateSearchSlot((int) searchId); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("ReadDirPlus return entries=" + (entCnt - 1) + ", eof=" + (search.hasMoreFiles() ? false : true)); - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (BadCookieException ex) { - errorSts = NFS.StsBadCookie; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) { - logger.debug("ReadDirPlus Exception: " + ex.toString()); - logger.debug(ex); - } - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("ReadDir error=" + NFS.getStatusString(errorSts)); - } - - // Return the read directory plus response - - rpc.setLength(); - return rpc; - } - - /** - * Process the filesystem status request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procFsStat(NFSSrvSession sess, RpcPacket rpc) { - - // Get the handle from the request - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("FsInfo request from " + rpc.getClientDetails()); - - // Call the disk share driver to get the disk size information - - int shareId = -1; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id - - shareId = getShareIdFromHandle(handle); - - // Get the required disk driver/tree connection - - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the static disk information from the context, if available - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - SrvDiskInfo diskInfo = diskCtx.getDiskInformation(); - - // If we did not get valid disk information from the device context - // check - // if the driver implements the - // disk sizing interface - - if (diskInfo == null) - diskInfo = new SrvDiskInfo(); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check if the driver implements the dynamic sizing interface to - // get - // realtime disk size information - - if (disk instanceof DiskSizeInterface) { - - // Get the dynamic disk sizing information - - DiskSizeInterface sizeInterface = (DiskSizeInterface) disk; - sizeInterface.getDiskInformation(diskCtx, diskInfo); - } - - // Calculate the disk size information - - // int unitSize = diskInfo.getBlockSize() * - // diskInfo.getBlocksPerAllocationUnit(); - - // Get the file details for the root directory - - String rootPath = getPathForHandle(sess, handle, conn); - FileInfo rootInfo = disk.getFileInformation(sess, conn, rootPath); - - // Pack the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packPostOpAttr(sess, rootInfo, shareId, rpc); - - // Calculate the total/free disk space in bytes - - long totalSize = ((long) diskInfo.getDiskSizeKb()) * 1024L; - long freeSize = ((long) diskInfo.getDiskFreeSizeKb()) * 1024L; - - // Pack the total size, free size and space available to the user - - rpc.packLong(totalSize); - rpc.packLong(freeSize); - rpc.packLong(freeSize); - - // Total/free file slots in the file system, assume one file per 1Kb - // of - // space - - long totalSlots = diskInfo.getDiskSizeKb(); - long freeSlots = diskInfo.getDiskFreeSizeKb(); - - // Pack the total slots, free slots and user slots available - - rpc.packLong(totalSlots); - rpc.packLong(freeSlots); - rpc.packLong(freeSlots); - - // Pack the number of seconds for which the file system in not - // expected to - // change - - rpc.packInt(0); - } - catch (SecurityException ex) { - errorSts = NFS.StsAccess; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("FsStat error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the filesystem information request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procFsInfo(NFSSrvSession sess, RpcPacket rpc) { - - // Get the handle from the request - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_INFO)) - logger.debug("[NFS] FsInfo request from " + rpc.getClientDetails()); - - // Check if the handle is valid - - if (NFSHandle.isValid(handle) == false) { - - // Return an error status - - rpc.buildErrorResponse(NFS.StsBadHandle); - return rpc; - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Check if this is a share handle - - int shareId = -1; - int errorSts = NFS.StsSuccess; - - // Pack the filesystem information for the filesystem - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Pack the status code and post op attributes - - rpc.packInt(NFS.StsSuccess); - packPostOpAttr(sess, conn, handle, rpc); - - // Pack the filesystem information - // - // Maximum/preferred read request supported by the server - - rpc.packInt(MaxReadSize); - rpc.packInt(PrefReadSize); - rpc.packInt(MultReadSize); - - // Maximum/preferred write request supported by the server - - rpc.packInt(MaxWriteSize); - rpc.packInt(PrefWriteSize); - rpc.packInt(MultWriteSize); - - // Preferred READDIR request size - - rpc.packInt(PrefReadDirSize); - - // Maximum file size supported - - rpc.packLong(MaxFileSize); - - // Server time resolution, indicate to nearest second - - rpc.packInt(1); // seconds - rpc.packInt(0); // nano-seconds - - // Server properties, check if the filesystem supports symbolic - // links - - int fileSysProps = NFS.FileSysHomogeneuos + NFS.FileSysCanSetTime; - if (conn.getInterface() instanceof SymbolicLinkInterface) - fileSysProps += NFS.FileSysSymLink; - - rpc.packInt(fileSysProps); - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Access Exception: " + ex.toString()); - } - - // Check for an error status - - if (errorSts != NFS.StsSuccess) { - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Access error=" + NFS.getStatusString(errorSts)); - } - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Process the retrieve POSIX information request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procPathConf(NFSSrvSession sess, RpcPacket rpc) { - - // Unpack the pathconf arguments - - byte[] handle = new byte[NFS.FileHandleSize]; - rpc.unpackByteArrayWithLength(handle); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("PathConf request from " + rpc.getClientDetails() - + " handle=" + NFSHandle.asString(handle)); - - // Call the disk share driver to get the file information for the path - - int shareId = -1; - String path = null; - int errorSts = NFS.StsSuccess; - - try { - - // Get the share id and path - - shareId = getShareIdFromHandle(handle); - TreeConnection conn = getTreeConnection(sess, shareId); - - // Check if the session has the required access to the shared - // filesystem - - if (conn.hasReadAccess() == false) - throw new AccessDeniedException(); - - // Get the path from the handle - - path = getPathForHandle(sess, handle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check if the file/directory exists - - if (disk.fileExists(sess, conn, path) != FileStatus.NotExist) { - - // Get file information for the path - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - - // Build the response - - rpc.buildResponseHeader(); - rpc.packInt(NFS.StsSuccess); - - packPostOpAttr(sess, finfo, shareId, rpc); - - // Pack the filesystem options - - rpc.packInt(32767); - rpc.packInt(255); - - rpc.packInt(Rpc.True); // truncate over size names - rpc.packInt(Rpc.True); // chown restricted - rpc.packInt(Rpc.True); // case insensitive - rpc.packInt(Rpc.True); // case preserving - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SEARCH)) - logger.debug("Pathconf path=" + path + ", finfo=" + (finfo != null ? finfo.toString() : "")); - } - else { - - // File does not exist - - errorSts = NFS.StsNoEnt; - } - } - catch (BadHandleException ex) { - errorSts = NFS.StsBadHandle; - } - catch (StaleHandleException ex) { - errorSts = NFS.StsStale; - } - catch (AccessDeniedException ex) { - errorSts = NFS.StsAccess; - } - catch (Exception ex) { - errorSts = NFS.StsServerFault; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Pathconf Exception: " + ex.toString()); - } - - // Check if an error is being returned - - if (errorSts != NFS.StsSuccess) { - - // Pack the error response - - rpc.buildErrorResponse(errorSts); - packPostOpAttr(sess, null, shareId, rpc); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("Pathconf error=" + NFS.getStatusString(errorSts)); - } - - // Return the path information response - - rpc.setLength(); - return rpc; - } - - /** - * Commit request - * - * @param sess - * NFSSrvSession - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procCommit(NFSSrvSession sess, RpcPacket rpc) { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_FILEIO)) - logger.debug("Commit request from " + rpc.getClientDetails()); - - // Pack the response - - rpc.buildResponseHeader(); - - rpc.packInt(NFS.StsSuccess); - packWccData(rpc, null); - packPostOpAttr(sess, null, 0, rpc); - - // Pack the write verifier, indicates if the server has been restarted - // since the file write requests - - rpc.packLong(m_writeVerifier); - - // Return the response - - rpc.setLength(); - return rpc; - } - - /** - * Find, or create, the session for the specified RPC request. - * - * @param rpc - * RpcPacket - * @return NFSSrvSession - * @exception RpcAuthenticationException - */ - private final NFSSrvSession findSessionForRequest(RpcPacket rpc) - throws RpcAuthenticationException { - - // Check the authentication type and search the appropriate session - // table for an existing session - - int authType = rpc.getCredentialsType(); - - // Authenticate the request - - Object sessKey = getRpcAuthenticator().authenticateRpcClient(authType, rpc); - - NFSSrvSession sess = null; - - switch (authType) { - - // Null authentication - - case AuthType.Null: - sess = findAuthNullSession(rpc, sessKey); - break; - - // Unix authentication - - case AuthType.Unix: - sess = findAuthUnixSession(rpc, sessKey); - break; - } - - // Setup the authentication context for the request - - try - { - getRpcAuthenticator().setCurrentUser( sess, sess.getClientInformation()); - } - catch ( Throwable ex) - { - sess = null; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_ERROR)) - logger.debug("RPC Authencation Exception: " + ex.toString()); - } - - // Check if the session is valid - - if ( sess == null) - throw new RpcAuthenticationException(Rpc.AuthBadCred); - - // Return the server session - - return sess; - } - - /** - * Find, or create, a null authentication session for the specified request - * - * @param rpc - * RpcPacket - * @param sessKey - * Object - * @return NFSSrvSession - */ - private final NFSSrvSession findAuthNullSession(RpcPacket rpc, - Object sessKey) { - - // Check if the null authentication session table is valid - - NFSSrvSession sess = null; - - if (m_sessAuthNull != null) { - - // Search for the required session using the client IP address - - sess = m_sessAuthNull.findSession(sessKey); - } - else { - - // Allocate the null authentication session table - - m_sessAuthNull = new NFSSessionTable(); - } - - // Check if we found the required session object - - if (sess == null) { - - // Create a new session for the request - - sess = new NFSSrvSession(this, rpc.getClientAddress(), rpc.getClientPort(), rpc.getClientProtocol()); - sess.setAuthIdentifier(sessKey); - - // Get the client information from the RPC - - sess.setClientInformation(getRpcAuthenticator().getRpcClientInformation(sessKey, rpc)); - - // Add the new session to the session table - - m_sessAuthNull.addSession(sess); - - // Set the session id and debug output prefix - - sess.setUniqueId("" + sessKey.hashCode()); - sess.setDebug(getConfiguration().getNFSDebug()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SESSION)) - logger.debug("[NFS] Added Null session " + sess.getUniqueId()); - } - - // Return the session - - return sess; - } - - /** - * Find, or create, a Unix authentication session for the specified request - * - * @param rpc - * RpcPacket - * @param sessKey - * Object - * @return NFSSrvSession - */ - private final NFSSrvSession findAuthUnixSession(RpcPacket rpc, - Object sessKey) { - - // Check if the Unix authentication session table is valid - - NFSSrvSession sess = null; - - if (m_sessAuthUnix != null) { - - // Search for the required session using the client IP address + gid - // + uid - - sess = m_sessAuthUnix.findSession(sessKey); - } - else { - - // Allocate the Unix authentication session table - - m_sessAuthUnix = new NFSSessionTable(); - } - - // Check if we found the required session object - - if (sess == null) { - - // Create a new session for the request - - sess = new NFSSrvSession(this, rpc.getClientAddress(), rpc.getClientPort(), rpc.getClientProtocol()); - sess.setAuthIdentifier(sessKey); - - // Set the session id and debug output prefix - - sess.setUniqueId("" + sessKey.hashCode()); - sess.setDebug(getConfiguration().getNFSDebug()); - - // Get the client information from the RPC - - sess.setClientInformation(getRpcAuthenticator().getRpcClientInformation(sessKey, rpc)); - - // Add the new session to the session table - - m_sessAuthUnix.addSession(sess); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebugFlag(DBG_SESSION)) - logger.debug("[NFS] Added Unix session " + sess.getUniqueId()); - } - - // Return the session - - return sess; - } - - /** - * Pack the NFS v3 file attributes structure using the file information - * - * @param rpc - * RpcPacket - * @param finfo - * FileInfo - * @param fileSysId - * int - */ - protected final void packAttributes3(RpcPacket rpc, FileInfo finfo, - int fileSysId) { - - // Pack the NFS format file attributes - - if (finfo.isDirectory()) { - - // Pack the directory information - - rpc.packInt(NFS.FileTypeDir); - if (finfo.hasMode()) - rpc.packInt(finfo.getMode()); - else - rpc.packInt(MODE_DIR_DEFAULT); - } else { - - // Pack the file information - - if (finfo.isFileType() == FileType.SymbolicLink) - rpc.packInt(NFS.FileTypeLnk); - else - rpc.packInt(NFS.FileTypeReg); - - if (finfo.hasMode()) - rpc.packInt(finfo.getMode()); - else - rpc.packInt(MODE_FILE_DEFAULT); - } - - // Set various Unix fields - - rpc.packInt(1); // number of links - - rpc.packInt(finfo.hasUid() ? finfo.getUid() : 0); - rpc.packInt(finfo.hasGid() ? finfo.getGid() : 0); - - // Set the size for the file - - if (finfo.isDirectory()) { - - // Pack the directory size/allocation - - rpc.packLong(512L); - rpc.packLong(1024L); - } else { - - // Pack the file size/allocation - - rpc.packLong(finfo.getSize()); - if (finfo.getAllocationSize() != 0) - rpc.packLong(finfo.getAllocationSize()); - else - rpc.packLong(finfo.getSize()); - } - - // Pack the rdev field - - rpc.packInt(0); // specdata1 - rpc.packInt(0); // specdata2 - - // Pack the file id - - long fid = ((long) finfo.getFileId()) & 0x0FFFFFFFFL; - fid += FILE_ID_OFFSET; - - rpc.packLong(fileSysId); - rpc.packLong(fid); // fid - - // Pack the file times - - if (finfo.hasAccessDateTime()) { - rpc.packInt((int) (finfo.getAccessDateTime() / 1000L)); - rpc.packInt(0); - } else - rpc.packLong(0); - - if (finfo.hasModifyDateTime()) { - rpc.packInt((int) (finfo.getModifyDateTime() / 1000L)); - rpc.packInt(0); - } else - rpc.packLong(0); - - if (finfo.hasChangeDateTime()) { - rpc.packInt((int) (finfo.getChangeDateTime() / 1000L)); - rpc.packInt(0); - } else - rpc.packLong(0); - } - - /** - * Pack a share handle - * - * @param shareName - * String - * @param rpc - * RpcPacket - */ - protected final void packShareHandle(String shareName, RpcPacket rpc) { - - // Indicate that a handle follows, pack the handle - - rpc.packInt(Rpc.True); - NFSHandle.packShareHandle(shareName, rpc, NFS.FileHandleSize); - } - - /** - * Pack a directory handle - * - * @param shareId - * int - * @param dirId - * int - * @param rpc - * RpcPacket - */ - protected final void packDirectoryHandle(int shareId, int dirId, - RpcPacket rpc) { - - // Indicate that a handle follows, pack the handle - - rpc.packInt(Rpc.True); - NFSHandle.packDirectoryHandle(shareId, dirId, rpc, NFS.FileHandleSize); - } - - /** - * Pack a directory handle - * - * @param shareId - * int - * @param dirId - * int - * @param fileId - * int - * @param rpc - * RpcPacket - */ - protected final void packFileHandle(int shareId, int dirId, int fileId, - RpcPacket rpc) { - - // Indicate that a handle follows, pack the handle - - rpc.packInt(Rpc.True); - NFSHandle.packFileHandle(shareId, dirId, fileId, rpc, - NFS.FileHandleSize); - } - - /** - * Get the share id from the specified handle - * - * @param handle - * byte[] - * @return int - * @exception BadHandleException - */ - protected final int getShareIdFromHandle(byte[] handle) - throws BadHandleException { - - // Check if this is a share handle - - int shareId = NFSHandle.unpackShareId(handle); - - // Check if the share id is valid - - if (shareId == -1) - throw new BadHandleException(); - - // Return the share id - - return shareId; - } - - /** - * Get the path for the specified handle - * - * @param sess - * NFSSrvSession - * @param handle - * byte[] - * @param tree - * TreeConnection - * @return String - * @exception BadHandleException - * @exception StaleHandleException - */ - protected final String getPathForHandle(NFSSrvSession sess, byte[] handle, - TreeConnection tree) throws BadHandleException, - StaleHandleException { - - // Get the share details via the share id hash - - ShareDetails details = m_shareDetails - .findDetails(getShareIdFromHandle(handle)); - - // Check if this is a share handle - - String path = null; - - int dirId = -1; - int fileId = -1; - - if (NFSHandle.isShareHandle(handle)) { - - // Use the root path - - path = "\\"; - } else if (NFSHandle.isDirectoryHandle(handle)) { - - // Get the directory id from the handle and get the associated path - - dirId = NFSHandle.unpackDirectoryId(handle); - path = details.getFileIdCache().findPath(dirId); - } else if (NFSHandle.isFileHandle(handle)) { - - // Get the file id from the handle and get the associated path - - fileId = NFSHandle.unpackFileId(handle); - path = details.getFileIdCache().findPath(fileId); - } else - throw new BadHandleException(); - - // Check if the path is valid. The path may not be valid if the server has - // been restarted as the file id cache will not contain the required path. - - if (path == null) { - - // Check if the filesystem driver supports converting file ids to - // paths - - if (details.hasFileIdSupport()) { - - // Get the file and directory ids from the handle - - dirId = NFSHandle.unpackDirectoryId(handle); - fileId = NFSHandle.unpackFileId(handle); - - // If the file id is not valid the handle is to a directory, use the - // directory id as the file id - - if (fileId == -1) { - fileId = dirId; - dirId = -1; - } - - // Convert the file id to a path - - FileIdInterface fileIdInterface = (FileIdInterface) tree - .getInterface(); - try { - - // Convert the file id to a path - - path = fileIdInterface.buildPathForFileId(sess, tree, - dirId, fileId); - - // Add the path to the cache - - details.getFileIdCache().addPath(fileId, path); - } catch (FileNotFoundException ex) { - } - } else if (NFSHandle.isDirectoryHandle(handle) && dirId == 0) { - - // Path is the root directory - - path = "\\"; - - // Add an entry to the cache - - details.getFileIdCache().addPath(dirId, path); - } - } - - // Check if the path is valid, filesystem driver may not support converting - // file ids to paths or the file/directory may have been deleted. - - if (path == null) - throw new StaleHandleException(); - - // Return the path - - return path; - } - - /** - * Get the file id from the specified handle - * - * @param handle - * byte[] - * @return String - * @exception BadHandleException - */ - protected final int getFileIdForHandle(byte[] handle) - throws BadHandleException { - - // Check the handle type - - int fileId = -1; - - if (NFSHandle.isShareHandle(handle)) { - - // Root file id - - fileId = 0; - } - else if (NFSHandle.isDirectoryHandle(handle)) { - - // Get the directory id from the handle - - fileId = NFSHandle.unpackDirectoryId(handle); - } - else if (NFSHandle.isFileHandle(handle)) { - - // Get the file id from the handle - - fileId = NFSHandle.unpackFileId(handle); - } - - // Check if the file id is valid - - if (fileId == -1) - throw new BadHandleException(); - - // Return the file id - - return fileId; - } - - /** - * Find, or open, the required network file using the file handle - * - * @param sess - * NFSSrvSession - * @param handle - * byte[] - * @param conn - * TreeConnection - * @param readOnly - * boolean - * @return NetworkFile - * @exception BadHandleException - * If the handle is not valid - * @exception StaleHandleException - * If the file id cannot be converted to a path - */ - protected final NetworkFile getNetworkFileForHandle(NFSSrvSession sess, byte[] handle, TreeConnection conn, boolean readOnly) - throws BadHandleException, StaleHandleException { - - // Check if the handle is a file handle - - if (NFSHandle.isFileHandle(handle) == false) - throw new BadHandleException("Not a file handle"); - - // Get the file id from the handle - - int fileId = getFileIdForHandle(handle); - - // Get the per session network file cache, use this to synchronize - - NetworkFileCache fileCache = sess.getFileCache(); - NetworkFile file = null; - - synchronized (fileCache) { - - // Check the file cache, file may already be open - - file = fileCache.findFile(fileId, sess); - if (file == null) { - - // Get the path for the file - - String path = getPathForHandle(sess, handle, conn); - if (path == null) - throw new StaleHandleException(); - - try { - - // Get the disk interface from the connection - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Open the network file - - FileOpenParams params = new FileOpenParams(path, FileAction.OpenIfExists, AccessMode.ReadWrite, 0); - file = disk.openFile(sess, conn, params); - - // Add the file to the active file cache - - if (file != null) - fileCache.addFile(file, conn, sess); - } - catch (AccessDeniedException ex) { - if (hasDebug()) - logger.debug(ex); - } - catch (Exception ex) { - logger.debug(ex); - } - } - } - - // Return the network file - - return file; - } - - /** - * Return the tree connection for the specified share index - * - * @param sess - * NFSSrvSession - * @param shareId - * int - * @return TreeConnection - * @exception BadHandleException - */ - protected final TreeConnection getTreeConnection(NFSSrvSession sess, - int shareId) throws BadHandleException { - - // Get the required tree connection from the session - - TreeConnection conn = sess.findConnection(shareId); - if (conn == null) { - - // Get a template tree connection from the global list - - TreeConnection template = m_connections.findConnection(shareId); - if (template == null) { - - // Check if any new shares have been added and try to find the - // required connection again - - if (checkForNewShares() > 0) - template = m_connections.findConnection(shareId); - } - - // Matching tree connection not found, handle is not valid - - if (template == null) - throw new BadHandleException(); - - // Check if there is an access control manager configured - - if (hasAccessControlManager()) { - - // Check if the session has access to the shared filesystem - - AccessControlManager aclMgr = getAccessControlManager(); - - int sharePerm = aclMgr.checkAccessControl(sess, template - .getSharedDevice()); - - if (sharePerm == AccessControl.NoAccess) { - - // Session does not have access to the shared filesystem, - // mount should - // have failed or permissions may have changed. - - throw new BadHandleException(); - } else if (sharePerm == AccessControl.Default) - sharePerm = AccessControl.ReadWrite; - - // Create a new tree connection from the template - - conn = new TreeConnection(template.getSharedDevice()); - conn.setPermission(sharePerm); - - // Add the tree connection to the active list for the session - - sess.addConnection(conn); - } - } - - // Return the tree connection - - return conn; - } - - /** - * Pack a weak cache consistency structure - * - * @param rpc - * RpcPacket - * @param finfo - * FileInfo - */ - protected final void packWccData(RpcPacket rpc, FileInfo finfo) { - - // Pack the weak cache consistency data - - if (finfo != null) { - - // Indicate that data follows - - rpc.packInt(Rpc.True); - - // Pack the file size - - if (finfo.isDirectory()) - rpc.packLong(512L); - else - rpc.packLong(finfo.getSize()); - - // Pack the file times - - if (finfo.hasModifyDateTime()) { - rpc.packInt((int) (finfo.getModifyDateTime() / 1000L)); - rpc.packInt(0); - } else - rpc.packLong(0); - - if (finfo.hasChangeDateTime()) { - rpc.packInt((int) (finfo.getChangeDateTime() / 1000L)); - rpc.packInt(0); - } else - rpc.packLong(0); - } else - rpc.packInt(Rpc.False); - } - - /** - * Check if a file path contains any directory components - * - * @param fpath - * String - * @return boolean - */ - protected final boolean pathHasDirectories(String fpath) { - - // Check if the file path is valid - - if (fpath == null || fpath.length() == 0) - return false; - - // Check if the file path starts with a directory component - - if (fpath.startsWith("\\") || fpath.startsWith("/") - || fpath.startsWith("..")) - return true; - - // Check if the file path contains directory components - - if (fpath.indexOf("\\") != -1 || fpath.indexOf("/") != -1) - return true; - - // File path does not have any directory components - - return false; - } - - /** - * Pack the pre operation weak cache consistency data for the specified - * file/directory - * - * @param sess - * NFSSrvSession - * @param finfo - * FileInfo - * @param rpc - * RpcPacket - */ - protected final void packPreOpAttr(NFSSrvSession sess, FileInfo finfo, - RpcPacket rpc) { - - // Pack the file information - - if (finfo != null) - packWccData(rpc, finfo); - else - rpc.packInt(Rpc.False); - } - - /** - * Pack the pre operation weak cache consistency data for the specified - * file/directory - * - * @param sess - * NFSSrvSession - * @param conn - * TreeConnection - * @param fhandle - * byte[] - * @param rpc - * RpcPacket - * @throws BadHandleException - * @throws StaleHandleException - * @throws InvalidDeviceInterfaceException - * @throws IOException - */ - protected final void packPreOpAttr(NFSSrvSession sess, TreeConnection conn, - byte[] fhandle, RpcPacket rpc) throws BadHandleException, - StaleHandleException, InvalidDeviceInterfaceException, IOException { - - // Get the path - - String path = getPathForHandle(sess, fhandle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the path - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - - // Pack the file information - - packWccData(rpc, finfo); - } - - /** - * Pack the post operation weak cache consistency data for the specified - * file/directory - * - * @param sess - * NFSSrvSession - * @param conn - * TreeConnection - * @param fhandle - * byte[] - * @param rpc - * RpcPacket - * @throws BadHandleException - * @throws StaleHandleException - * @throws InvalidDeviceInterfaceException - * @throws IOException - */ - protected final void packPostOpAttr(NFSSrvSession sess, - TreeConnection conn, byte[] fhandle, RpcPacket rpc) - throws BadHandleException, StaleHandleException, - InvalidDeviceInterfaceException, IOException { - - // Get the path - - String path = getPathForHandle(sess, fhandle, conn); - - // Get the disk interface from the disk driver - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the path - - FileInfo finfo = disk.getFileInformation(sess, conn, path); - - // Pack the file information - - if (finfo != null) { - rpc.packInt(Rpc.True); - packAttributes3(rpc, finfo, getShareIdFromHandle(fhandle)); - } else - rpc.packInt(Rpc.False); - } - - /** - * Pack the post operation weak cache consistency data for the specified - * file/directory - * - * @param sess - * NFSSrvSession - * @param finfo - * FileInfo - * @param fileSysId - * int - * @param rpc - * RpcPacket - */ - protected final void packPostOpAttr(NFSSrvSession sess, FileInfo finfo, - int fileSysId, RpcPacket rpc) { - - // Pack the file information - - if (finfo != null) { - - // Pack the post operation attributes - - rpc.packInt(Rpc.True); - packAttributes3(rpc, finfo, fileSysId); - } else - rpc.packInt(Rpc.False); - } - - /** - * Generate a share relative path from the directory path and argument path. - * The argument path may contain the value '..' in which case the directory - * path will be stipped back one level. - * - * @param dirPath - * String - * @param argPath - * String - * @return String - */ - protected final String generatePath(String dirPath, String argPath) { - - // If the argument path is '..', if so then strip the directory path - // back a - // level - - StringBuffer pathBuf = new StringBuffer(); - - if (argPath.equals("..")) { - - // Split the path into component directories - - String[] dirs = FileName.splitAllPaths(dirPath); - - // Rebuild the path without the last directory - - pathBuf.append("\\"); - int dirCnt = dirs.length - 1; - - if (dirCnt > 0) { - - // Add the paths - - for (int i = 0; i < dirCnt; i++) { - pathBuf.append(dirs[i]); - pathBuf.append("\\"); - } - } - - // Remove the trailing slash - - if (pathBuf.length() > 1) - pathBuf.setLength(pathBuf.length() - 1); - } else { - - // Add the share relative path - - pathBuf.append(dirPath); - if (dirPath.endsWith("\\") == false) - pathBuf.append("\\"); - pathBuf.append(argPath); - } - - // Return the path - - return pathBuf.toString(); - } - - /** - * Check for new shared devices and add them to the share and tree - * connection lists - * - * @return int - */ - protected final int checkForNewShares() { - - // Scan the shared device list and check for new shared devices - - SharedDeviceList shareList = getConfiguration().getShareMapper().getShareList(getConfiguration().getServerName(), null, false); - Enumeration shares = shareList.enumerateShares(); - - int newShares = 0; - - while (shares.hasMoreElements()) { - - // Get the shared device - - SharedDevice share = (SharedDevice) shares.nextElement(); - - // Check if it is a disk type shared device, if so then add a connection - // to the tree connection hash - - if (share != null && share.getType() == ShareType.DISK) { - - // Check if the filesystem driver has file id support - - boolean fileIdSupport = false; - try { - if (share.getInterface() instanceof FileIdInterface) - fileIdSupport = true; - } catch (InvalidDeviceInterfaceException ex) { - } - - // Check if the share is already in the share/tree connection - // lists - - if (m_shareDetails.findDetails(share.getName()) == null) { - - // Add the new share details - - m_shareDetails.addDetails(new ShareDetails(share.getName(), fileIdSupport)); - m_connections.addConnection(new TreeConnection(share)); - - // Update the new share count - - newShares++; - } - } - } - - // Return the count of new shares added - - return newShares; - } - - /** - * Return the next session id - * - * @return int - */ - protected final synchronized int getNextSessionId() { - return m_sessId++; - } - - /** - * Return the configured RPC authenticator - * - * @return RpcAuthenticator - */ - protected final RpcAuthenticator getRpcAuthenticator() { - return m_rpcAuthenticator; - } - - /** - * Inform session listeners that a new session has been created - * - * @param sess - * SrvSession - */ - protected final void fireSessionOpened(SrvSession sess) { - fireSessionOpenEvent(sess); - } - - /** - * Inform session listeners that a session has been closed - * - * @param sess - * SrvSession - */ - protected final void fireSessionClosed(SrvSession sess) { - fireSessionClosedEvent(sess); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSessionTable.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSessionTable.java deleted file mode 100644 index fcce6d8f0c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSessionTable.java +++ /dev/null @@ -1,116 +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.server.oncrpc.nfs; - -import java.util.*; - -/** - * NFS Server Session Table Class - * - * @author GKSpencer - */ -public class NFSSessionTable { - - // Session list - - private Hashtable m_sessions; - - /** - * Class constructor - */ - public NFSSessionTable() - { - m_sessions = new Hashtable(); - } - - /** - * 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 NFSSrvSession - */ - public final void addSession(NFSSrvSession sess) - { - m_sessions.put(sess.getAuthIdentifier(), sess); - } - - /** - * Find the session using the authentication identifier - * - * @param authIdent Object - * @return NFSSrvSession - */ - public final NFSSrvSession findSession(Object authIdent) - { - return (NFSSrvSession) m_sessions.get(authIdent); - } - - /** - * Remove a session from the list - * - * @param sess NFSSrvSession - * @return NFSSrvSession - */ - public final NFSSrvSession removeSession(NFSSrvSession sess) - { - return removeSession(sess.getAuthIdentifier()); - } - - /** - * Remove a session from the list - * - * @param authIdent Object - * @return NFSSrvSession - */ - public final NFSSrvSession removeSession(Object authIdent) - { - - // Find the required session - - NFSSrvSession sess = findSession(authIdent); - - // Remove the session and return the removed session - - m_sessions.remove(authIdent); - return sess; - } - - /** - * Enumerate the session ids - * - * @return Enumeration - */ - public final Enumeration enumerate() - { - return m_sessions.keys(); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSrvSession.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSrvSession.java deleted file mode 100644 index 9784a7729d..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NFSSrvSession.java +++ /dev/null @@ -1,477 +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.server.oncrpc.nfs; - -import java.net.*; -import java.util.*; - -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.core.DeviceInterface; -import org.alfresco.filesys.server.filesys.SearchContext; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.TreeConnectionHash; -import org.alfresco.filesys.server.oncrpc.Rpc; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NFS Server Session Class - * - * @author GKSpencer - */ -public class NFSSrvSession extends SrvSession { - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.nfs.protocol"); - - // Default and maximum number of search slots - - private static final int DefaultSearches = 32; - private static final int MaxSearches = 256; - - // Remote address and port - - private InetAddress m_remAddr; - private int m_remPort; - - // Session type (TCP or UDP) - - private int m_type; - - // Authentication identifier - // - // Identifies this session uniquely within the authentication type being used by the client - - private Object m_authIdentifier; - - // Active tree connections - - private TreeConnectionHash m_connections; - - // Cache of currently open files - - private NetworkFileCache m_fileCache; - - // Last time the session was accessed. Used to determine when to expire UDP sessions. - - private long m_lastAccess; - - // Active search list for this session - - private SearchContext[] m_search; - private int m_searchCount; - - /** - * Class constructor - * - * @param srv NetworkServer - * @param addr InetAddress - * @param port int - * @param type int - */ - public NFSSrvSession(NetworkServer srv, InetAddress addr, int port, int type) - { - super(-1, srv, "NFS", null); - - // Save the remove address/port and type - - m_remAddr = addr; - m_remPort = port; - m_type = type; - - // Create a unique id for the session from the remote address, port and type - - StringBuffer str = new StringBuffer(); - - str.append(type == Rpc.TCP ? "T" : "U"); - str.append(m_remAddr.getHostAddress()); - str.append(":"); - str.append(m_remPort); - - setUniqueId(str.toString()); - - // Set the remote name - - setRemoteName(m_remAddr.getHostAddress()); - - // Initialize the last access date/time - - setLastAccess(System.currentTimeMillis()); - } - - /** - * Return the session type - * - * @return int - */ - public final int isType() - { - return m_type; - } - - /** - * Return the open file cache - * - * @return NetworkFileCache - */ - public final NetworkFileCache getFileCache() - { - if (m_fileCache == null) - m_fileCache = new NetworkFileCache(getUniqueId(), getNFSServer().getRpcAuthenticator()); - return m_fileCache; - } - - /** - * Determine if the session has an authentication identifier - * - * @return boolean - */ - public final boolean hasAuthIdentifier() - { - return m_authIdentifier != null ? true : false; - } - - /** - * Return the authentication identifier - * - * @return Object - */ - public final Object getAuthIdentifier() - { - return m_authIdentifier; - } - - /** - * Return the client network address - * - * @return InetAddress - */ - public InetAddress getRemoteAddress() - { - return m_remAddr; - } - - /** - * Return the remote port - * - * @return int - */ - public final int getRemotePort() - { - return m_remPort; - } - - /** - * Get the last access date/time for the session - * - * @return long - */ - public final long getLastAccess() - { - return m_lastAccess; - } - - /** - * Find the tree connection for the specified share hash - * - * @param shareHash int - * @return TreeConnection - */ - public final TreeConnection findConnection(int shareHash) - { - if (m_connections == null) - return null; - return m_connections.findConnection(shareHash); - } - - /** - * Add a new connection to the list of active tree connections for this session - * - * @param tree TreeConnection - */ - public final void addConnection(TreeConnection tree) - { - if (m_connections == null) - m_connections = new TreeConnectionHash(); - m_connections.addConnection(tree); - } - - /** - * Remove a connection from the list of active tree connections for this session - * - * @param tree TreeConnection - */ - public final void removeConnection(TreeConnection tree) - { - if (m_connections == null) - return; - m_connections.deleteConnection(tree.getSharedDevice().getName()); - } - - /** - * Set the authentication identifier - * - * @param authIdent Object - */ - public final void setAuthIdentifier(Object authIdent) - { - m_authIdentifier = authIdent; - } - - /** - * Set the last access date/time for the session - * - * @param dateTime long - */ - public final void setLastAccess(long dateTime) - { - m_lastAccess = dateTime; - } - - /** - * Set the last access date/time for the session - */ - public final void setLastAccess() - { - m_lastAccess = System.currentTimeMillis(); - } - - /** - * Close the session, cleanup any resources. - */ - public void closeSession() - { - - // Cleanup open files, tree connections and searches - - cleanupSession(); - - // Call the base class - - super.closeSession(); - } - - /** - * Allocate a slot in the active searches list for a new search. - * - * @param search SearchContext - * @return int Search slot index, or -1 if there are no more search slots available. - */ - protected synchronized final int allocateSearchSlot(SearchContext search) - { - - // Check if the search array has been allocated - - if (m_search == null) - m_search = new SearchContext[DefaultSearches]; - - // Find a free slot for the new search - - int idx = 0; - - while (idx < m_search.length && m_search[idx] != null) - idx++; - - // Check if we found a free slot - - if (idx == m_search.length) - { - - // The search array needs to be extended, check if we reached the limit. - - if (m_search.length >= MaxSearches) - return -1; - - // Extend the search array - - SearchContext[] newSearch = new SearchContext[m_search.length * 2]; - System.arraycopy(m_search, 0, newSearch, 0, m_search.length); - m_search = newSearch; - } - - // If the search context is valid then store in the allocated slot - - if (search != null) - m_search[idx] = search; - - // Return the allocated search slot index - - m_searchCount++; - return idx; - } - - /** - * Deallocate the specified search context/slot. - * - * @param ctxId int - */ - protected synchronized final void deallocateSearchSlot(int ctxId) - { - - // Check if the search array has been allocated and that the index is valid - - if (m_search == null || ctxId >= m_search.length) - return; - - // Close the search - - if (m_search[ctxId] != null) - m_search[ctxId].closeSearch(); - - // Free the specified search context slot - - m_searchCount--; - m_search[ctxId] = null; - } - - /** - * Return the NFS server that the session is associated with - * - * @return NFSServer - */ - public final NFSServer getNFSServer() - { - return (NFSServer) getServer(); - } - - /** - * Return the search context for the specified search id. - * - * @return com.starla.smbsrv.SearchContext - * @param srchId int - */ - protected final SearchContext getSearchContext(int srchId) - { - - // Check if the search array is valid and the search index is valid - - if (m_search == null || srchId >= m_search.length) - return null; - - // Return the required search context - - return m_search[srchId]; - } - - /** - * Return the number of active tree searches. - * - * @return int - */ - public final int getSearchCount() - { - return m_searchCount; - } - - /** - * Store the seach context in the specified slot. - * - * @param slot Slot to store the search context. - * @param srch com.starla.smbsrv.SearchContext - */ - protected final void setSearchContext(int slot, SearchContext srch) - { - - // Check if the search slot id is valid - - if (m_search == null || slot > m_search.length) - return; - - // Store the context - - m_search[slot] = srch; - } - - /** - * Cleanup any resources owned by this session, close files, searches and change notification requests. - */ - protected final void cleanupSession() - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug(NFSServer.DBG_SESSION)) - logger.debug("NFS Cleanup session, searches=" + getSearchCount() + ", files=" - + (m_fileCache != null ? m_fileCache.numberOfEntries() : 0) + ", treeConns=" - + (m_connections != null ? m_connections.numberOfEntries() : 0)); - - // Check if there are any active searches - - if (m_search != null) - { - - // Close all active searches - - for (int idx = 0; idx < m_search.length; idx++) - { - - // Check if the current search slot is active - - if (m_search[idx] != null) - deallocateSearchSlot(idx); - } - - // Release the search context list, clear the search count - - m_search = null; - m_searchCount = 0; - } - - // Close any open files - - if (m_fileCache != null) - m_fileCache.closeAllFiles(); - - // Check if there are open tree connections - - if (m_connections != null && m_connections.numberOfEntries() > 0) - { - - // Enumerate the active connections - - Enumeration conns = m_connections.enumerateConnections(); - - while (conns.hasMoreElements()) - { - - // Get the current tree connection - - TreeConnection tree = (TreeConnection) conns.nextElement(); - - tree.closeConnection(this); - - // Inform the driver that the connection has been closed - - DeviceInterface devIface = tree.getInterface(); - if (devIface != null) - devIface.treeClosed(this, tree); - - // Release the connection list - - m_connections = null; - } - } - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NetworkFileCache.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/NetworkFileCache.java deleted file mode 100644 index 905655942d..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/NetworkFileCache.java +++ /dev/null @@ -1,507 +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.server.oncrpc.nfs; - -import java.util.*; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.oncrpc.RpcAuthenticator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Network File Cache Class - * - *

Caches the network files that are currently being accessed by the NFS server. - * - * @author GKSpencer - */ -public class NetworkFileCache { - - // Debug logging - - private static final Log logger = LogFactory.getLog(NetworkFileCache.class); - - // Default file timeout - - public static final long DefaultFileTimeout = 5000L; // 5 seconds - - // Network file cache, key is the file id - - private Hashtable m_fileCache; - - // File expiry thread - - private FileExpiry m_expiryThread; - - // RPC authenticator - - private RpcAuthenticator m_rpcAuthenticator; - - // File timeout - - private long m_fileTmo = DefaultFileTimeout; - - // Debug enable flag - - private boolean m_debug = false; - - /** - * File Entry Class - */ - protected class FileEntry { - - // Network file - - private NetworkFile m_file; - - // Disk share connection - - private TreeConnection m_conn; - - // File timeout - - private long m_timeout; - - // Session that last accessed the file - - private SrvSession m_sess; - - /** - * Class constructor - * - * @param file NetworkFile - * @param conn TreeConnection - * @param sess SrvSession - */ - public FileEntry(NetworkFile file, TreeConnection conn, SrvSession sess) { - m_file = file; - m_conn = conn; - setSession(sess); - - updateTimeout(); - } - - /** - * Return the file timeout - * - * @return long - */ - public final long getTimeout() { - return m_timeout; - } - - /** - * Return the network file - * - * @return NetworkFile - */ - public final NetworkFile getFile() { - return m_file; - } - - /** - * Return the disk share connection - * - * @return TreeConnection - */ - public final TreeConnection getConnection() { - return m_conn; - } - - /** - * Get the session that last accessed the file - * - * @return SrvSession - */ - public final SrvSession getSession() - { - return m_sess; - } - - /** - * Update the file timeout - */ - public final void updateTimeout() { - m_timeout = System.currentTimeMillis() + m_fileTmo; - } - - /** - * Update the file timeout - * - * @param tmo - * long - */ - public final void updateTimeout(long tmo) { - m_timeout = tmo; - } - - /** - * Set the session that last accessed the file - * - * @param sess SrvSession - */ - public final void setSession( SrvSession sess) - { - m_sess = sess; - } - }; - - /** - * File Expiry Thread Class - */ - protected class FileExpiry implements Runnable { - - // Expiry thread - - private Thread m_thread; - - // Wakeup interval - - private long m_wakeup; - - // Shutdown flag - - private boolean m_shutdown; - - /** - * Class Constructor - * - * @param wakeup - * long - * @param name - * String - */ - public FileExpiry(long wakeup, String name) { - - // Set the wakeup interval - - m_wakeup = wakeup; - - // Create and start the file expiry thread - - m_thread = new Thread(this); - m_thread.setDaemon(true); - m_thread.setName("NFSFileExpiry_" + name); - m_thread.start(); - } - - /** - * Main thread method - */ - public void run() { - - // Loop until shutdown - - while (m_shutdown == false) { - - // Sleep for a while - - try { - Thread.sleep(m_wakeup); - } catch (InterruptedException ex) { - } - - // Get the current system time - - long timeNow = System.currentTimeMillis(); - - // Check for expired files - - synchronized (m_fileCache) { - - // Enumerate the cache entries - - Enumeration enm = m_fileCache.keys(); - - while (enm.hasMoreElements()) { - - // Get the current key - - Integer fileId = (Integer) enm.nextElement(); - - // Get the file entry and check if it has expired - - FileEntry fentry = (FileEntry) m_fileCache.get(fileId); - - if (fentry != null && fentry.getTimeout() < timeNow) { - - // Get the network file - - NetworkFile netFile = fentry.getFile(); - - // Check if the file has an I/O request pending, if - // so then reset the file expiry time - // for the file - - if (netFile.hasIOPending()) { - - // Update the expiry time for the file entry - - fentry.updateTimeout(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("NFSFileExpiry: I/O pending file=" + fentry.getFile().getFullName() + ", fid=" + fileId); - } else { - - // File entry has expired, remove it from the - // cache - - m_fileCache.remove(fileId); - - // Close the file via the disk interface - - try { - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug( "NFSFileExpiry: Closing file " + fentry.getFile().getFullName()); - - - // Set the current user using the session that last accessed the file - - if ( m_rpcAuthenticator != null) - m_rpcAuthenticator.setCurrentUser( fentry.getSession(), fentry.getSession().getClientInformation()); - - // Get the disk interface - - DiskInterface disk = (DiskInterface) fentry.getConnection().getInterface(); - - // Close the file - - disk.closeFile( fentry.getSession(), fentry.getConnection(), netFile); - - // Commit any transactions - - fentry.getSession().endTransaction(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("NFSFileExpiry: Closed file=" + fentry.getFile().getFullName() + ", fid=" + fileId); - } - catch (Exception ex) { - logger.error( "File expiry exception", ex); - } - } - } - } - } - } - } - - /** - * Request the file expiry thread to shutdown - */ - public final void requestShutdown() { - - // Set the shutdown flag - - m_shutdown = true; - - // Wakeup the thread - - try { - m_thread.interrupt(); - } catch (Exception ex) { - } - - // Wait for the expiry thread to complete - - try { - m_thread.join(DefaultFileTimeout); - } catch (Exception ex) { - } - } - }; - - /** - * Class constructor - * - * @param name String - * @param rpcAuth RpcAuthenticator - */ - public NetworkFileCache(String name, RpcAuthenticator rpcAuth) { - - // Create the file cache - - m_fileCache = new Hashtable(); - - // Start the file expiry thread - - m_expiryThread = new FileExpiry(DefaultFileTimeout / 4, name); - - // Set the RPC authenticator - - m_rpcAuthenticator = rpcAuth; - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() { - return m_debug; - } - - /** - * Add a file to the cache - * - * @param file NetworkFile - * @param conn TreeConnection - * @param sess SrvSession - */ - public synchronized final void addFile(NetworkFile file, TreeConnection conn, SrvSession sess) { - - // Add the file id mapping - - synchronized (m_fileCache) { - m_fileCache.put(new Integer(file.getFileId()), new FileEntry(file, conn, sess)); - } - - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Added file " + file.getName() + ", fid=" + file.getFileId()); - } - - /** - * Remove a file from the cache - * - * @param id - */ - public synchronized final void removeFile(int id) { - - // Create the search key - - Integer fileId = new Integer(id); - - synchronized (m_fileCache) { - m_fileCache.remove(fileId); - } - } - - /** - * Find a file via the file id - * - * @param id int - * @param sess SrvSession - * @return NetworkFile - */ - public synchronized final NetworkFile findFile(int id, SrvSession sess) { - - // Create the search key - - Integer fileId = new Integer(id); - FileEntry fentry = null; - - synchronized (m_fileCache) { - fentry = (FileEntry) m_fileCache.get(fileId); - } - - // Return the file, or null if not found - - if (fentry != null) { - - // Update the file timeout and return the file - - fentry.updateTimeout(); - fentry.setSession(sess); - - return fentry.getFile(); - } - - // Invalid file id - - return null; - } - - /** - * Return the count of entries in the cache - * - * @return int - */ - public final int numberOfEntries() { - return m_fileCache.size(); - } - - /** - * Close the expiry cache, close and remove all files from the cache and - * stop the expiry thread. - */ - public final void closeAllFiles() { - - // Enumerate the cache entries - - Enumeration keys = m_fileCache.keys(); - - while (keys.hasMoreElements()) { - - // Get the current key and lookup the matching value - - Integer key = (Integer) keys.nextElement(); - FileEntry entry = (FileEntry) m_fileCache.get(key); - - // Expire the file entry - - entry.updateTimeout(0L); - } - - // Shutdown the expiry thread, this should close the files - - m_expiryThread.requestShutdown(); - } - - /** - * Dump the cache entries to the debug device - */ - public final void dumpCache() { - - // Dump the count of entries in the cache - - logger.debug("NetworkFileCache entries=" + numberOfEntries()); - - // Enumerate the cache entries - - Enumeration keys = m_fileCache.keys(); - - while (keys.hasMoreElements()) { - - // Get the current key and lookup the matching value - - Integer key = (Integer) keys.nextElement(); - FileEntry entry = (FileEntry) m_fileCache.get(key); - - // Dump the entry details - - logger.debug("fid=" + key + ": " + entry); - } - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/SearchCache.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/SearchCache.java deleted file mode 100644 index a655bbc521..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/SearchCache.java +++ /dev/null @@ -1,372 +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.server.oncrpc.nfs; - -import org.alfresco.filesys.server.filesys.SearchContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Search Cache Class - * - *

Holds the details of the active searches for the NFS server - * - * @author GKSpencer - */ -public class SearchCache { - - // Debug logging - - private static final Log logger = LogFactory.getLog(SearchCache.class); - - // Maximum number of active searches - - public static final int MaximumSearches = 255; - - // Default search timeout - - public static final long DefaultSearchTimeout = 30000L; // 30 seconds - - // Array of active searches, last allocated index - - private SearchEntry[] m_searches; - private int m_lastIdx; - - // Search timeout - - private long m_searchTmo = DefaultSearchTimeout; - - // Debug enable flag - - private boolean m_debug = true; - - /** - * Search Entry Class - */ - protected class SearchEntry - { - - // Search context - - private SearchContext m_search; - - // Search timeout - - private long m_timeout; - - /** - * Class constructor - * - * @param search SearchContext - */ - public SearchEntry(SearchContext search) - { - m_search = search; - updateTimeout(); - } - - /** - * Return the search timeout - * - * @return long - */ - public final long getTimeout() - { - return m_timeout; - } - - /** - * Return the search context - * - * @return SearchContext - */ - public final SearchContext getSearch() - { - return m_search; - } - - /** - * Update the search timeout - */ - public final void updateTimeout() - { - m_timeout = System.currentTimeMillis() + m_searchTmo; - } - }; - - /** - * Search Expiry Thread Class - */ - protected class SearchExpiry implements Runnable - { - - // Expiry thread - - private Thread m_thread; - - // Wakeup interval - - private long m_wakeup; - - /** - * Class Constructor - * - * @param wakeup long - */ - public SearchExpiry(long wakeup) - { - - // Set the wakeup interval - - m_wakeup = wakeup; - - // Create and start the search expiry thread - - m_thread = new Thread(this); - m_thread.setDaemon(true); - m_thread.setName("NFSSearchExpiry"); - m_thread.start(); - } - - /** - * Main thread method - */ - public void run() - { - - // Loop until shutdown - - while (true) - { - - // Sleep for a while - - try - { - Thread.sleep(m_wakeup); - } catch (InterruptedException ex) - { - } - - // Get the current system time - - long timeNow = System.currentTimeMillis(); - - // Check for expired searches - - synchronized (m_searches) - { - - // Check all allocated slots - - for (int i = 0; i < m_searches.length; i++) - { - - // Check if the current slot has a valid entry - - if (m_searches[i] != null && m_searches[i].getTimeout() < timeNow) - { - - // Remove the current search entry - - SearchEntry entry = m_searches[i]; - m_searches[i] = null; - - // Close the search - - entry.getSearch().closeSearch(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("NFSSearchExpiry: Closed search=" + entry.getSearch().getSearchString() - + ", id=" + i); - } - } - } - } - } - }; - - /** - * Default constructor - */ - public SearchCache() - { - - // Create the active search list - - m_searches = new SearchEntry[MaximumSearches]; - - // Start the search expiry thread - - new SearchExpiry(DefaultSearchTimeout / 2); - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Allocate a search slot - * - * @param search SearchContext - * @return int - */ - public final int allocateSearchId(SearchContext search) - { - - synchronized (m_searches) - { - - // Search for a free slot in the search list - - int cnt = 0; - - while (cnt < MaximumSearches) - { - - // Check if the index has wrapped - - if (m_lastIdx >= MaximumSearches) - m_lastIdx = 0; - - // Check if the current slot is empty - - if (m_searches[m_lastIdx] == null) - { - - // Use this slot - - SearchEntry entry = new SearchEntry(search); - m_searches[m_lastIdx] = entry; - return m_lastIdx++; - } else - m_lastIdx++; - - // Update the slot count - - cnt++; - } - } - - // No empty search slot found - - return -1; - } - - /** - * Release a search slot - * - * @param id int - */ - public final void releaseSearchId(int id) - { - - // Range check the id - - if (id < 0 || id >= MaximumSearches) - return; - - // Delete the search entry - - synchronized (m_searches) - { - m_searches[id] = null; - } - } - - /** - * Return the required search context - * - * @param id int - * @return SearchContext - */ - public final SearchContext getSearch(int id) - { - - // Range check the id - - if (id < 0 || id >= MaximumSearches) - return null; - - // Get the search entry - - SearchEntry entry = null; - - synchronized (m_searches) - { - entry = m_searches[id]; - } - - // Return the search context, if valid - - if (entry != null) - { - - // Update the search timeout and return the search - - entry.updateTimeout(); - return entry.getSearch(); - } - - // Invalid search - - return null; - } - - /** - * Dump the active search list - */ - public final void dumpSearches() - { - - synchronized (m_searches) - { - - // Find all active searches in the list - - for (int i = 0; i < m_searches.length; i++) - { - - // Check if the current search slot is active - - if (m_searches[i] != null) - { - - // Get the search details - - SearchEntry entry = m_searches[i]; - - logger.debug("" + i + ": " + entry.getSearch().toString()); - } - } - } - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetails.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetails.java deleted file mode 100644 index ce1ace98d8..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetails.java +++ /dev/null @@ -1,100 +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.server.oncrpc.nfs; - -/** - * Share Details Class - * - *

Contains the file id cache, active search cache and tree connection details - * of a shared filesystem. - * - * @author GKSpencer - */ -public class ShareDetails { - - // Share name - - private String m_name; - - // File id to path conversion cache - - private FileIdCache m_idCache; - - // Flag to indicate if the filesystem driver for this share supports file id - // lookups - // via the FileIdInterface - - private boolean m_fileIdLookup; - - /** - * Class constructor - * - * @param name String - * @param fileIdSupport boolean - */ - public ShareDetails(String name, boolean fileIdSupport) - { - - // Save the share name - - m_name = name; - - // Set the file id support flag - - m_fileIdLookup = fileIdSupport; - - // Create the file id and search caches - - m_idCache = new FileIdCache(); - } - - /** - * Return the share name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the file id cache - * - * @return FileIdCache - */ - public final FileIdCache getFileIdCache() - { - return m_idCache; - } - - /** - * Determine if the filesystem driver for this share has file id support - * - * @return boolean - */ - public final boolean hasFileIdSupport() - { - return m_fileIdLookup; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetailsHash.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetailsHash.java deleted file mode 100644 index 234bdbacda..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/ShareDetailsHash.java +++ /dev/null @@ -1,105 +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.server.oncrpc.nfs; - -import java.util.*; - -/** - * Share Details Hash Class - * - *

Hashtable of ShareDetails for the available disk shared devices. ShareDetails are indexed using the - * hash of the share name to allow mounts to be persistent across server restarts. - * - * @author GKSpencer - */ -public class ShareDetailsHash { - - // Share name hash to share details - - private Hashtable m_details; - - /** - * Class constructor - */ - public ShareDetailsHash() - { - m_details = new Hashtable(); - } - - /** - * Add share details to the list of available shares - * - * @param details ShareDetails - */ - public final void addDetails(ShareDetails details) - { - m_details.put(new Integer(details.getName().hashCode()), details); - } - - /** - * Delete share details from the list - * - * @param shareName String - * @return ShareDetails - */ - public final ShareDetails deleteDetails(String shareName) - { - return (ShareDetails) m_details.get(new Integer(shareName.hashCode())); - } - - /** - * Find share details for the specified share name - * - * @param shareName String - * @return ShareDetails - */ - public final ShareDetails findDetails(String shareName) - { - - // Get the share details for the associated share name - - ShareDetails details = (ShareDetails) m_details.get(new Integer(shareName.hashCode())); - - // Return the share details - - return details; - } - - /** - * Find share details for the specified share name hash code - * - * @param hashCode int - * @return ShareDetails - */ - public final ShareDetails findDetails(int hashCode) - { - - // Get the share details for the associated share name - - ShareDetails details = (ShareDetails) m_details.get(new Integer(hashCode)); - - // Return the share details - - return details; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/nfs/StaleHandleException.java b/source/java/org/alfresco/filesys/server/oncrpc/nfs/StaleHandleException.java deleted file mode 100644 index 9b820f9767..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/nfs/StaleHandleException.java +++ /dev/null @@ -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.server.oncrpc.nfs; - -/** - * Stale Handle Exception Class - * - * @author GKSpencer - */ -public class StaleHandleException extends Exception { - - // Object version id - - private static final long serialVersionUID = -8607694363687774475L; - - /** - * Default constructor - */ - public StaleHandleException() - { - super(); - } - - /** - * Class constructor - * - * @param msg String - */ - public StaleHandleException(String msg) - { - super(msg); - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapper.java b/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapper.java deleted file mode 100644 index d02ceb2f8c..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapper.java +++ /dev/null @@ -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.server.oncrpc.portmap; - -/** - * PortMapper RPC Service Constants Class - * - * @author GKSpencer - */ -public class PortMapper { - - // Default port mapper port - - public static final int DefaultPort = 111; - - // Program and version id - - public static final int ProgramId = 100000; - public static final int VersionId = 2; - - // RPC procedure ids - - public static final int ProcNull = 0; - public static final int ProcSet = 1; - public static final int ProcUnSet = 2; - public static final int ProcGetPort = 3; - public static final int ProcDump = 4; - public static final int ProcMax = 4; - - // RPC procedure names - - private static final String[] _procNames = { "Null", "Set", "UnSet", - "GetPort", "Dump" }; - - /** - * Return a procedure id as a name - * - * @param id - * int - * @return String - */ - public final static String getProcedureName(int id) { - if (id < 0 || id > ProcMax) - return null; - return _procNames[id]; - } -} diff --git a/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapperServer.java b/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapperServer.java deleted file mode 100644 index a9a0e8fb2d..0000000000 --- a/source/java/org/alfresco/filesys/server/oncrpc/portmap/PortMapperServer.java +++ /dev/null @@ -1,557 +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.server.oncrpc.portmap; - -import java.io.*; -import java.util.*; - -import org.alfresco.filesys.server.NetworkServer; -import org.alfresco.filesys.server.ServerListener; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.oncrpc.PortMapping; -import org.alfresco.filesys.server.oncrpc.Rpc; -import org.alfresco.filesys.server.oncrpc.RpcPacket; -import org.alfresco.filesys.server.oncrpc.RpcProcessor; -import org.alfresco.filesys.server.oncrpc.TcpRpcSessionHandler; -import org.alfresco.filesys.server.oncrpc.UdpRpcDatagramHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Port Mapper Server Class - * - * @author GKSpencer - */ -public class PortMapperServer extends NetworkServer implements RpcProcessor { - - // Debug logging - - protected static final Log logger = LogFactory.getLog("org.alfresco.nfs.protocol"); - - // Constants - // - // Default port mapper port - - public final static int DefaultPort = 111; - - // Maximum request size to accept - - public final static int MaxRequestSize = 1024; - - // Incoming datagram handler for UDP requests - - private UdpRpcDatagramHandler m_udpHandler; - - // Incoming session handler for TCP requests - - private TcpRpcSessionHandler m_tcpHandler; - - // Portmapper port - - private int m_port; - - // Table of active port mappings - - private Hashtable m_mappings; - private Hashtable m_noVerMappings; - - /** - * Class constructor - * - * @param config - * ServerConfiguration - */ - public PortMapperServer(ServerConfiguration config) { - super("Portmap", config); - - // Enable/disable debug output - - setDebug(config.hasPortMapperDebug()); - - // Set the port to use - - if (config.getPortMapperPort() != 0) - setPort(config.getPortMapperPort()); - else - setPort(DefaultPort); - - // Create the mappings tables - - m_mappings = new Hashtable(); - m_noVerMappings = new Hashtable(); - } - - /** - * Return the server port - * - * @return int - */ - public final int getPort() { - return m_port; - } - - /** - * Start the portmapper server - */ - public void startServer() { - - try { - - // Create the UDP RPC handler to accept incoming requests - - m_udpHandler = new UdpRpcDatagramHandler("PortMap", "Port", this, this, null, getPort(), MaxRequestSize); - m_udpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread udpThread = new Thread(m_udpHandler); - udpThread.setName("PortMap_UDP"); - udpThread.start(); - - // Create the TCP RPC handler to accept incoming requests - - m_tcpHandler = new TcpRpcSessionHandler("PortMap", "Port", this, this, null, getPort(), MaxRequestSize); - m_tcpHandler.initializeSessionHandler(this); - - // Start the UDP request listener is a seperate thread - - Thread tcpThread = new Thread(m_tcpHandler); - tcpThread.setName("PortMap_TCP"); - tcpThread.start(); - - // Add port mapper entries for the portmapper service - - PortMapping portMap = new PortMapping(PortMapper.ProgramId, PortMapper.VersionId, Rpc.UDP, getPort()); - addPortMapping(portMap); - - portMap = new PortMapping(PortMapper.ProgramId, PortMapper.VersionId, Rpc.TCP, getPort()); - addPortMapping(portMap); - } - catch (Exception ex) { - logger.debug(ex); - } - } - - /** - * Shutdown the server - * - * @param immediate - * boolean - */ - public void shutdownServer(boolean immediate) { - - // Stop the RPC handlers - - if (m_udpHandler != null) { - m_udpHandler.closeSessionHandler(this); - m_udpHandler = null; - } - - if (m_tcpHandler != null) { - m_tcpHandler.closeSessionHandler(this); - m_tcpHandler = null; - } - - // Fire a shutdown notification event - - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Set the server port - * - * @param port - * int - */ - public final void setPort(int port) { - m_port = port; - } - - /** - * Process an RPC request - * - * @param rpc - * RpcPacket - * @return RpcPacket - * @throws IOException - */ - public RpcPacket processRpc(RpcPacket rpc) throws IOException { - - // Validate the request - - if (rpc.getProgramId() != PortMapper.ProgramId) { - - // Request is not for us - - rpc.buildAcceptErrorResponse(Rpc.StsProgUnavail); - return rpc; - } else if (rpc.getProgramVersion() != PortMapper.VersionId) { - - // Request is not for this version of portmapper - - rpc.buildProgramMismatchResponse(PortMapper.VersionId, - PortMapper.VersionId); - return rpc; - } - - // Position the RPC buffer pointer at the start of the call parameters - - rpc.positionAtParameters(); - - // Process the RPC request - - RpcPacket response = null; - - switch (rpc.getProcedureId()) { - - // Null request - - case PortMapper.ProcNull: - response = procNull(rpc); - break; - - // Set a port - - case PortMapper.ProcSet: - response = procSet(rpc); - break; - - // Release a port - - case PortMapper.ProcUnSet: - response = procUnSet(rpc); - break; - - // Get the port for a service - - case PortMapper.ProcGetPort: - response = procGetPort(rpc); - break; - - // Dump ports request - - case PortMapper.ProcDump: - response = procDump(rpc); - break; - } - - // Return the RPC response - - return response; - } - - /** - * Process the null request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procNull(RpcPacket rpc) { - - // Build the response - - rpc.buildResponseHeader(); - return rpc; - } - - /** - * Process the set request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procSet(RpcPacket rpc) { - - // Get the call parameters - - int progId = rpc.unpackInt(); - int verId = rpc.unpackInt(); - int proto = rpc.unpackInt(); - int port = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[PortMap] Set port program=" + Rpc.getServiceName(progId) + ", version=" + verId - + ", protocol=" + (proto == Rpc.TCP ? "TCP" : "UDP") + ", port=" + port); - - // Check if the port is already mapped - - PortMapping portMap = findPortMapping(progId, verId, proto); - int portAdded = Rpc.False; - - if (portMap == null) { - - // Add a mapping for the new service - - portMap = new PortMapping(progId, verId, proto, port); - if (addPortMapping(portMap) == true) - portAdded = Rpc.True; - } - - // Check if the service is on the same port as the current port mapping, - // and it is not - // an attempt to set the port mapper service port. - - else if (progId != PortMapper.ProgramId && portMap.getPort() == port) { - - // Settings are the same as the existing service settings so accept - // it - - portAdded = Rpc.True; - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Pack a boolean indicating if the port was added, or not - - rpc.packInt(portAdded); - rpc.setLength(); - - // Return the response - - return rpc; - } - - /** - * Process the unset request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procUnSet(RpcPacket rpc) { - - // Get the call parameters - - int progId = rpc.unpackInt(); - int verId = rpc.unpackInt(); - int proto = rpc.unpackInt(); - int port = rpc.unpackInt(); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[PortMap] UnSet port program=" + Rpc.getServiceName(progId) + ", version=" + verId - + ", protocol=" + (proto == Rpc.TCP ? "TCP" : "UDP") + ", port=" + port); - - // Check if the port is mapped, and it is not an attempt to remove a - // portmapper portt - - PortMapping portMap = findPortMapping(progId, verId, proto); - int portRemoved = Rpc.False; - - if (portMap != null && progId != PortMapper.ProgramId) { - - // Remove the port mapping - - if (removePortMapping(portMap) == true) - portRemoved = Rpc.True; - } - - // Build the response header - - rpc.buildResponseHeader(); - - // Pack a boolean indicating if the port was removed, or not - - rpc.packInt(portRemoved); - rpc.setLength(); - - // Return the response - - return rpc; - } - - /** - * Process the get port request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procGetPort(RpcPacket rpc) { - - // Get the call parameters - - int progId = rpc.unpackInt(); - int verId = rpc.unpackInt(); - int proto = rpc.unpackInt(); - - // Find the required port mapping - - PortMapping portMap = findPortMapping(progId, verId, proto); - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[PortMap] Get port program=" + Rpc.getServiceName(progId) + ", version=" + verId - + ", protocol=" + (proto == Rpc.TCP ? "TCP" : "UDP") + ", port=" + (portMap != null ? portMap.getPort() : 0)); - - // Build the response header - - rpc.buildResponseHeader(); - - // Pack the port number of the requested RPC service, or zero if not - // found - - rpc.packInt(portMap != null ? portMap.getPort() : 0); - rpc.setLength(); - - // Return the response - - return rpc; - } - - /** - * Process the dump request - * - * @param rpc - * RpcPacket - * @return RpcPacket - */ - private final RpcPacket procDump(RpcPacket rpc) { - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("[PortMap] Dump ports request from " + rpc.getClientDetails()); - - // Build the response - - rpc.buildResponseHeader(); - - // Pack the active port mappings structures - - Enumeration enm = m_mappings.elements(); - - while (enm.hasMoreElements()) { - - // Get the current port mapping - - PortMapping portMap = (PortMapping) enm.nextElement(); - - // Pack the port mapping structure - - rpc.packInt(Rpc.True); - rpc.packPortMapping(portMap); - } - - // Pack the end of list structure, set the response length - - rpc.packInt(Rpc.False); - rpc.setLength(); - - // Return the response - - return rpc; - } - - /** - * Add a port mapping to the active list - * - * @param portMap - * PortMapping - * @return boolean - */ - private final boolean addPortMapping(PortMapping portMap) { - - // Check if there is an existing port mapping that matches the new port - - Integer key = new Integer(portMap.hashCode()); - if (m_mappings.get(key) != null) - return false; - - // Add the port mapping - - m_mappings.put(key, portMap); - - // Add a port mapping with a version id of zero - - key = new Integer(PortMapping.generateHashCode(portMap.getProgramId(), 0, portMap.getProtocol())); - m_noVerMappings.put(key, portMap); - - // Indicate that the mapping was added - - return true; - } - - /** - * Remove a port mapping from the active list - * - * @param portMap - * PortMapping - * @return boolean - */ - private final boolean removePortMapping(PortMapping portMap) { - - // Remove the port mapping from the active lists - - Integer key = new Integer(portMap.hashCode()); - Object removedObj = m_mappings.remove(key); - - key = new Integer(PortMapping.generateHashCode(portMap.getProgramId(), 0, portMap.getProtocol())); - m_noVerMappings.remove(key); - - // Return a status indicating if the mapping was removed - - return removedObj != null ? true : false; - } - - /** - * Search for a port mapping - * - * @param progId - * int - * @param verId - * int - * @param proto - * int - * @return PortMapping - */ - private final PortMapping findPortMapping(int progId, int verId, int proto) { - - // Create a key for the RPC service - - Integer key = new Integer(PortMapping.generateHashCode(progId, verId, - proto)); - - // Search for the required port mapping, including the version id - - PortMapping portMap = (PortMapping) m_mappings.get(key); - if (portMap == null && verId == 0) { - - // Search for the port mapping without the version id - - portMap = (PortMapping) m_noVerMappings.get(key); - } - - // Return the port mapping, or null if not found - - return portMap; - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/LocalPseudoFile.java b/source/java/org/alfresco/filesys/server/pseudo/LocalPseudoFile.java deleted file mode 100644 index 9d21e90610..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/LocalPseudoFile.java +++ /dev/null @@ -1,120 +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.server.pseudo; - -import java.io.File; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.NetworkFile; - -/** - * Local Pseudo File Class - * - *

Pseudo file class that uses a file on the local filesystem. - * - * @author gkspencer - */ -public class LocalPseudoFile extends PseudoFile -{ - // Path to the file on the local filesystem - - private String m_path; - - /** - * Class constructor - * - * @param name String - * @param path String - */ - public LocalPseudoFile(String name, String path) - { - super(name); - - m_path = path; - } - - /** - * Return the path to the file on the local filesystem - * - * @return String - */ - public final String getFilePath() - { - return m_path; - } - - /** - * Return the file information for the pseudo file - * - * @return FileInfo - */ - public FileInfo getFileInfo() - { - // Check if the file information is valid - - if ( getInfo() == null) { - - // Get the file details - - File localFile = new File( getFilePath()); - if ( localFile.exists()) - { - // Create the file information - - FileInfo fInfo = new FileInfo( getFileName(), localFile.length(), getAttributes()); - - // Set the file creation/modification times - - fInfo.setModifyDateTime( localFile.lastModified()); - fInfo.setCreationDateTime( _creationDateTime); - fInfo.setChangeDateTime( _creationDateTime); - - // Set the allocation size, round up the actual length - - fInfo.setAllocationSize(( localFile.length() + 512L) & 0xFFFFFFFFFFFFFE00L); - - setFileInfo( fInfo); - } - } - - // Return the file information - - return getInfo(); - } - - /** - * Return a network file for reading/writing the pseudo file - * - * @param netPath String - * @return NetworkFile - */ - public NetworkFile getFile(String netPath) - { - // Create a pseudo file mapped to a file in the local filesystem - - return new PseudoNetworkFile( getFileName(), getFilePath(), netPath); - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/MemoryNetworkFile.java b/source/java/org/alfresco/filesys/server/pseudo/MemoryNetworkFile.java deleted file mode 100644 index 46b2ec47bd..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/MemoryNetworkFile.java +++ /dev/null @@ -1,255 +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.server.pseudo; - -import java.io.IOException; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.smb.SeekType; - -/** - * In Memory Network File Class - * - *

In memory network file implementation that uses a memory buffer for the file data. - * - * @author gkspencer - */ -public class MemoryNetworkFile extends NetworkFile -{ - // Current file position - - private long m_filePos; - - // File data - - private byte[] m_data; - - /** - * Class constructor. - * - * @param name String - * @param localPath String - * @param finfo FileInfo - */ - public MemoryNetworkFile(String name, byte[] data, FileInfo finfo) - { - super( name); - - // Set the file data - - m_data = data; - if ( m_data == null) - m_data = new byte[0]; - - // Set the file size - - setFileSize( m_data.length); - - // Set the creation and modification date/times - - setModifyDate( finfo.getModifyDateTime()); - setCreationDate( finfo.getCreationDateTime()); - - // Set the file id and relative path - - if ( finfo.getPath() != null) - { - setFileId( finfo.getPath().hashCode()); - setFullName( finfo.getPath()); - } - } - - /** - * Close the network file. - */ - public void closeFile() throws java.io.IOException - { - // Nothing to do - } - - /** - * Return the current file position. - * - * @return long - */ - public long currentPosition() - { - return m_filePos; - } - - /** - * Flush the file. - * - * @exception IOException - */ - public void flushFile() throws IOException - { - // Nothing to do - } - - /** - * Determine if the end of file has been reached. - * - * @return boolean - */ - public boolean isEndOfFile() throws java.io.IOException - { - // Check if we reached end of file - - if ( m_filePos == m_data.length) - return true; - return false; - } - - /** - * Open the file. - * - * @param createFlag boolean - * @exception IOException - */ - public void openFile(boolean createFlag) throws java.io.IOException - { - // Indicate that the file is open - - setClosed(false); - } - - /** - * Read from the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param fileOff long - * @return Length of data read. - * @exception IOException - */ - public int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException - { - // Check if the read is within the file data range - - long fileLen = (long) m_data.length; - - if ( fileOff >= fileLen) - return 0; - - // Calculate the actual read length - - if (( fileOff + len) > fileLen) - len = (int) ( fileLen - fileOff); - - // Copy the data to the user buffer - - System.arraycopy( m_data, (int) fileOff, buf, pos, len); - - // Update the current file position - - m_filePos = fileOff + len; - - // Return the actual length of data read - - return len; - } - - /** - * Seek to the specified file position. - * - * @param pos long - * @param typ int - * @return long - * @exception IOException - */ - public long seekFile(long pos, int typ) throws IOException - { - // Seek to the required file position - - switch (typ) - { - // From start of file - - case SeekType.StartOfFile: - if (currentPosition() != pos) - m_filePos = pos; - break; - - // From current position - - case SeekType.CurrentPos: - m_filePos += pos; - break; - - // From end of file - - case SeekType.EndOfFile: - m_filePos += pos; - if ( m_filePos < 0) - m_filePos = 0L; - break; - } - - // Return the new file position - - return currentPosition(); - } - - /** - * Truncate the file - * - * @param siz long - * @exception IOException - */ - public void truncateFile(long siz) throws IOException - { - // Allow the truncate, do not alter the pseduo file data - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException - { - // Allow the write, just do not do anything - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param offset long - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException - { - // Allow the write, just do not do anything - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/MemoryPseudoFile.java b/source/java/org/alfresco/filesys/server/pseudo/MemoryPseudoFile.java deleted file mode 100644 index 4a8a92faa3..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/MemoryPseudoFile.java +++ /dev/null @@ -1,105 +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.server.pseudo; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.NetworkFile; - -/** - * In Memory Pseudo File Class - * - *

Pseudo file class that uses an in memory buffer for the file data. - * - * @author gkspencer - */ -public class MemoryPseudoFile extends PseudoFile -{ - // File data buffer - - private byte[] m_data; - - /** - * Class constructor - * - * @param name String - * @param data byte[] - */ - public MemoryPseudoFile(String name, byte[] data) - { - super( name); - - m_data = data; - } - - /** - * Return the file information for the pseudo file - * - * @return FileInfo - */ - public FileInfo getFileInfo() - { - // Check if the file information is valid - - if ( getInfo() == null) { - - // Create the file information - - FileInfo fInfo = new FileInfo( getFileName(), m_data != null ? m_data.length : 0, getAttributes()); - - // Set the file creation/modification times - - fInfo.setCreationDateTime( _creationDateTime); - fInfo.setModifyDateTime( _creationDateTime); - fInfo.setChangeDateTime( _creationDateTime); - - // Set the allocation size, round up the actual length - - fInfo.setAllocationSize(( fInfo.getSize() + 512L) & 0xFFFFFFFFFFFFFE00L); - - setFileInfo( fInfo); - } - - // Return the file information - - return getInfo(); - } - - /** - * Return a network file for reading/writing the pseudo file - * - * @param netPath String - * @return NetworkFile - */ - public NetworkFile getFile(String netPath) - { - // Create a pseudo file mapped to the in memory file data - - FileInfo finfo = getFileInfo(); - finfo.setPath( netPath); - - return new MemoryNetworkFile( getFileName(), m_data, finfo); - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoFile.java b/source/java/org/alfresco/filesys/server/pseudo/PseudoFile.java deleted file mode 100644 index b15e931d1f..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoFile.java +++ /dev/null @@ -1,192 +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.server.pseudo; - -import org.alfresco.filesys.server.filesys.FileAttribute; -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.NetworkFile; - -/** - * Pseudo File Class - * - *

Creates a pseudo file entry for a folder that maps to a file outside of the usual file area but appears - * in folder listings for the owner folder. - * - * @author gkspencer - */ -public abstract class PseudoFile -{ - // Dummy creation date/time to use for pseudo files - - protected static long _creationDateTime = System.currentTimeMillis(); - - // File name for pseudo file - - private String m_fileName; - - // File flags/attributes - - private int m_fileFlags = FileAttribute.ReadOnly; - - // File information, used for file information/folder searches - - private FileInfo m_fileInfo; - - /** - * Class constructor - * - * @param name String - */ - protected PseudoFile(String name) - { - m_fileName = name; - } - - /** - * Class constructor - * - * @param name String - * @param flags int - */ - protected PseudoFile(String name, int flags) - { - m_fileName = name; - m_fileFlags = flags; - } - - /** - * Return the pseudo file name as it will appear in folder listings - * - * @return String - */ - public final String getFileName() - { - return m_fileName; - } - - /** - * Return the standard file attributes - * - * @return int - */ - public final int getAttributes() - { - return m_fileFlags; - } - - /** - * Check if the pseudo file is a file - * - * @return boolean - */ - public final boolean isFile() - { - return (m_fileFlags & FileAttribute.Directory) != 0 ? false : true; - } - - /** - * Check if the pseudo file is a folder - * - * @return boolean - */ - public final boolean isDirectory() - { - return (m_fileFlags & FileAttribute.Directory) != 0 ? true : false; - } - - /** - * Check if the pseudo file is read-only - * - * @return boolean - */ - public final boolean isReadOnly() - { - return (m_fileFlags & FileAttribute.ReadOnly) != 0 ? true : false; - } - - /** - * Check if the pseudo file is hidden - * - * @return boolean - */ - public final boolean isHidden() - { - return (m_fileFlags & FileAttribute.Hidden) != 0 ? true : false; - } - - /** - * Return the file information for the pseudo file - * - * @return FileInfo - */ - public abstract FileInfo getFileInfo(); - - /** - * Return a network file for reading/writing the pseudo file - * - * @param netPath String - * @return NetworkFile - */ - public abstract NetworkFile getFile(String netPath); - - /** - * Set the file information - * - * @param fileInfo FileInfo - */ - protected final void setFileInfo( FileInfo finfo) - { - m_fileInfo = finfo; - } - - /** - * Return the file information - * - * @return FileInfo - */ - protected final FileInfo getInfo() - { - return m_fileInfo; - } - - /** - * Return the pseudo file as a string - * - * @return String - */ - public String toString() - { - StringBuilder str = new StringBuilder(); - - str.append("["); - str.append(getFileName()); - str.append(","); - str.append(getFileInfo()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileInterface.java b/source/java/org/alfresco/filesys/server/pseudo/PseudoFileInterface.java deleted file mode 100644 index 603ac3d0f5..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileInterface.java +++ /dev/null @@ -1,78 +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.server.pseudo; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.TreeConnection; - -/** - * Pseudo File Interface - * - *

Provides the ability to add files into the file listing of a folder. - * - * @author gkspencer - */ -public interface PseudoFileInterface -{ - /** - * Check if the specified path refers to a pseudo file - * - * @param sess SrvSession - * @param tree TreeConnection - * @param path String - * @return boolean - */ - public boolean isPseudoFile(SrvSession sess, TreeConnection tree, String path); - - /** - * Return the pseudo file for the specified path, or null if the path is not a pseudo file - * - * @param sess SrvSession - * @param tree TreeConnection - * @param path String - * @return PseudoFile - */ - public PseudoFile getPseudoFile(SrvSession sess, TreeConnection tree, String path); - - /** - * Add pseudo files to a folder so that they appear in a folder search - * - * @param sess SrvSession - * @param tree TreeConnection - * @param path String - * @return int - */ - public int addPseudoFilesToFolder(SrvSession sess, TreeConnection tree, String path); - - /** - * Delete a pseudo file - * - * @param sess SrvSession - * @param tree TreeConnection - * @param path String - */ - public void deletePseudoFile(SrvSession sess, TreeConnection tree, String path); -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileList.java b/source/java/org/alfresco/filesys/server/pseudo/PseudoFileList.java deleted file mode 100644 index 9d57a9bfff..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoFileList.java +++ /dev/null @@ -1,155 +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.server.pseudo; - -import java.util.ArrayList; -import java.util.List; - -/** - * Pseudo File List Class - * - *

Contains a list of pseudo file list entries for a folder. - * - * @author gkspencer - */ -public class PseudoFileList -{ - // List of pseudo files - - private List m_list; - - /** - * Default constructor - */ - public PseudoFileList() - { - m_list = new ArrayList(); - } - - /** - * Add a pseudo file to the list - * - * @param pfile PseudoFile - */ - public final void addFile( PseudoFile pfile) - { - m_list.add( pfile); - } - - /** - * Return the count of files in the list - * - * @return int - */ - public final int numberOfFiles() - { - return m_list.size(); - } - - /** - * Return the file at the specified index in the list - * - * @param idx int - * @return PseudoFile - */ - public final PseudoFile getFileAt(int idx) - { - if ( idx < m_list.size()) - return m_list.get(idx); - return null; - } - - /** - * Search for the specified pseudo file name - * - * @param fname String - * @param caseSensitive boolean - * @return PseudoFile - */ - public final PseudoFile findFile( String fname, boolean caseSensitive) - { - // Check if there are any entries in the list - - if ( m_list == null || m_list.size() == 0) - return null; - - // Search for the name match - - for ( PseudoFile pfile : m_list) - { - if ( caseSensitive && pfile.getFileName().equals( fname)) - return pfile; - else if ( pfile.getFileName().equalsIgnoreCase( fname)) - return pfile; - } - - // File not found - - return null; - } - - /** - * Remove the specified pseudo file from the list - * - * @param fname String - * @param caseSensitive boolean - * @return PseudoFile - */ - public final PseudoFile removeFile( String fname, boolean caseSensitive) - { - // Check if there are any entries in the list - - if ( m_list == null || m_list.size() == 0) - return null; - - // Search for the name match - - for ( int idx = 0; idx < m_list.size(); idx++) - { - // Get the current pseudo file - - PseudoFile pfile = m_list.get( idx); - boolean match = false; - - if ( caseSensitive && pfile.getFileName().equals( fname)) - match = true; - else if ( pfile.getFileName().equalsIgnoreCase( fname)) - match = true; - - // If we found the matching pseudo file remove it from the list - - if ( match) - { - m_list.remove( idx); - return pfile; - } - } - - // File not found - - return null; - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoFolderNetworkFile.java b/source/java/org/alfresco/filesys/server/pseudo/PseudoFolderNetworkFile.java deleted file mode 100644 index 47e55aaabd..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoFolderNetworkFile.java +++ /dev/null @@ -1,179 +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.server.pseudo; - -import java.io.IOException; - -import org.alfresco.filesys.server.filesys.AccessDeniedException; -import org.alfresco.filesys.server.filesys.FileAttribute; -import org.alfresco.filesys.server.filesys.NetworkFile; - -/** - * Pseudo Folder Network File Class - * - *

Represents an open pseudo folder. - * - * @author gkspencer - */ -public class PseudoFolderNetworkFile extends NetworkFile { - - /** - * Class constructor. - * - * @param name String - */ - public PseudoFolderNetworkFile(String name) - { - super( name); - - setAttributes( FileAttribute.Directory); - } - - /** - * Class constructor. - * - * @param name String - * @param relPath String - */ - public PseudoFolderNetworkFile(String name, String relPath) - { - super( name); - - setFullName( relPath); - setAttributes( FileAttribute.Directory); - } - - /** - * Close the network file. - */ - public void closeFile() throws java.io.IOException - { - // Nothing to do - } - - /** - * Return the current file position. - * - * @return long - */ - public long currentPosition() - { - return 0L; - } - - /** - * Flush the file. - * - * @exception IOException - */ - public void flushFile() throws IOException - { - // Nothing to do - } - - /** - * Determine if the end of file has been reached. - * - * @return boolean - */ - public boolean isEndOfFile() throws java.io.IOException - { - return true; - } - - /** - * Open the file. - * - * @param createFlag boolean - * @exception IOException - */ - public void openFile(boolean createFlag) throws java.io.IOException - { - } - - /** - * Read from the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param fileOff long - * @return Length of data read. - * @exception IOException - */ - public int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException - { - throw new AccessDeniedException( "Attempt to read/write folder file"); - } - - /** - * Seek to the specified file position. - * - * @param pos long - * @param typ int - * @return long - * @exception IOException - */ - public long seekFile(long pos, int typ) throws IOException - { - throw new AccessDeniedException( "Attempt to read/write folder file"); - } - - /** - * Truncate the file - * - * @param siz long - * @exception IOException - */ - public void truncateFile(long siz) throws IOException - { - throw new AccessDeniedException( "Attempt to read/write folder file"); - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException - { - throw new AccessDeniedException( "Attempt to read/write folder file"); - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param offset long - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException - { - throw new AccessDeniedException( "Attempt to read/write folder file"); - } -} diff --git a/source/java/org/alfresco/filesys/server/pseudo/PseudoNetworkFile.java b/source/java/org/alfresco/filesys/server/pseudo/PseudoNetworkFile.java deleted file mode 100644 index 7546beeeb4..0000000000 --- a/source/java/org/alfresco/filesys/server/pseudo/PseudoNetworkFile.java +++ /dev/null @@ -1,310 +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.server.pseudo; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; - -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.smb.SeekType; - -/** - * Pseudo File Network File Class - * - *

Represents an open pseudo file and provides access to the file data. - * - * @author gkspencer - */ -public class PseudoNetworkFile extends NetworkFile -{ - // File details - - protected File m_file; - - // Random access file used to read/write the actual file - - protected RandomAccessFile m_io; - - // End of file flag - - protected boolean m_eof; - - /** - * Class constructor. - * - * @param name String - * @param localPath String - * @param netPath String - */ - public PseudoNetworkFile(String name, String localPath, String netPath) - { - super( name); - - // Set the file using the existing file object - - m_file = new File( localPath); - - // Set the file size - - setFileSize(m_file.length()); - m_eof = false; - - // Set the modification date/time, if available. Fake the creation date/time as it's not - // available from the File class - - long modDate = m_file.lastModified(); - setModifyDate(modDate); - setCreationDate(modDate); - - // Set the file id - - setFileId(netPath.hashCode()); - - // Set the full relative path - - setFullName( netPath); - } - - /** - * Close the network file. - */ - public void closeFile() throws java.io.IOException - { - - // Close the file, if used - - if (m_io != null) - { - - // Close the file - - m_io.close(); - m_io = null; - - // Set the last modified date/time for the file - - if (this.getWriteCount() > 0) - m_file.setLastModified(System.currentTimeMillis()); - - // Indicate that the file is closed - - setClosed(true); - } - } - - /** - * Return the current file position. - * - * @return long - */ - public long currentPosition() - { - - // Check if the file is open - - try - { - if (m_io != null) - return m_io.getFilePointer(); - } - catch (Exception ex) - { - } - return 0; - } - - /** - * Flush the file. - * - * @exception IOException - */ - public void flushFile() throws IOException - { - // Flush all buffered data - - if (m_io != null) - m_io.getFD().sync(); - } - - /** - * Determine if the end of file has been reached. - * - * @return boolean - */ - public boolean isEndOfFile() throws java.io.IOException - { - // Check if we reached end of file - - if (m_io != null && m_io.getFilePointer() == m_io.length()) - return true; - return false; - } - - /** - * Open the file. - * - * @param createFlag boolean - * @exception IOException - */ - public void openFile(boolean createFlag) throws java.io.IOException - { - - synchronized (m_file) - { - // Check if the file is open - - if (m_io == null) - { - - // Open the file, always read-only for now - - m_io = new RandomAccessFile(m_file, "r"); - - // Indicate that the file is open - - setClosed(false); - } - } - } - - /** - * Read from the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param fileOff long - * @return Length of data read. - * @exception IOException - */ - public int readFile(byte[] buf, int len, int pos, long fileOff) throws java.io.IOException - { - - // Open the file, if not already open - - if (m_io == null) - openFile(false); - - // Seek to the required file position - - if (currentPosition() != fileOff) - seekFile(fileOff, SeekType.StartOfFile); - - // Read from the file - - int rdlen = m_io.read(buf, pos, len); - - // Return the actual length of data read - - return rdlen; - } - - /** - * Seek to the specified file position. - * - * @param pos long - * @param typ int - * @return long - * @exception IOException - */ - public long seekFile(long pos, int typ) throws IOException - { - - // Open the file, if not already open - - if (m_io == null) - openFile(false); - - // Check if the current file position is the required file position - - switch (typ) - { - - // From start of file - - case SeekType.StartOfFile: - if (currentPosition() != pos) - m_io.seek(pos); - break; - - // From current position - - case SeekType.CurrentPos: - m_io.seek(currentPosition() + pos); - break; - - // From end of file - - case SeekType.EndOfFile: { - long newPos = m_io.length() + pos; - m_io.seek(newPos); - } - break; - } - - // Return the new file position - - return currentPosition(); - } - - /** - * Truncate the file - * - * @param siz long - * @exception IOException - */ - public void truncateFile(long siz) throws IOException - { - // Allow the truncate, just do not do anything - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException - { - // Allow the write, just do not do anything - } - - /** - * Write a block of data to the file. - * - * @param buf byte[] - * @param len int - * @param pos int - * @param offset long - * @exception IOException - */ - public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException - { - // Allow the write, just do not do anything - } -} diff --git a/source/java/org/alfresco/filesys/smb/Capability.java b/source/java/org/alfresco/filesys/smb/Capability.java deleted file mode 100644 index 49f300a912..0000000000 --- a/source/java/org/alfresco/filesys/smb/Capability.java +++ /dev/null @@ -1,56 +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.smb; - -/** - * SMB Capabilities Class - *

- * Contains the capability flags for the client/server during a session setup. - * - * @author GKSpencer - */ -public class Capability -{ - // Capabilities - - public static final int RawMode = 0x00000001; - public static final int MpxMode = 0x00000002; - public static final int Unicode = 0x00000004; - public static final int LargeFiles = 0x00000008; - public static final int NTSMBs = 0x00000010; - public static final int RemoteAPIs = 0x00000020; - public static final int NTStatus = 0x00000040; - public static final int Level2Oplocks = 0x00000080; - public static final int LockAndRead = 0x00000100; - public static final int NTFind = 0x00000200; - public static final int DFS = 0x00001000; - public static final int InfoPassthru = 0x00002000; - public static final int LargeRead = 0x00004000; - public static final int LargeWrite = 0x00008000; - public static final int UnixExtensions = 0x00800000; - public static final int BulkTransfer = 0x20000000; - public static final int CompressedData = 0x40000000; - public static final int ExtendedSecurity = 0x80000000; -} diff --git a/source/java/org/alfresco/filesys/smb/DataType.java b/source/java/org/alfresco/filesys/smb/DataType.java deleted file mode 100644 index c1f8dd1a23..0000000000 --- a/source/java/org/alfresco/filesys/smb/DataType.java +++ /dev/null @@ -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.smb; - -/** - * SMB data type class. - *

- * This class contains the data types that are used within an SMB protocol packet. - */ - -public class DataType -{ - - // SMB data types - - public static final char DataBlock = (char) 0x01; - public static final char Dialect = (char) 0x02; - public static final char Pathname = (char) 0x03; - public static final char ASCII = (char) 0x04; - public static final char VariableBlock = (char) 0x05; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/Dialect.java b/source/java/org/alfresco/filesys/smb/Dialect.java deleted file mode 100644 index d5523c8d32..0000000000 --- a/source/java/org/alfresco/filesys/smb/Dialect.java +++ /dev/null @@ -1,415 +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.smb; - -/** - * SMB dialect class. - *

- * This class contains the available SMB protocol dialects that may be negotiated when an SMB - * session is setup. - */ - -public final class Dialect -{ - - // SMB dialect strings, encoded into the SMB session setup packet. - - private static final String[] protList = { - "PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0" }; - - // SMB dialect type strings - - private static final String[] protType = { - "Core", - "CorePlus", - "DOS LANMAN 1.0", - "LANMAN1.0", - "DOS LANMAN 2.1", - "LM1.2X002", - "LANMAN2.1", - "NT LM 0.12" }; - - // Dialect constants - - public static final int Core = 0; - public static final int CorePlus = 1; - public static final int DOSLanMan1 = 2; - public static final int LanMan1 = 3; - public static final int DOSLanMan2 = 4; - public static final int LanMan2 = 5; - public static final int LanMan2_1 = 6; - public static final int NT = 7; - public static final int Max = 8; - - public static final int Unknown = -1; - - // SMB dialect type to string conversion array - - private static final int[] protIdx = { - Core, - CorePlus, - DOSLanMan1, - DOSLanMan1, - LanMan1, - DOSLanMan2, - LanMan2, - LanMan2_1, - LanMan2_1, - NT, - NT, - NT }; - - // SMB dialect type to string conversion array length - - public static final int SMB_PROT_MAXSTRING = protIdx.length; - - // Table that maps SMB commands to the minimum required SMB dialect - - private static final int[] cmdtable = { - Core, // CreateDirectory - Core, // DeleteDirectory - Core, // OpenFile - Core, // CreateFile - Core, // CloseFile - Core, // FlushFile - Core, // DeleteFile - Core, // RenameFile - Core, // QueryFileInfo - Core, // SetFileInfo - Core, // Read - Core, // Write - Core, // LockFile - Core, // UnlockFile - Core, // CreateTemporary - Core, // CreateNew - Core, // CheckDirectory - Core, // ProcessExit - Core, // SeekFile - LanMan1, // LockAndRead - LanMan1, // WriteAndUnlock - 0, // Unused - 0, // .. - 0, // .. - 0, // .. - 0, // .. - LanMan1, // ReadRaw - LanMan1, // WriteMpxSecondary - LanMan1, // WriteRaw - LanMan1, // WriteMpx - 0, // Unused - LanMan1, // WriteComplete - 0, // Unused - LanMan1, // SetInformation2 - LanMan1, // QueryInformation2 - LanMan1, // LockingAndX - LanMan1, // Transaction - LanMan1, // TransactionSecondary - LanMan1, // Ioctl - LanMan1, // Ioctl2 - LanMan1, // Copy - LanMan1, // Move - LanMan1, // Echo - LanMan1, // WriteAndClose - LanMan1, // OpenAndX - LanMan1, // ReadAndX - LanMan1, // WriteAndX - 0, // Unused - LanMan1, // CloseAndTreeDisconnect - LanMan2, // Transaction2 - LanMan2, // Transaction2Secondary - LanMan2, // FindClose2 - LanMan1, // FindNotifyClose - 0, // Unused - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - Core, // TreeConnect - Core, // TreeDisconnect - Core, // Negotiate - Core, // SessionSetupAndX - LanMan1, // LogoffAndX - LanMan1, // TreeConnectAndX - 0, // Unused - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - Core, // DiskInformation - Core, // Search - LanMan1, // Find - LanMan1, // FindUnique - 0, // Unused - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - NT, // NTTransact - NT, // NTTransactSecondary - NT, // NTCreateAndX - NT, // NTCancel - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - Core, // OpenPrintFile - Core, // WritePrintFile - Core, // ClosePrintFile - Core, // GetPrintQueue - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - 0, // .. - -1, // SendMessage - -1, // SendBroadcast - -1, // SendForward - -1, // CancelForward - -1, // GetMachineName - -1, // SendMultiStart - -1, // SendMultiEnd - -1 // SendMultiText - }; - - /** - * Return the required SMB dialect string. - * - * @param i SMB dialect string index. - * @return SMB dialect string. - */ - - public static String DialectString(int i) - { - - // Validate the dialect index - - if (i >= protList.length) - return null; - return protList[i]; - } - - /** - * Determine if the SMB dialect supports the SMB command - * - * @return boolean - * @param dialect int SMB dialect type. - * @param cmd int SMB command code. - */ - public final static boolean DialectSupportsCommand(int dialect, int cmd) - { - // Range check the command - - if (cmd > cmdtable.length) - return false; - - // Check if the SMB dialect supports the SMB command. - - if (cmdtable[cmd] <= dialect) - return true; - return false; - } - - /** - * Return the SMB dialect type for the specified SMB dialect string index. - * - * @param i SMB dialect type. - * @return SMB dialect string index. - */ - - public static int DialectType(int i) - { - return protIdx[i]; - } - - /** - * Return the SMB dialect type for the specified string. - * - * @return int - * @param diastr java.lang.String - */ - public static int DialectType(String diastr) - { - - // Search the protocol string list - - int i = 0; - - while (i < protList.length && protList[i].compareTo(diastr) != 0) - i++; - - // Return the protocol id - - if (i < protList.length) - return DialectType(i); - else - return Unknown; - } - - /** - * Return the dialect type as a string. - * - * @param dia SMB dialect type. - * @return SMB dialect type string. - */ - - public static String DialectTypeString(int dia) - { - return protType[dia]; - } - - /** - * Return the number of available SMB dialect strings. - * - * @return Number of available SMB dialect strings. - */ - - public static int NumberOfDialects() - { - return protList.length; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/DialectSelector.java b/source/java/org/alfresco/filesys/smb/DialectSelector.java deleted file mode 100644 index 3efa310d99..0000000000 --- a/source/java/org/alfresco/filesys/smb/DialectSelector.java +++ /dev/null @@ -1,190 +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.smb; - -import java.util.BitSet; - -/** - * SMB dialect selector class. - */ -public class DialectSelector -{ - - // Bit set of selected SMB dialects. - - private BitSet dialects; - - /** - * Construct a new SMB dialect selector with the SMB core protocol selected. - */ - - public DialectSelector() - { - dialects = new BitSet(Dialect.Max); - - // Select only the core protocol by default - - ClearAll(); - AddDialect(Dialect.Core); - } - - /** - * Add a dialect to the list of available SMB dialects. - * - * @param idx Index of the dialect to add to the available dialects. - * @exception java.lang.ArrayIndexOutOfBoundsException Invalid dialect index. - */ - - public void AddDialect(int d) throws java.lang.ArrayIndexOutOfBoundsException - { - dialects.set(d); - } - - /** - * Clear all the dialect bits. - */ - - public void ClearAll() - { - for (int i = 0; i < dialects.size(); dialects.clear(i++)) - ; - } - - /** - * Copy the SMB dialect selector settings. - * - * @param dsel DialectSelector - */ - public void copyFrom(DialectSelector dsel) - { - - // Clear all current settings - - ClearAll(); - - // Copy the settings - - for (int i = 0; i < Dialect.Max; i++) - { - - // Check if the dialect is enabled - - if (dsel.hasDialect(i)) - AddDialect(i); - } - } - - /** - * Determine if the specified SMB dialect is selected/available. - * - * @param idx Index of the dialect to test for. - * @return true if the SMB dialect is available, else false. - * @exception java.lang.ArrayIndexOutOfBoundsException Invalid dialect index. - */ - - public boolean hasDialect(int d) throws java.lang.ArrayIndexOutOfBoundsException - { - return dialects.get(d); - } - - /** - * Determine if the core SMB dialect is enabled - * - * @return boolean - */ - public boolean hasCore() - { - if (hasDialect(Dialect.Core) || hasDialect(Dialect.CorePlus)) - return true; - return false; - } - - /** - * Determine if the LanMan SMB dialect is enabled - * - * @return boolean - */ - public boolean hasLanMan() - { - if (hasDialect(Dialect.DOSLanMan1) || hasDialect(Dialect.DOSLanMan2) || hasDialect(Dialect.LanMan1) - || hasDialect(Dialect.LanMan2) || hasDialect(Dialect.LanMan2_1)) - return true; - return false; - } - - /** - * Determine if the NT SMB dialect is enabled - * - * @return boolean - */ - public boolean hasNT() - { - if (hasDialect(Dialect.NT)) - return true; - return false; - } - - /** - * Remove an SMB dialect from the list of available dialects. - * - * @param idx Index of the dialect to remove. - * @exception java.lang.ArrayIndexOutOfBoundsException Invalid dialect index. - */ - - public void RemoveDialect(int d) throws java.lang.ArrayIndexOutOfBoundsException - { - dialects.clear(d); - } - - /** - * Return the dialect selector list as a string. - * - * @return java.lang.String - */ - public String toString() - { - - // Create a string buffer to build the return string - - StringBuffer str = new StringBuffer(); - str.append("["); - - for (int i = 0; i < dialects.size(); i++) - { - if (hasDialect(i)) - { - str.append(Dialect.DialectTypeString(i)); - str.append(","); - } - } - - // Trim the last comma and return the string - - if (str.length() > 1) - str.setLength(str.length() - 1); - str.append("]"); - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/DirectoryWatcher.java b/source/java/org/alfresco/filesys/smb/DirectoryWatcher.java deleted file mode 100644 index b77b9f8421..0000000000 --- a/source/java/org/alfresco/filesys/smb/DirectoryWatcher.java +++ /dev/null @@ -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.smb; - -/** - * Directory Watcher Interface - */ -public interface DirectoryWatcher -{ - - // Notification event types - - public final static int FileActionUnknown = -1; - public final static int FileNoAction = 0; - public final static int FileAdded = 1; - public final static int FileRemoved = 2; - public final static int FileModified = 3; - public final static int FileRenamedOld = 4; - public final static int FileRenamedNew = 5; - - /** - * Directory change occurred - * - * @param typ int - * @param fname String - */ - public void directoryChanged(int typ, String fname); -} diff --git a/source/java/org/alfresco/filesys/smb/FileInfoLevel.java b/source/java/org/alfresco/filesys/smb/FileInfoLevel.java deleted file mode 100644 index f4062ada06..0000000000 --- a/source/java/org/alfresco/filesys/smb/FileInfoLevel.java +++ /dev/null @@ -1,97 +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.smb; - -/** - * File Information Levels class. This class contains the file information levels that may be - * requested in the various Transact2 requests. - */ -public class FileInfoLevel -{ - - // Find first/next information levels - - public static final int FindStandard = 0x0001; - public static final int FindQueryEASize = 0x0002; - public static final int FindQueryEAsList = 0x0003; - public static final int FindFileDirectory = 0x0101; - public static final int FindFileFullDirectory = 0x0102; - public static final int FindFileNames = 0x0103; - public static final int FindFileBothDirectory = 0x0104; - - // File information levels - - public static final int SetStandard = 0x0001; - public static final int SetQueryEASize = 0x0002; - public static final int SetBasicInfo = 0x0101; - public static final int SetDispositionInfo = 0x0102; - public static final int SetAllocationInfo = 0x0103; - public static final int SetEndOfFileInfo = 0x0104; - - // Query path information levels - - public static final int PathStandard = 0x0001; - public static final int PathQueryEASize = 0x0002; - public static final int PathQueryEAsFromList = 0x0003; - public static final int PathAllEAs = 0x0004; - public static final int PathIsNameValid = 0x0006; - public static final int PathFileBasicInfo = 0x0101; - public static final int PathFileStandardInfo = 0x0102; - public static final int PathFileEAInfo = 0x0103; - public static final int PathFileNameInfo = 0x0104; - public static final int PathFileAllInfo = 0x0107; - public static final int PathFileAltNameInfo = 0x0108; - public static final int PathFileStreamInfo = 0x0109; - public static final int PathFileCompressionInfo = 0x010B; - - // Filesystem query information levels - - public static final int FSInfoAllocation = 0x0001; - public static final int FSInfoVolume = 0x0002; - public static final int FSInfoQueryVolume = 0x0102; - public static final int FSInfoQuerySize = 0x0103; - public static final int FSInfoQueryDevice = 0x0104; - public static final int FSInfoQueryAttribute = 0x0105; - - // NT pasthru levels - - public static final int NTFileBasicInfo = 1004; - public static final int NTFileStandardInfo = 1005; - public static final int NTFileInternalInfo = 1006; - public static final int NTFileEAInfo = 1007; - public static final int NTFileAccessInfo = 1008; - public static final int NTFileNameInfo = 1009; - public static final int NTFileRenameInfo = 1010; - public static final int NTFileDispositionInfo = 1013; - public static final int NTFilePositionInfo = 1014; - public static final int NTFileModeInfo = 1016; - public static final int NTFileAlignmentInfo = 1017; - public static final int NTFileAllInfo = 1018; - public static final int NTFileAltNameInfo = 1021; - public static final int NTFileStreamInfo = 1022; - public static final int NTFileCompressionInfo = 1028; - public static final int NTNetworkOpenInfo = 1034; - public static final int NTAttributeTagInfo = 1035; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/FindFirstNext.java b/source/java/org/alfresco/filesys/smb/FindFirstNext.java deleted file mode 100644 index 0ad49bcbf4..0000000000 --- a/source/java/org/alfresco/filesys/smb/FindFirstNext.java +++ /dev/null @@ -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.smb; - -/** - * Find First/Next Flags - */ -public class FindFirstNext -{ - // Find first/find next flags - - public static final int CloseSearch = 0x01; - public static final int CloseAtEnd = 0x02; - public static final int ReturnResumeKey = 0x04; - public static final int ResumePrevious = 0x08; - public static final int BackupIntent = 0x10; -} diff --git a/source/java/org/alfresco/filesys/smb/InvalidUNCPathException.java b/source/java/org/alfresco/filesys/smb/InvalidUNCPathException.java deleted file mode 100644 index fe7646c6bf..0000000000 --- a/source/java/org/alfresco/filesys/smb/InvalidUNCPathException.java +++ /dev/null @@ -1,54 +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.smb; - -/** - * Invalid UNC path exception class - *

- * The InvalidUNCPathException indicates that a UNC path has an invalid format. - * - * @see PCShare - */ -public class InvalidUNCPathException extends Exception -{ - private static final long serialVersionUID = 3257567304241066297L; - - /** - * Default invalid UNC path exception constructor. - */ - - public InvalidUNCPathException() - { - } - - /** - * Invalid UNC path exception constructor, with additional details string. - */ - - public InvalidUNCPathException(String msg) - { - super(msg); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/LockingAndX.java b/source/java/org/alfresco/filesys/smb/LockingAndX.java deleted file mode 100644 index bc3132df7d..0000000000 --- a/source/java/org/alfresco/filesys/smb/LockingAndX.java +++ /dev/null @@ -1,106 +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.smb; - -/** - * LockingAndX SMB Constants Class - */ -public class LockingAndX -{ - - // Lock type flags - - public static final int SharedLock = 0x0001; - public static final int OplockBreak = 0x0002; - public static final int ChangeType = 0x0004; - public static final int Cancel = 0x0008; - public static final int LargeFiles = 0x0010; - - /** - * Check if this is a normal lock/unlock, ie. no flags except the LargeFiles flag may be set - * - * @param flags - * @return boolean - */ - public final static boolean isNormalLockUnlock(int flags) - { - return (flags & 0x000F) == 0 ? true : false; - } - - /** - * Check if the large files flag is set - * - * @param flags int - * @return boolean - */ - public final static boolean hasLargeFiles(int flags) - { - return (flags & LargeFiles) != 0 ? true : false; - } - - /** - * Check if the shared lock flag is set - * - * @param flags int - * @return boolean - */ - public final static boolean hasSharedLock(int flags) - { - return (flags & SharedLock) != 0 ? true : false; - } - - /** - * Check if the oplock break flag is set - * - * @param flags int - * @return boolean - */ - public final static boolean hasOplockBreak(int flags) - { - return (flags & OplockBreak) != 0 ? true : false; - } - - /** - * Check if the change type flag is set - * - * @param flags int - * @return boolean - */ - public final static boolean hasChangeType(int flags) - { - return (flags & ChangeType) != 0 ? true : false; - } - - /** - * Check if the cancel flag is set - * - * @param flags int - * @return boolean - */ - public final static boolean hasCancel(int flags) - { - return (flags & Cancel) != 0 ? true : false; - } -} diff --git a/source/java/org/alfresco/filesys/smb/NTIOCtl.java b/source/java/org/alfresco/filesys/smb/NTIOCtl.java deleted file mode 100644 index d45c343623..0000000000 --- a/source/java/org/alfresco/filesys/smb/NTIOCtl.java +++ /dev/null @@ -1,250 +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.smb; - -/** - * NT IO Control Codes Class - */ -public class NTIOCtl -{ - - // Device type codes - - public static final int DeviceBeep = 0x0001; - public static final int DeviceCDRom = 0x0002; - public static final int DeviceCDRomFileSystem = 0x0003; - public static final int DeviceController = 0x0004; - public static final int DeviceDataLink = 0x0005; - public static final int DeviceDFS = 0x0006; - public static final int DeviceDisk = 0x0007; - public static final int DeviceDiskFileSystem = 0x0008; - public static final int DeviceFileSystem = 0x0009; - public static final int DeviceInportPort = 0x000A; - public static final int DeviceKeyboard = 0x000B; - public static final int DeviceMailSlot = 0x000C; - public static final int DeviceMidiIn = 0x000D; - public static final int DeviceMidiOut = 0x000E; - public static final int DeviceMouse = 0x000F; - public static final int DeviceMultiUNCProvider = 0x0010; - public static final int DeviceNamedPipe = 0x0011; - public static final int DeviceNetwork = 0x0012; - public static final int DeviceNetworkBrowser = 0x0013; - public static final int DeviceNetworkFileSystem = 0x0014; - public static final int DeviceNull = 0x0015; - public static final int DeviceParallelPort = 0x0016; - public static final int DevicePhysicalNetCard = 0x0017; - public static final int DevicePrinter = 0x0018; - public static final int DeviceScanner = 0x0019; - public static final int DeviceSerialMousePort = 0x001A; - public static final int DeviceSerialPort = 0x001B; - public static final int DeviceScreen = 0x001C; - public static final int DeviceSound = 0x001D; - public static final int DeviceStreams = 0x001E; - public static final int DeviceTape = 0x001F; - public static final int DeviceTapeFileSystem = 0x0020; - public static final int DeviceTransport = 0x0021; - public static final int DeviceUnknown = 0x0022; - public static final int DeviceVideo = 0x0023; - public static final int DeviceVirtualDisk = 0x0024; - public static final int DeviceWaveIn = 0x0025; - public static final int DeviceWaveOut = 0x0026; - public static final int Device8042Port = 0x0027; - public static final int DeviceNetworkRedirector = 0x0028; - public static final int DeviceBattery = 0x0029; - public static final int DeviceBusExtender = 0x002A; - public static final int DeviceModem = 0x002B; - public static final int DeviceVDM = 0x002C; - public static final int DeviceMassStorage = 0x002D; - public static final int DeviceSMB = 0x002E; - public static final int DeviceKS = 0x002F; - public static final int DeviceChanger = 0x0030; - public static final int DeviceSmartCard = 0x0031; - public static final int DeviceACPI = 0x0032; - public static final int DeviceDVD = 0x0033; - public static final int DeviceFullScreenVideo = 0x0034; - public static final int DeviceDFSFileSystem = 0x0035; - public static final int DeviceDFSVolume = 0x0036; - - // Method types for I/O and filesystem controls - - public static final int MethodBuffered = 0; - public static final int MethodInDirect = 1; - public static final int MethodOutDirect = 2; - public static final int MethodNeither = 3; - - // Access check types - - public static final int AccessAny = 0; - public static final int AccessRead = 0x0001; - public static final int AccessWrite = 0x0002; - - // Filesystem function codes - - public static final int FsCtlRequestOplockLevel1 = 0; - public static final int FsCtlRequestOplockLevel2 = 1; - public static final int FsCtlRequestBatchOplock = 2; - public static final int FsCtlOplockBreakAck = 3; - public static final int FsCtlOpBatchAckClosePend = 4; - public static final int FsCtlOplockBreakNotify = 5; - public static final int FsCtlLockVolume = 6; - public static final int FsCtlUnlockVolume = 7; - public static final int FsCtlDismountVolume = 8; - public static final int FsCtlIsVolumeMounted = 10; - public static final int FsCtlIsPathnameValid = 11; - public static final int FsCtlMarkVolumeDirty = 12; - public static final int FsCtlQueryRetrievalPtrs = 14; - public static final int FsCtlGetCompression = 15; - public static final int FsCtlSetCompression = 16; - public static final int FsCtlMarkAsSystemHive = 19; - public static final int FsCtlOplockBreakAck2 = 20; - public static final int FsCtlInvalidateVolumes = 21; - public static final int FsCtlQueryFatBPB = 22; - public static final int FsCtlRequestFilterOplock = 23; - public static final int FsCtlFileSysGetStats = 24; - public static final int FsCtlGetNTFSVolumeData = 25; - public static final int FsCtlGetNTFSFileRecord = 26; - public static final int FsCtlGetVolumeBitmap = 27; - public static final int FsCtlGetRetrievalPtrs = 28; - public static final int FsCtlMoveFile = 29; - public static final int FsCtlIsVolumeDirty = 30; - public static final int FsCtlGetHFSInfo = 31; - public static final int FsCtlAllowExtenDasdIO = 32; - public static final int FsCtlReadPropertyData = 33; - public static final int FsCtlWritePropertyData = 34; - public static final int FsCtlFindFilesBySID = 35; - public static final int FsCtlDumpPropertyData = 37; - public static final int FsCtlSetObjectId = 38; - public static final int FsCtlGetObjectId = 39; - public static final int FsCtlDeleteObjectId = 40; - public static final int FsCtlSetReparsePoint = 41; - public static final int FsCtlGetReparsePoint = 42; - public static final int FsCtlDeleteReparsePoint = 43; - public static final int FsCtlEnumUsnData = 44; - public static final int FsCtlSecurityIdCheck = 45; - public static final int FsCtlReadUsnJournal = 46; - public static final int FsCtlSetObjectIdExtended = 47; - public static final int FsCtlCreateOrGetObjectId = 48; - public static final int FsCtlSetSparse = 49; - public static final int FsCtlSetZeroData = 50; - public static final int FsCtlQueryAllocRanges = 51; - public static final int FsCtlEnableUpgrade = 52; - public static final int FsCtlSetEncryption = 53; - public static final int FsCtlEncryptionFsCtlIO = 54; - public static final int FsCtlWriteRawEncrypted = 55; - public static final int FsCtlReadRawEncrypted = 56; - public static final int FsCtlCreateUsnJournal = 57; - public static final int FsCtlReadFileUsnData = 58; - public static final int FsCtlWriteUsnCloseRecord = 59; - public static final int FsCtlExtendVolume = 60; - - // Base value for custom control codes - - public static final int FsCtlCustom = 0x800; - - /** - * Extract the device type from an I/O control code - * - * @param ioctl int - * @return int - */ - public final static int getDeviceType(int ioctl) - { - return (ioctl >> 16) & 0x0000FFFF; - } - - /** - * Extract the access type from an I/O control code - * - * @param ioctl int - * @return int - */ - public final static int getAccessType(int ioctl) - { - return (ioctl >> 14) & 0x00000003; - } - - /** - * Extract the function code from the I/O control code - * - * @param ioctl int - * @return int - */ - public final static int getFunctionCode(int ioctl) - { - return (ioctl >> 2) & 0x00000FFF; - } - - /** - * Extract the method code from the I/O control code - * - * @param ioctl int - * @return int - */ - public final static int getMethod(int ioctl) - { - return ioctl & 0x00000003; - } - - /** - * Make a control code - * - * @param devType int - * @param func int - * @param method int - * @param access int - * @return int - */ - public final static int makeControlCode(int devType, int func, int method, int access) - { - return (devType << 16) + (access << 14) + (func << 2) + (method); - } - - /** - * Return an I/O control code as a string - * - * @param ioctl int - * @return String - */ - public final static String asString(int ioctl) - { - StringBuffer str = new StringBuffer(); - - str.append("[Func:"); - str.append(getFunctionCode(ioctl)); - - str.append(",DevType:"); - str.append(getDeviceType(ioctl)); - - str.append(",Access:"); - str.append(getAccessType(ioctl)); - - str.append(",Method:"); - str.append(getMethod(ioctl)); - - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/NTTime.java b/source/java/org/alfresco/filesys/smb/NTTime.java deleted file mode 100644 index 1f46b14157..0000000000 --- a/source/java/org/alfresco/filesys/smb/NTTime.java +++ /dev/null @@ -1,106 +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.smb; - -import java.util.Date; - -/** - * NT 64bit Time Conversion Class - *

- * Convert an NT 64bit time value to a Java Date value and vice versa. - */ -public class NTTime -{ - // NT time value indicating infinite time - - public static final long InfiniteTime = 0x7FFFFFFFFFFFFFFFL; - - // Time conversion constant, difference between NT 64bit base date of 1-1-1601 00:00:00 and - // Java base date of 1-1-1970 00:00:00. In 100ns units. - - private static final long TIME_CONVERSION = 116444736000000000L; - - /** - * Convert a Java Date value to an NT 64bit time - * - * @param jdate Date - * @return long - */ - public final static long toNTTime(Date jdate) - { - - // Add the conversion constant to the Java date raw value, convert the Java milliseconds to - // 100ns units - - long ntDate = (jdate.getTime() * 10000L) + TIME_CONVERSION; - return ntDate; - } - - /** - * Convert a Java Date value to an NT 64bit time - * - * @param jdate long - * @return long - */ - public final static long toNTTime(long jdate) - { - - // Add the conversion constant to the Java date raw value, convert the Java milliseconds to - // 100ns units - - long ntDate = (jdate * 10000L) + TIME_CONVERSION; - return ntDate; - } - - /** - * Convert an NT 64bit time value to a Java date value - * - * @param ntDate long - * @return SMBDate - */ - public final static SMBDate toSMBDate(long ntDate) - { - - // Convert the NT 64bit 100ns time value to a Java milliseconds value - - long jDate = (ntDate - TIME_CONVERSION) / 10000L; - return new SMBDate(jDate); - } - - /** - * Convert an NT 64bit time value to a Java date value - * - * @param ntDate long - * @return long - */ - public final static long toJavaDate(long ntDate) - { - - // Convert the NT 64bit 100ns time value to a Java milliseconds value - - long jDate = (ntDate - TIME_CONVERSION) / 10000L; - return jDate; - } -} diff --git a/source/java/org/alfresco/filesys/smb/NetworkSession.java b/source/java/org/alfresco/filesys/smb/NetworkSession.java deleted file mode 100644 index 5d16354c61..0000000000 --- a/source/java/org/alfresco/filesys/smb/NetworkSession.java +++ /dev/null @@ -1,97 +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.smb; - -import java.io.IOException; -import java.net.UnknownHostException; - -/** - * Network Session Interface - *

- * Base class for client network sessions. - */ -public interface NetworkSession -{ - - /** - * Return the protocol name - * - * @return String - */ - public String getProtocolName(); - - /** - * Open a connection to a remote host - * - * @param toName Host name/address being called - * @param fromName Local host name/address - * @param toAddr Optional address of the remote host - * @exception IOException - * @exception UnknownHostException - */ - public void Open(String toName, String fromName, String toAddr) throws IOException, UnknownHostException; - - /** - * Determine if the session is connected to a remote host - * - * @return boolean - */ - public boolean isConnected(); - - /** - * Check if the network session has data available - * - * @return boolean - * @exception IOException - */ - public boolean hasData() throws IOException; - - /** - * Receive a data packet from the remote host. - * - * @param buf Byte buffer to receive the data into. - * @param tmo Receive timeout in milliseconds, or zero for no timeout - * @return Length of the received data. - * @exception java.io.IOException I/O error occurred. - */ - public int Receive(byte[] buf, int tmo) throws IOException; - - /** - * Send a data packet to the remote host. - * - * @param data Byte array containing the data to be sent. - * @param siz Length of the data to send. - * @return true if the data was sent successfully, else false. - * @exception java.io.IOException I/O error occurred. - */ - public boolean Send(byte[] data, int siz) throws IOException; - - /** - * Close the network session - * - * @exception java.io.IOException I/O error occurred - */ - public void Close() throws IOException; -} diff --git a/source/java/org/alfresco/filesys/smb/PCShare.java b/source/java/org/alfresco/filesys/smb/PCShare.java deleted file mode 100644 index 92f0d24e0e..0000000000 --- a/source/java/org/alfresco/filesys/smb/PCShare.java +++ /dev/null @@ -1,590 +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.smb; - -/** - * PC share class. - *

- * The PC share class holds the details of a network share, including the required username and - * password access control. - */ -public final class PCShare -{ - - // Domain name - - private String m_domain = null; - - // Node name string. - - private String m_nodename = null; - - // Remote share name string. - - private String m_shrname = null; - - // User name access control string. - - private String m_username = null; - - // Password access control string. - - private String m_password = null; - - // Remote path, relative to the share. - - private String m_path = null; - - // File name string. - - private String m_fname = null; - - // Primary and secondary protocols to try connection on - - private int m_primaryProto = Protocol.UseDefault; - private int m_secondaryProto = Protocol.UseDefault; - - // Extended security negotiation flags - - private int m_extendedSecFlags; - - /** - * Construct an empty PCShare object. - */ - public PCShare() - { - } - - /** - * Construct a PCShare using the supplied UNC path. - * - * @param netpath Network path of the remote server, in UNC format ie. \\node\\share. - * @exception InvalidUNCPathException If the network path is invalid. - */ - public PCShare(String netpath) throws InvalidUNCPathException - { - setNetworkPath(netpath); - - // If the user name has not been set, use the guest account - - if (m_username == null) - setUserName("GUEST"); - } - - /** - * Construct a PCShare using the specified remote server and access control details. - * - * @param nname Node name of the remote server. - * @param shr Share name on the remote server. - * @param uname User name used to access the remote share. - * @param pwd Password used to access the remote share. - */ - public PCShare(String nname, String shr, String uname, String pwd) - { - setNodeName(nname); - setShareName(shr); - setUserName(uname); - setPassword(pwd); - } - - /** - * Build a share relative path using the supplied working directory and file name. - * - * @param workdir Working directory string, relative to the root of the share. - * @param fname File name string. - * @return Share relative path string. - */ - public static String makePath(String workdir, String fname) - { - - // Create a string buffer to build the share relative path - - StringBuffer pathStr = new StringBuffer(); - - // Make sure there is a leading '\' on the path string - - if (!workdir.startsWith("\\")) - pathStr.append("\\"); - pathStr.append(workdir); - - // Make sure the path ends with '\' - - if (pathStr.charAt(pathStr.length() - 1) != '\\') - pathStr.append("\\"); - - // Add the file name to the path string - - pathStr.append(fname); - - // Return share relative the path string - - return pathStr.toString(); - } - - /** - * Return the domain for the share. - * - * @return java.lang.String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Determine if extended security flags have been set - * - * @return boolean - */ - public final boolean hasExtendedSecurityFlags() - { - return m_extendedSecFlags != 0 ? true : false; - } - - /** - * Return the extended security flags - * - * @return int - */ - public final int getExtendedSecurityFlags() - { - return m_extendedSecFlags; - } - - /** - * Get the remote file name string. - * - * @return Remote file name string. - */ - public final String getFileName() - { - return m_fname; - } - - /** - * Return the full UNC path for this PC share object. - * - * @return Path string of the remote share/path/file in UNC format, ie. \\node\share\path\file. - */ - public final String getNetworkPath() - { - - // Create a string buffer to build up the full network path - - StringBuffer strBuf = new StringBuffer(128); - - // Add the node name and share name - - strBuf.append("\\\\"); - strBuf.append(getNodeName()); - strBuf.append("\\"); - strBuf.append(getShareName()); - - // Add the path, if there is one - - if (getPath() != null && getPath().length() > 0) - { - if (getPath().charAt(0) != '\\') - { - strBuf.append("\\"); - } - strBuf.append(getPath()); - } - - // Add the file name if there is one - - if (getFileName() != null && getFileName().length() > 0) - { - if (strBuf.charAt(strBuf.length() - 1) != '\\') - { - strBuf.append("\\"); - } - strBuf.append(getFileName()); - } - - // Return the network path - - return strBuf.toString(); - } - - /** - * Get the remote node name string. - * - * @return Node name string. - */ - public final String getNodeName() - { - return m_nodename; - } - - /** - * Get the remote password required to access the remote share. - * - * @return Remote password string. - */ - public final String getPassword() - { - return m_password; - } - - /** - * Get the share relative path string. - * - * @return Share relative path string. - */ - public final String getPath() - { - return m_path != null ? m_path : "\\"; - } - - /** - * Return the share relative path for this PC share object. - * - * @return Path string of the remote share/path/file relative to the share, ie. \path\file. - */ - public final String getRelativePath() - { - - // Create a string buffer to build up the full network path - - StringBuffer strBuf = new StringBuffer(128); - - // Add the path, if there is one - - if (getPath().length() > 0) - { - if (getPath().charAt(0) != '\\') - { - strBuf.append("\\"); - } - strBuf.append(getPath()); - } - - // Add the file name if there is one - - if (getFileName().length() > 0) - { - if (strBuf.charAt(strBuf.length() - 1) != '\\') - { - strBuf.append("\\"); - } - strBuf.append(getFileName()); - } - - // Return the network path - - return strBuf.toString(); - } - - /** - * Get the remote share name string. - * - * @return Remote share name string. - */ - - public final String getShareName() - { - return m_shrname; - } - - /** - * Get the remote user name string. - * - * @return Remote user name string required to access the remote share. - */ - - public final String getUserName() - { - return m_username != null ? m_username : ""; - } - - /** - * Get the primary protocol to connect with - * - * @return int - */ - public final int getPrimaryProtocol() - { - return m_primaryProto; - } - - /** - * Get the secondary protocol to connect with - * - * @return int - */ - public final int getSecondaryProtocol() - { - return m_secondaryProto; - } - - /** - * Determine if the share has a domain specified. - * - * @return boolean - */ - public final boolean hasDomain() - { - return m_domain == null ? false : true; - } - - /** - * Set the domain to be used during the session setup. - * - * @param domain java.lang.String - */ - public final void setDomain(String domain) - { - m_domain = domain; - if (m_domain != null) - m_domain = m_domain.toUpperCase(); - } - - /** - * Set the remote file name string. - * - * @param fn Remote file name string. - */ - - public final void setFileName(String fn) - { - m_fname = fn; - } - - /** - * Set the PC share from the supplied UNC path string. - * - * @param netpath UNC format remote file path. - */ - - public final void setNetworkPath(String netpath) throws InvalidUNCPathException - { - - // Take a copy of the network path - - StringBuffer path = new StringBuffer(netpath); - for (int i = 0; i < path.length(); i++) - { - - // Convert forward slashes to back slashes - - if (path.charAt(i) == '/') - path.setCharAt(i, '\\'); - } - String npath = path.toString(); - - // UNC path starts with '\\' - - if (!npath.startsWith("\\\\") || npath.length() < 5) - throw new InvalidUNCPathException(npath); - - // Extract the node name from the network path - - int pos = 2; - int endpos = npath.indexOf("\\", pos); - - if (endpos == -1) - throw new InvalidUNCPathException(npath); - - setNodeName(npath.substring(pos, endpos)); - pos = endpos + 1; - - // Extract the share name from the network path - - endpos = npath.indexOf("\\", pos); - - if (endpos == -1) - { - - // Share name is the last part of the UNC path - - setShareName(npath.substring(pos)); - - // Set the root path and clear the file name - - setPath("\\"); - setFileName(""); - } - else - { - setShareName(npath.substring(pos, endpos)); - - pos = endpos + 1; - - // Extract the share relative path from the network path - - endpos = npath.lastIndexOf("\\"); - - if (endpos != -1 && endpos > pos) - { - - // Set the share relative path, and update the current position index - - setPath(npath.substring(pos, endpos)); - - // File name is the rest of the UNC path - - setFileName(npath.substring(endpos + 1)); - } - else - { - - // Set the share relative path to the root path - - setPath("\\"); - - // Set the file name string - - if (npath.length() > pos) - setFileName(npath.substring(pos)); - else - setFileName(""); - } - } - - // Check if the share name contains embedded access control - - pos = m_shrname.indexOf("%"); - if (pos != -1) - { - - // Find the end of the user name - - endpos = m_shrname.indexOf(":", pos); - if (endpos != -1) - { - - // Extract the user name and password strings - - setUserName(m_shrname.substring(pos + 1, endpos)); - setPassword(m_shrname.substring(endpos + 1)); - } - else - { - - // Extract the user name string - - setUserName(m_shrname.substring(pos + 1)); - } - - // Reset the share name string, to remove the access control - - setShareName(m_shrname.substring(0, pos)); - } - - // Check if the path has been set, if not then use the root path - - if (m_path == null || m_path.length() == 0) - m_path = "\\"; - } - - /** - * Set the extended security negotiation flags - * - * @param extFlags int - */ - public final void setExtendedSecurityFlags(int extFlags) - { - m_extendedSecFlags = extFlags; - } - - /** - * Set the remote node name string. - * - * @param nname Remote node name string. - */ - - public final void setNodeName(String nname) - { - m_nodename = nname; - } - - /** - * Set the remote password string. - * - * @param pwd Remote password string, required to access the remote share. - */ - - public final void setPassword(String pwd) - { - m_password = pwd; - } - - /** - * Set the share relative path string. - * - * @param pth Share relative path string. - */ - - public final void setPath(String pth) - { - m_path = pth; - } - - /** - * Set the remote share name string. - * - * @param shr Remote share name string. - */ - - public final void setShareName(String shr) - { - m_shrname = shr; - } - - /** - * Set the remote user name string. - * - * @param uname Remote user name string. - */ - - public final void setUserName(String uname) - { - m_username = uname; - } - - /** - * Set the primary and secondary protocol order that is used to connect to the remote host. - * - * @param pri int - * @param sec int - */ - public final void setProtocolOrder(int pri, int sec) - { - m_primaryProto = pri; - m_secondaryProto = sec; - } - - /** - * Return the PCShare object as a string - * - * @return PCShare string. - */ - - public final String toString() - { - return getNetworkPath(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/PacketType.java b/source/java/org/alfresco/filesys/smb/PacketType.java deleted file mode 100644 index eb2047950e..0000000000 --- a/source/java/org/alfresco/filesys/smb/PacketType.java +++ /dev/null @@ -1,418 +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.smb; - -/** - * SMB packet type class - */ -public class PacketType -{ - // SMB packet types - - public static final int CreateDirectory = 0x00; - public static final int DeleteDirectory = 0x01; - public static final int OpenFile = 0x02; - public static final int CreateFile = 0x03; - public static final int CloseFile = 0x04; - public static final int FlushFile = 0x05; - public static final int DeleteFile = 0x06; - public static final int RenameFile = 0x07; - public static final int GetFileAttributes = 0x08; - public static final int SetFileAttributes = 0x09; - public static final int ReadFile = 0x0A; - public static final int WriteFile = 0x0B; - public static final int LockFile = 0x0C; - public static final int UnLockFile = 0x0D; - public static final int CreateTemporary = 0x0E; - public static final int CreateNew = 0x0F; - public static final int CheckDirectory = 0x10; - - public static final int ProcessExit = 0x11; - public static final int SeekFile = 0x12; - public static final int LockAndRead = 0x13; - public static final int WriteAndUnlock = 0x14; - public static final int ReadRaw = 0x1A; - public static final int ReadMpx = 0x1B; - public static final int ReadMpxSecondary = 0x1C; - public static final int WriteRaw = 0x1D; - public static final int WriteMpx = 0x1E; - public static final int WriteComplete = 0x20; - public static final int SetInformation2 = 0x22; - public static final int QueryInformation2 = 0x23; - public static final int LockingAndX = 0x24; - public static final int Transaction = 0x25; - public static final int TransactionSecond = 0x26; - public static final int IOCtl = 0x27; - public static final int IOCtlSecondary = 0x28; - public static final int Copy = 0x29; - public static final int Move = 0x2A; - public static final int Echo = 0x2B; - public static final int WriteAndClose = 0x2C; - public static final int OpenAndX = 0x2D; - public static final int ReadAndX = 0x2E; - public static final int WriteAndX = 0x2F; - public static final int CloseAndTreeDisc = 0x31; - public static final int Transaction2 = 0x32; - public static final int Transaction2Second= 0x33; - public static final int FindClose2 = 0x34; - public static final int FindNotifyClose = 0x35; - - public static final int TreeConnect = 0x70; - public static final int TreeDisconnect = 0x71; - public static final int Negotiate = 0x72; - public static final int SessionSetupAndX = 0x73; - public static final int LogoffAndX = 0x74; - public static final int TreeConnectAndX = 0x75; - - public static final int DiskInformation = 0x80; - public static final int Search = 0x81; - public static final int Find = 0x82; - public static final int FindUnique = 0x83; - - public static final int NTTransact = 0xA0; - public static final int NTTransactSecond = 0xA1; - public static final int NTCreateAndX = 0xA2; - public static final int NTCancel = 0xA4; - - public static final int OpenPrintFile = 0xC0; - public static final int WritePrintFile = 0xC1; - public static final int ClosePrintFile = 0xC2; - public static final int GetPrintQueue = 0xC3; - - // Send message codes - - public static final int SendMessage = 0xD0; - public static final int SendBroadcast = 0xD1; - public static final int SendForward = 0xD2; - public static final int CancelForward = 0xD3; - public static final int GetMachineName = 0xD4; - public static final int SendMultiStart = 0xD5; - public static final int SendMultiEnd = 0xD6; - public static final int SendMultiText = 0xD7; - - // Transaction2 operation codes - - public static final int Trans2Open = 0x00; - public static final int Trans2FindFirst = 0x01; - public static final int Trans2FindNext = 0x02; - public static final int Trans2QueryFileSys= 0x03; - public static final int Trans2QueryPath = 0x05; - public static final int Trans2SetPath = 0x06; - public static final int Trans2QueryFile = 0x07; - public static final int Trans2SetFile = 0x08; - public static final int Trans2CreateDir = 0x0D; - public static final int Trans2SessSetup = 0x0E; - - // Remote admin protocol (RAP) codes - - public static final int RAPShareEnum = 0; - public static final int RAPShareGetInfo = 1; - public static final int RAPSessionEnum = 6; - public static final int RAPServerGetInfo = 13; - public static final int NetServerDiskEnum = 15; - public static final int NetGroupEnum = 47; - public static final int RAPUserGetInfo = 56; - public static final int RAPWkstaGetInfo = 63; - public static final int RAPServerEnum = 94; - public static final int RAPServerEnum2 = 104; - public static final int RAPWkstaUserLogon = 132; - public static final int RAPWkstaUserLogoff= 133; - public static final int RAPChangePassword = 214; - - // Service information/control codes - - public static final int NetServiceEnum = 39; - public static final int NetServiceInstall = 40; - public static final int NetServiceControl = 41; - - // User/group information codes - - public static final int NetGroupGetUsers = 52; - public static final int NetUserEnum = 53; - public static final int NetUserGetGroups = 59; - - // Printer/print queue admin codes - - public static final int NetPrintQEnum = 69; - public static final int NetPrintQGetInfo = 70; - public static final int NetPrintQSetInfo = 71; - public static final int NetPrintQAdd = 72; - public static final int NetPrintQDel = 73; - public static final int NetPrintQPause = 74; - public static final int NetPrintQContinue = 75; - public static final int NetPrintJobEnum = 76; - public static final int NetPrintJobGetInfo= 77; - public static final int NetPrintJobSetInfo= 78; - public static final int NetPrintJobDelete = 81; - public static final int NetPrintJobPause = 82; - public static final int NetPrintJobContinue = 83; - public static final int NetPrintDestEnum = 84; - public static final int NetPrintDestGetInfo = 85; - public static final int NetPrintDestControl = 86; - - // Transaction named pipe sub-commands - - public static final int CallNamedPipe = 0x54; - public static final int WaitNamedPipe = 0x53; - public static final int PeekNmPipe = 0x23; - public static final int QNmPHandState = 0x21; - public static final int SetNmPHandState = 0x01; - public static final int QNmPipeInfo = 0x22; - public static final int TransactNmPipe = 0x26; - public static final int RawReadNmPipe = 0x11; - public static final int RawWriteNmPipe = 0x31; - - // Miscellaneous codes - - public static final int NetBIOSEnum = 92; - - // NT transaction function codes - - public static final int NTTransCreate = 1; - public static final int NTTransIOCtl = 2; - public static final int NTTransSetSecurityDesc = 3; - public static final int NTTransNotifyChange = 4; - public static final int NTTransRename = 5; - public static final int NTTransQuerySecurityDesc = 6; - public static final int NTTransGetUserQuota = 7; - public static final int NTTransSetUserQuota = 8; - - // Flag to indicate no chained AndX command - - public static final int NoChainedCommand = 0xFF; - - // SMB command names (block 1) - - private static String[] _cmdNames1 = { "CreateDirectory", - "DeleteDirectory", - "OpenFile", - "CreateFile", - "CloseFile", - "FlushFile", - "DeleteFile", - "RenameFile", - "GetFileAttributes", - "SetFileAttributes", - "ReadFile", - "WriteFile", - "LockFile", - "UnLockFile", - "CreateTemporary", - "CreateNew", - "CheckDirectory", - "ProcessExit", - "SeekFile", - "LockAndRead", - "WriteAndUnlock", - null, - null, - null, - null, - null, - "ReadRaw", - "ReadMpx", - "ReadMpxSecondary", - "WriteRaw", - "WriteMpx", - null, - "WriteComplete", - null, - "SetInformation2", - "QueryInformation2", - "LockingAndX", - "Transaction", - "TransactionSecond", - "IOCtl", - "IOCtlSecondary", - "Copy", - "Move", - "Echo", - "WriteAndClose", - "OpenAndX", - "ReadAndX", - "WriteAndX", - null, - "CloseAndTreeDisconnect", - "Transaction2", - "Transaction2Secondary", - "FindClose2", - "FindNotifyClose" - }; - - private static String[] _cmdNames2 = { "TreeConnect", - "TreeDisconnect", - "Negotiate", - "SessionSetupAndX", - "LogoffAndX", - "TreeConnectAndX" - }; - - private static String[] _cmdNames3 = { "DiskInformation", - "Search", - "Find", - "FindUnique" - }; - - private static String[] _cmdNames4 = { "NTTransact", - "NTTransactSecondary", - "NTCreateAndX", - null, - "NTCancel" - }; - - private static String[] _cmdNames5 = { "OpenPrintFile", - "WritePrintFile", - "ClosePrintFile", - "GetPrintQueue" - }; - - private static String[] _cmdNames6 = { "SendMessage", - "SendBroadcast", - "SendForward", - "CancelForward", - "GetMachineName", - "SendMultiStart", - "SendMultiEnd", - "SendMultiText" - }; - - // Transaction2 operation code names - - private static String[] _transNames = { "Trans2Open", - "Trans2FindFirst", - "Trans2FindNext", - "Trans2QueryFileSys", - "Trans2QueryPath", - "Trans2SetPath", - "Trans2QueryFile", - "Trans2SetFile", - "Trans2CreateDirectory", - "Trans2SessionSetup" - }; - - // NT transaction operation code names - - private static String[] _ntTranNames = { "", // zero not used - "NTTransCreate", - "NTTransIOCtl", - "NTTransSetSecurityDesc", - "NTTransNotifyChange", - "NTTransRename", - "NTTransQuerySecurityDesc", - "NTTransGetUserQuota", - "NTTransSetUserQuota" - }; - - /** - * Return an SMB command as a string - * - * @param cmd int - * @return String - */ - public static final String getCommandName(int cmd) - { - - // Get the command name - - String cmdName = ""; - - if (cmd >= 0 && cmd < _cmdNames1.length) - { - - // Get the command name from the main name table - - cmdName = _cmdNames1[cmd]; - } - else - { - - // Mask the command to determine the command table to index - - int cmdTop = cmd & 0x00F0; - - switch (cmd & 0x00F0) - { - case 0x70: - cmdName = _cmdNames2[cmd - 0x70]; - break; - case 0x80: - cmdName = _cmdNames3[cmd - 0x80]; - break; - case 0xA0: - cmdName = _cmdNames4[cmd - 0xA0]; - break; - case 0xC0: - cmdName = _cmdNames5[cmd - 0xC0]; - break; - case 0xD0: - cmdName = _cmdNames6[cmd - 0xD0]; - break; - default: - cmdName = "0x" + Integer.toHexString(cmd); - break; - } - } - - // Return the command name string - - return cmdName; - } - - /** - * Return a transaction code as a string - * - * @param opcode int - * @return String - */ - public final static String getTransactionName(int opcode) - { - - // Range check the opcode - - String opcodeName = ""; - - if (opcode >= 0 && opcode < _transNames.length) - opcodeName = _transNames[opcode]; - return opcodeName; - } - - /** - * Return an NT transation code as a string - * - * @param opcode int - * @return String - */ - public final static String getNTTransationName(int opcode) - { - - // Range check the opcode - - String opcodeName = ""; - - if (opcode >= 0 && opcode < _ntTranNames.length) - opcodeName = _ntTranNames[opcode]; - return opcodeName; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/Protocol.java b/source/java/org/alfresco/filesys/smb/Protocol.java deleted file mode 100644 index 1a09974aec..0000000000 --- a/source/java/org/alfresco/filesys/smb/Protocol.java +++ /dev/null @@ -1,61 +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.smb; - -/** - * Protocol Class - *

- * Declares constants for the available SMB protocols (TCP/IP NetBIOS and native TCP/IP SMB) - */ -public class Protocol -{ - - // Available protocol types - - public final static int TCPNetBIOS = 1; - public final static int NativeSMB = 2; - - // Protocol control constants - - public final static int UseDefault = 0; - public final static int None = -1; - - /** - * Return the protocol type as a string - * - * @param typ int - * @return String - */ - public static final String asString(int typ) - { - String ret = ""; - if (typ == TCPNetBIOS) - ret = "TCP/IP NetBIOS"; - else if (typ == NativeSMB) - ret = "Native SMB (port 445)"; - - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/smb/SMBDate.java b/source/java/org/alfresco/filesys/smb/SMBDate.java deleted file mode 100644 index 53c3367d35..0000000000 --- a/source/java/org/alfresco/filesys/smb/SMBDate.java +++ /dev/null @@ -1,153 +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.smb; - -import java.util.Calendar; -import java.util.Date; - -/** - * SMB date/time class. - */ -public final class SMBDate extends Date -{ - private static final long serialVersionUID = 3258407335553806902L; - - // Constants - // - // Bit masks for extracting the date/time fields from an SMB encoded date/time. - // - - private static final int Days = 0x001F; - private static final int Month = 0x01E0; - private static final int Year = 0xFE00; - - private static final int TwoSeconds = 0x001F; - private static final int Minutes = 0x07E0; - private static final int Hours = 0xF800; - - /** - * Construct the SMBDate using a seconds since 1-Jan-1970 00:00:00 value. - * - * @param secs Seconds since base date/time 1970 value - */ - - public SMBDate(int secs) - { - super((long) (secs & 0x7FFFFFFF)); - } - - /** - * Construct the SMBDate using the SMB encoded date/time values. - * - * @param dat SMB encoded date value - * @param tim SMB encoded time value - */ - - public SMBDate(int dat, int tim) - { - - // Extract the date from the SMB encoded value - - int days = dat & Days; - int months = (dat & Month) >> 5; - int year = (dat & Year) >> 9; - - // Extract the time from the SMB encoded value - - int secs = (tim & TwoSeconds) * 2; - int mins = (tim & Minutes) >> 5; - int hours = (tim & Hours) >> 11; - - // Use a calendar object to create the date/time value - - Calendar cal = Calendar.getInstance(); - cal.clear(); - cal.set(year + 1980, months - 1, days, hours, mins, secs); - - // Initialize this dates raw value - - this.setTime(cal.getTime().getTime()); - } - - /** - * Create a new SMBDate using the long time value. - * - * @param dattim long - */ - public SMBDate(long dattim) - { - super(dattim); - } - - /** - * Return this date as an SMB encoded date. - * - * @return SMB encoded date value. - */ - - public final int asSMBDate() - { - - // Use a calendar object to get the day, month and year values - - Calendar cal = Calendar.getInstance(); - cal.setTime(this); - - // Build the SMB encoded date value - - int smbDate = cal.get(Calendar.DAY_OF_MONTH); - smbDate += (cal.get(Calendar.MONTH) + 1) << 5; - smbDate += (cal.get(Calendar.YEAR) - 1980) << 9; - - // Return the SMB encoded date value - - return smbDate; - } - - /** - * Return this time as an SMB encoded time. - * - * @return SMB encoded time value. - */ - - public final int asSMBTime() - { - - // Use a calendar object to get the hour, minutes and seconds values - - Calendar cal = Calendar.getInstance(); - cal.setTime(this); - - // Build the SMB encoded time value - - int smbTime = cal.get(Calendar.SECOND) / 2; - smbTime += cal.get(Calendar.MINUTE) << 5; - smbTime += cal.get(Calendar.HOUR_OF_DAY) << 11; - - // Return the SMB encoded time value - - return smbTime; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/SMBDeviceType.java b/source/java/org/alfresco/filesys/smb/SMBDeviceType.java deleted file mode 100644 index 7ffe707c44..0000000000 --- a/source/java/org/alfresco/filesys/smb/SMBDeviceType.java +++ /dev/null @@ -1,74 +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.smb; - -/** - * SMB device types class. - *

- * The class provides symbols for the remote device types that may be connected to. The values are - * also used when returning remote share information. - */ -public class SMBDeviceType -{ - - // Device type constants - - public static final int Disk = 0; - public static final int Printer = 1; - public static final int Comm = 2; - public static final int Pipe = 3; - public static final int Unknown = -1; - - /** - * Convert the device type to a string - * - * @param devtyp Device type - * @return Device type string - */ - public static String asString(int devtyp) - { - String devStr = null; - - switch (devtyp) - { - case Disk: - devStr = "Disk"; - break; - case Printer: - devStr = "Printer"; - break; - case Pipe: - devStr = "Pipe"; - break; - case Comm: - devStr = "Comm"; - break; - default: - devStr = "Unknown"; - break; - } - return devStr; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/SMBErrorText.java b/source/java/org/alfresco/filesys/smb/SMBErrorText.java deleted file mode 100644 index 3c8e7f128a..0000000000 --- a/source/java/org/alfresco/filesys/smb/SMBErrorText.java +++ /dev/null @@ -1,850 +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.smb; - -/** - * SMB error text class. - *

- * The SMBErrorText is a static class that converts SMB error class/error codes into their - * appropriate error message strings. The class is used by the SMBException class when outputting an - * SMB exception as a string. - *

- * SMB error classes and error codes are declared in the SMBStatus class. - */ - -public final class SMBErrorText -{ - - /** - * Return the error string associated with the SMB error class/code - * - * @param errclass Error class. - * @param errcode Error code. - * @return Error string. - */ - public final static String ErrorString(int errclass, int errcode) - { - - // Determine the error class - - String errtext = null; - - switch (errclass) - { - - // Success class - - case SMBStatus.Success: - errtext = "The request was successful"; - break; - - // DOS error class - - case SMBStatus.ErrDos: - errtext = DOSErrorText(errcode); - break; - - // Server error class - - case SMBStatus.ErrSrv: - errtext = ServerErrorText(errcode); - break; - - // Hardware error class - - case SMBStatus.ErrHrd: - errtext = HardwareErrorText(errcode); - break; - - // Network error codes, returned by transaction requests - - case SMBStatus.NetErr: - errtext = NetworkErrorText(errcode); - break; - - // JLAN error codes - - case SMBStatus.JLANErr: - errtext = JLANErrorText(errcode); - break; - - // NT 32-bit error codes - - case SMBStatus.NTErr: - errtext = NTErrorText(errcode); - break; - - // Win32 error codes - - case SMBStatus.Win32Err: - errtext = Win32ErrorText(errcode); - break; - - // DCE/RPC error - - case SMBStatus.DCERPCErr: - errtext = DCERPCErrorText(errcode); - break; - - // Bad SMB command - - case SMBStatus.ErrCmd: - errtext = "Command was not in the SMB format"; - break; - } - - if (errtext == null) - errtext = "[Unknown error status/class: " + errclass + "," + errcode + "]"; - - // Return the error text - - return errtext; - } - - /** - * Return a DOS error string. - * - * @param errcode DOS error code. - * @return DOS error string. - */ - - private static String DOSErrorText(int errcode) - { - - // Convert the DOS error code to a text string - - String errtext = null; - - switch (errcode) - { - case 1: - errtext = "Invalid function. Server did not recognize/perform system call"; - break; - case 2: - errtext = "File not found"; - break; - case 3: - errtext = "Directory invalid"; - break; - case 4: - errtext = "Too many open files"; - break; - case 5: - errtext = "Access denied"; - break; - case 6: - errtext = "Invalid file handle"; - break; - case 7: - errtext = "Memory control blocks destroyed"; - break; - case 8: - errtext = "Insufficient server memory to perform function"; - break; - case 9: - errtext = "Invalid memory block address"; - break; - case 10: - errtext = "Invalid environment"; - break; - case 11: - errtext = "Invalid format"; - break; - case 12: - errtext = "Invalid open mode"; - break; - case 13: - errtext = "Invalid data, in server IOCTL call"; - break; - case 15: - errtext = "Invalid drive specified"; - break; - case 16: - errtext = "Delete directory attempted to delete servers directory"; - break; - case 17: - errtext = "Not same device"; - break; - case 18: - errtext = "No more files"; - break; - case 32: - errtext = "File sharing mode conflict"; - break; - case 33: - errtext = "Lock request conflicts with existing lock"; - break; - case 66: - errtext = "IPC not supported"; - break; - case 80: - errtext = "File already exists"; - break; - case 110: - errtext = "Cannot open the file specified"; - break; - case 124: - errtext = "Unknown information level"; - break; - case SMBStatus.DOSDirectoryNotEmpty: - errtext = "Directory not empty"; - break; - case 230: - errtext = "Named pipe invalid"; - break; - case 231: - errtext = "All instances of pipe are busy"; - break; - case 232: - errtext = "Named pipe close in progress"; - break; - case 233: - errtext = "No process on other end of named pipe"; - break; - case 234: - errtext = "More data to be returned"; - break; - case 267: - errtext = "Invalid directory name in path"; - break; - case 275: - errtext = "Extended attributes did not fit"; - break; - case 282: - errtext = "Extended attributes not supported"; - break; - case 2142: - errtext = "Unknown IPC"; - break; - } - - // Return the error string - - return errtext; - } - - /** - * Return a hardware error string. - * - * @param errcode Hardware error code. - * @return Hardware error string. - */ - private final static String HardwareErrorText(int errcode) - { - - // Convert the hardware error code to a text string - - String errtext = null; - - switch (errcode) - { - case 19: - errtext = "Attempt to write on write protected media"; - break; - case 20: - errtext = "Unknown unit"; - break; - case 21: - errtext = "Drive not ready"; - break; - case 22: - errtext = "Unknown command"; - break; - case 23: - errtext = "Data error (CRC)"; - break; - case 24: - errtext = "Bad request structure length"; - break; - case 25: - errtext = "Seek error"; - break; - case 26: - errtext = "Unknown media type"; - break; - case 27: - errtext = "Sector not found"; - break; - case 28: - errtext = "Printer out of paper"; - break; - case 29: - errtext = "Write fault"; - break; - case 30: - errtext = "Read fault"; - break; - case 31: - errtext = "General failure"; - break; - case 32: - errtext = "Open conflicts with existing open"; - break; - case 33: - errtext = "Lock request conflicted with existing lock"; - break; - case 34: - errtext = "Wrong disk was found in a drive"; - break; - case 35: - errtext = "No FCBs are available to process request"; - break; - case 36: - errtext = "A sharing buffer has been exceeded"; - break; - } - - // Return the error string - - return errtext; - } - - /** - * Return a JLAN error string. - * - * @return java.lang.String - * @param errcode int - */ - private static String JLANErrorText(int errcode) - { - - // Convert the JLAN error code to a text string - - String errtext = null; - - switch (errcode) - { - case SMBStatus.JLANUnsupportedDevice: - errtext = "Invalid device type for dialect"; - break; - case SMBStatus.JLANNoMoreSessions: - errtext = "No more sessions available"; - break; - case SMBStatus.JLANSessionNotActive: - errtext = "Session is not active"; - break; - case SMBStatus.JLANInvalidSMBReceived: - errtext = "Invalid SMB response received"; - break; - case SMBStatus.JLANLargeFilesNotSupported: - errtext = "Large files not supported"; - break; - case SMBStatus.JLANInvalidFileInfo: - errtext = "Invalid file information for level"; - break; - case SMBStatus.JLANDceRpcNotSupported: - errtext = "Server does not support DCE/RPC requests"; - break; - } - return errtext; - } - - /** - * Return a network error string. - * - * @param errcode Network error code. - * @return Network error string. - */ - private final static String NetworkErrorText(int errcode) - { - - // Convert the network error code to a text string - - String errtext = null; - - switch (errcode) - { - case SMBStatus.NETAccessDenied: - errtext = "Access denied"; - break; - case SMBStatus.NETInvalidHandle: - errtext = "Invalid handle"; - break; - case SMBStatus.NETUnsupported: - errtext = "Function not supported"; - break; - case SMBStatus.NETBadDeviceType: - errtext = "Bad device type"; - break; - case SMBStatus.NETBadNetworkName: - errtext = "Bad network name"; - break; - case SMBStatus.NETAlreadyAssigned: - errtext = "Already assigned"; - break; - case SMBStatus.NETInvalidPassword: - errtext = "Invalid password"; - break; - case SMBStatus.NETInvParameter: - errtext = "Incorrect parameter"; - break; - case SMBStatus.NETContinued: - errtext = "Transaction continued ..."; - break; - case SMBStatus.NETNoMoreItems: - errtext = "No more items"; - break; - case SMBStatus.NETInvalidAddress: - errtext = "Invalid address"; - break; - case SMBStatus.NETServiceDoesNotExist: - errtext = "Service does not exist"; - break; - case SMBStatus.NETBadDevice: - errtext = "Bad device"; - break; - case SMBStatus.NETNoNetOrBadPath: - errtext = "No network or bad path"; - break; - case SMBStatus.NETExtendedError: - errtext = "Extended error"; - break; - case SMBStatus.NETNoNetwork: - errtext = "No network"; - break; - case SMBStatus.NETCancelled: - errtext = "Cancelled"; - break; - case SMBStatus.NETSrvNotRunning: - errtext = "Server service is not running"; - break; - case SMBStatus.NETBufferTooSmall: - errtext = "Supplied buffer is too small"; - break; - case SMBStatus.NETNoTransactions: - errtext = "Server is not configured for transactions"; - break; - case SMBStatus.NETInvQueueName: - errtext = "Invalid queue name"; - break; - case SMBStatus.NETNoSuchPrintJob: - errtext = "Specified print job could not be located"; - break; - case SMBStatus.NETNotResponding: - errtext = "Print process is not responding"; - break; - case SMBStatus.NETSpoolerNotStarted: - errtext = "Spooler is not started on the remote server"; - break; - case SMBStatus.NETCannotPerformOp: - errtext = "Operation cannot be performed on the print job in it's current state"; - break; - case SMBStatus.NETErrLoadLogonScript: - errtext = "Error occurred running/loading logon script"; - break; - case SMBStatus.NETLogonNotValidated: - errtext = "Logon was not validated by any server"; - break; - case SMBStatus.NETLogonSrvOldSoftware: - errtext = "Logon server is running old software version, cannot validate logon"; - break; - case SMBStatus.NETUserNameNotFound: - errtext = "User name was not found"; - break; - case SMBStatus.NETUserLgnWkNotAllowed: - errtext = "User is not allowed to logon from this computer"; - break; - case SMBStatus.NETUserLgnTimeNotAllowed: - errtext = "USer is not allowed to logon at this time"; - break; - case SMBStatus.NETUserPasswordExpired: - errtext = "User password has expired"; - break; - case SMBStatus.NETPasswordCannotChange: - errtext = "Password cannot be changed"; - break; - case SMBStatus.NETPasswordTooShort: - errtext = "Password is too short"; - break; - } - - // Return the error string - - return errtext; - } - - /** - * Return a server error string. - * - * @param errcode Server error code. - * @return Server error string. - */ - private final static String ServerErrorText(int errcode) - { - - // Convert the server error code to a text string - - String errtext = null; - switch (errcode) - { - case 1: - errtext = "Non-specific error"; - break; - case 2: - errtext = "Bad password"; - break; - case 4: - errtext = "Client does not have access rights"; - break; - case 5: - errtext = "Invalid TID"; - break; - case 6: - errtext = "Invalid network name"; - break; - case 7: - errtext = "Invalid device"; - break; - case 49: - errtext = "Print queue full (files)"; - break; - case 50: - errtext = "Print queue full (space)"; - break; - case 51: - errtext = "EOF on print queue dump"; - break; - case 52: - errtext = "Invalid print file FID"; - break; - case 64: - errtext = "Server did not recognize the command received"; - break; - case 65: - errtext = "Internal server error"; - break; - case 67: - errtext = "FID and pathname combination invalid"; - break; - case 69: - errtext = "Invalid access permission"; - break; - case 71: - errtext = "Invalid attribute mode"; - break; - case 81: - errtext = "Server is paused"; - break; - case 82: - errtext = "Not receiving messages"; - break; - case 83: - errtext = "No room to buffer message"; - break; - case 87: - errtext = "Too many remote user names"; - break; - case 88: - errtext = "Operation timed out"; - break; - case 89: - errtext = "No resources available for request"; - break; - case 90: - errtext = "Too many UIDs active on session"; - break; - case 91: - errtext = "Invalid UID"; - break; - case 250: - errtext = "Unable to support RAW, use MPX"; - break; - case 251: - errtext = "Unable to support RAW, use standard read/write"; - break; - case 252: - errtext = "Continue in MPX mode"; - break; - case 65535: - errtext = "Function not supported"; - break; - } - - // Return the error string - - return errtext; - } - - /** - * Return an NT error string. - * - * @param errcode NT error code. - * @return NT error string. - */ - private final static String NTErrorText(int errcode) - { - - // Convert the NT error code to a text string - - String errtext = ""; - - switch (errcode) - { - case SMBStatus.NTSuccess: - errtext = "The request was successful"; - break; - case SMBStatus.NTAccessDenied: - errtext = "Access denied"; - break; - case SMBStatus.NTObjectNotFound: - errtext = "Object not found"; - break; - case SMBStatus.Win32InvalidHandle: - errtext = "Invalid handle"; - break; - case SMBStatus.Win32BadDeviceType: - errtext = "Bad device type"; - break; - case SMBStatus.Win32BadNetworkName: - errtext = "Bad network name"; - break; - case SMBStatus.Win32AlreadyAssigned: - errtext = "Already assigned"; - break; - case SMBStatus.Win32InvalidPassword: - errtext = "Invalid password"; - break; - case SMBStatus.NTInvalidParameter: - errtext = "Invalid parameter"; - break; - case SMBStatus.Win32MoreData: - errtext = "More data available"; - break; - case SMBStatus.Win32NoMoreItems: - errtext = "No more items"; - break; - case SMBStatus.Win32InvalidAddress: - errtext = "Invalid address"; - break; - case SMBStatus.Win32ServiceDoesNotExist: - errtext = "Service does not exist"; - break; - case SMBStatus.Win32BadDevice: - errtext = "Bad device"; - break; - case SMBStatus.Win32NoNetOrBadPath: - errtext = "No network or bad path"; - break; - case SMBStatus.Win32ExtendedError: - errtext = "Extended error"; - break; - case SMBStatus.Win32NoNetwork: - errtext = "No network"; - break; - case SMBStatus.NTCancelled: - errtext = "Cancelled"; - break; - case SMBStatus.NTBufferOverflow: - errtext = "Buffer overflow"; - break; - case SMBStatus.NTNoSuchFile: - errtext = "No such file"; - break; - case SMBStatus.NTInvalidDeviceRequest: - errtext = "Invalid device request"; - break; - case SMBStatus.NTMoreProcessingRequired: - errtext = "More processing required"; - break; - case SMBStatus.NTInvalidSecDescriptor: - errtext = "Invalid security descriptor"; - break; - case SMBStatus.NTNotSupported: - errtext = "Not supported"; - break; - case SMBStatus.NTBadDeviceType: - errtext = "Bad device type"; - break; - case SMBStatus.NTObjectPathNotFound: - errtext = "Object path not found"; - break; - case SMBStatus.NTLogonFailure: - errtext = "Logon failure"; - break; - case SMBStatus.NTAccountDisabled: - errtext = "Account disabled"; - break; - case SMBStatus.NTNoneMapped: - errtext = "None mapped"; - break; - case SMBStatus.NTInvalidInfoClass: - errtext = "Invalid information class"; - break; - case SMBStatus.NTObjectNameCollision: - errtext = "Object name collision"; - break; - case SMBStatus.NTNotImplemented: - errtext = "Not implemented"; - break; - case SMBStatus.NTFileOffline: - errtext = "File is offline"; - break; - case SMBStatus.NTSharingViolation: - errtext = "Sharing violation"; - break; - case SMBStatus.NTBadNetName: - errtext = "Bad network name"; - break; - case SMBStatus.NTBufferTooSmall: - errtext = "Buffer too small"; - break; - case SMBStatus.NTLockConflict: - errtext = "Lock conflict"; - break; - case SMBStatus.NTLockNotGranted: - errtext = "Lock not granted"; - break; - case SMBStatus.NTRangeNotLocked: - errtext = "Range not locked"; - break; - case SMBStatus.NTDiskFull: - errtext = "Disk full"; - break; - case SMBStatus.NTTooManyOpenFiles: - errtext = "Too many open files"; - break; - case SMBStatus.NTRequestNotAccepted: - errtext = "Request not accepted"; - break; - case SMBStatus.NTNoSuchDomain: - errtext = "No such domain"; - break; - case SMBStatus.NTNoMoreFiles: - errtext = "No more files"; - break; - case SMBStatus.NTObjectNameInvalid: - errtext = "Object name invalid"; - break; - case SMBStatus.NTPipeBusy: - errtext = "Pipe is busy"; - break; - case SMBStatus.NTInvalidLevel: - errtext = "Invalid information level"; - break; - default: - errtext = "Unknown NT status 0x" + Integer.toHexString(errcode); - break; - } - return errtext; - } - - /** - * Return a Win32 error string. - * - * @param errcode Win32 error code. - * @return Win32 error string. - */ - private final static String Win32ErrorText(int errcode) - { - - // Convert the Win32 error code to a text string - - String errtext = ""; - - switch (errcode) - { - case SMBStatus.Win32FileNotFound: - errtext = "File not found"; - break; - case SMBStatus.Win32PathNotFound: - errtext = "Path not found"; - break; - case SMBStatus.Win32AccessDenied: - errtext = "Access denied"; - break; - case SMBStatus.Win32InvalidHandle: - errtext = "Invalid handle"; - break; - case SMBStatus.Win32BadDeviceType: - errtext = "Bad device type"; - break; - case SMBStatus.Win32BadNetworkName: - errtext = "Bad network name"; - break; - case SMBStatus.Win32AlreadyAssigned: - errtext = "Already assigned"; - break; - case SMBStatus.Win32InvalidPassword: - errtext = "Invalid password"; - break; - case SMBStatus.Win32MoreEntries: - errtext = "More entries"; - break; - case SMBStatus.Win32MoreData: - errtext = "More data"; - break; - case SMBStatus.Win32NoMoreItems: - errtext = "No more items"; - break; - case SMBStatus.Win32InvalidAddress: - errtext = "Invalid address"; - break; - case SMBStatus.Win32ServiceDoesNotExist: - errtext = "Service does not exist"; - break; - case SMBStatus.Win32ServiceMarkedForDelete: - errtext = "Service marked for delete"; - break; - case SMBStatus.Win32ServiceExists: - errtext = "Service already exists"; - break; - case SMBStatus.Win32ServiceDuplicateName: - errtext = "Duplicate service name"; - break; - case SMBStatus.Win32BadDevice: - errtext = "Bad device"; - break; - case SMBStatus.Win32NoNetOrBadPath: - errtext = "No network or bad path"; - break; - case SMBStatus.Win32ExtendedError: - errtext = "Extended error"; - break; - case SMBStatus.Win32NoNetwork: - errtext = "No network"; - break; - default: - errtext = "Unknown Win32 status 0x" + Integer.toHexString(errcode); - break; - } - return errtext; - } - - /** - * Return a DCE/RPC error string. - * - * @param errcode DCE/RPC error code - * @return DCE/RPC error string. - */ - private final static String DCERPCErrorText(int errcode) - { - - // Convert the DCE/RPC error code to a text string - - if (errcode == SMBStatus.DCERPC_Fault) - return "DCE/RPC Fault"; - return "DCE/RPC Error 0x" + Integer.toHexString(errcode); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/SMBException.java b/source/java/org/alfresco/filesys/smb/SMBException.java deleted file mode 100644 index e34803fd57..0000000000 --- a/source/java/org/alfresco/filesys/smb/SMBException.java +++ /dev/null @@ -1,100 +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.smb; - -/** - * SMB exception class - *

- * This class holds the detail of an SMB network error. The SMB error class and error code are - * available to give extra detail about the error condition. - */ -public class SMBException extends Exception -{ - private static final long serialVersionUID = 3256719593644176946L; - - // SMB error class - - protected int m_errorclass; - - // SMB error code - - protected int m_errorcode; - - /** - * Construct an SMB exception with the specified error class/error code. - */ - - public SMBException(int errclass, int errcode) - { - super(SMBErrorText.ErrorString(errclass, errcode)); - m_errorclass = errclass; - m_errorcode = errcode; - } - - /** - * Construct an SMB exception with the specified error class/error code and additional text - * error message. - */ - - public SMBException(int errclass, int errcode, String msg) - { - super(msg); - m_errorclass = errclass; - m_errorcode = errcode; - } - - /** - * Return the error class for this SMB exception. - * - * @return SMB error class. - */ - - public int getErrorClass() - { - return m_errorclass; - } - - /** - * Return the error code for this SMB exception - * - * @return SMB error code - */ - - public int getErrorCode() - { - return m_errorcode; - } - - /** - * Return the error text for the SMB exception - * - * @return Error text string. - */ - - public String getErrorText() - { - return SMBErrorText.ErrorString(m_errorclass, m_errorcode); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/SMBStatus.java b/source/java/org/alfresco/filesys/smb/SMBStatus.java deleted file mode 100644 index 5c3d93f2d4..0000000000 --- a/source/java/org/alfresco/filesys/smb/SMBStatus.java +++ /dev/null @@ -1,286 +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.smb; - -/** - * SMB status code class. - *

- * The SMBStatus class contains the error class and error code values that a remote server may - * return. - *

- * The available error classes are defined below :- - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
SMBStatus.SuccesIndicates that an SMB request was successful
SMBStatus.ErrDOSError is from the DOS operating system set
SMBStatus.ErrSrvError is from the server network file manager
SMBStatus.ErrHrdError is a hardware type error
SMBStatus.ErrCmdCommand was not in the SMB format
SMBStatus.NetErrErrors returned by SMB transactions
SMBStatus.NTErr32 bit errors returned when NT dialect is in use
SMBStatus.DCERPCErrErrors returned by DCE/RPC requests
SMBStatus.JLANErrJLAN error codes
- */ -public final class SMBStatus -{ - - // Error classes - - public static final int Success = 0x00; - public static final int ErrDos = 0x01; - public static final int ErrSrv = 0x02; - public static final int ErrHrd = 0x03; - public static final int NetErr = 0x04; - public static final int JLANErr = 0x05; - public static final int NTErr = 0x06; - public static final int DCERPCErr = 0x07; - public static final int Win32Err = 0x08; - - public static final int ErrCmd = 0xFF; - - // Mask for NT severity - - public static final int NT_SEVERITY_MASK = 0xF0000000; - public static final int NT_ERROR_MASK = 0x0FFFFFFF; - - // DOS error codes. - - public static final int DOSInvalidFunc = 1; - public static final int DOSFileNotFound = 2; - public static final int DOSDirectoryInvalid = 3; - public static final int DOSTooManyOpenFiles = 4; - public static final int DOSAccessDenied = 5; - public static final int DOSInvalidHandle = 6; - public static final int DOSMemCtrlBlkDestoyed = 7; - public static final int DOSInsufficientMem = 8; - public static final int DOSInvalidAddress = 9; - public static final int DOSInvalidEnv = 10; - public static final int DOSInvalidFormat = 11; - public static final int DOSInvalidOpenMode = 12; - public static final int DOSInvalidData = 13; - public static final int DOSInvalidDrive = 15; - public static final int DOSDeleteSrvDir = 16; - public static final int DOSNotSameDevice = 17; - public static final int DOSNoMoreFiles = 18; - public static final int DOSFileSharingConflict = 32; - public static final int DOSLockConflict = 33; - public static final int DOSFileAlreadyExists = 80; - public static final int DOSUnknownInfoLevel = 124; - public static final int DOSDirectoryNotEmpty = 145; - public static final int DOSNotLocked = 158; - - // Server error codes - - public static final int SRVNonSpecificError = 1; - public static final int SRVBadPassword = 2; - public static final int SRVNoAccessRights = 4; - public static final int SRVInvalidTID = 5; - public static final int SRVInvalidNetworkName = 6; - public static final int SRVInvalidDevice = 7; - public static final int SRVPrintQueueFullFiles = 49; - public static final int SRVPrintQueueFullSpace = 50; - public static final int SRVEOFOnPrintQueueDump = 51; - public static final int SRVInvalidPrintFID = 52; - public static final int SRVUnrecognizedCommand = 64; - public static final int SRVInternalServerError = 65; - public static final int SRVFIDAndPathInvalid = 67; - public static final int SRVInvalidAccessPerm = 69; - public static final int SRVInvalidAttributeMode = 70; - public static final int SRVServerPaused = 81; - public static final int SRVNotReceivingMessages = 82; - public static final int SRVNoBuffers = 83; - public static final int SRVTooManyRemoteNames = 87; - public static final int SRVTimedOut = 88; - public static final int SRVNoResourcesAvailable = 89; - public static final int SRVTooManyUIDs = 90; - public static final int SRVInvalidUID = 91; - public static final int SRVNoRAWUseMPX = 250; - public static final int SRVNoRAWUseStdReadWrite = 251; - public static final int SRVContinueInMPXMode = 252; - public static final int SRVNotSupported = 65535; - - // Hardware error codes. - - public static final int HRDWriteProtected = 19; - public static final int HRDUnknownUnit = 20; - public static final int HRDDriveNotReady = 21; - public static final int HRDUnknownCommand = 22; - public static final int HRDDataError = 23; - public static final int HRDBadRequestLength = 24; - public static final int HRDSeekError = 25; - public static final int HRDUnknownMediaType = 26; - public static final int HRDSectorNotFound = 27; - public static final int HRDPrinterOutOfPaper = 28; - public static final int HRDWriteFault = 29; - public static final int HRDReadFault = 30; - public static final int HRDGeneralFailure = 31; - public static final int HRDOpenConflict = 32; - public static final int HRDLockConflict = 33; - public static final int HRDWrongDiskInDrive = 34; - public static final int HRDNoFCBsAvailable = 35; - public static final int HRDSharingBufferOverrun = 36; - - // Network error codes - - public static final int NETAccessDenied = 5; - public static final int NETInvalidHandle = 6; - public static final int NETUnsupported = 50; - public static final int NETNetAccessDenied = 65; - public static final int NETBadDeviceType = 66; - public static final int NETBadNetworkName = 67; - public static final int NETAlreadyAssigned = 85; - public static final int NETInvalidPassword = 86; - public static final int NETInvParameter = 87; - public static final int NETContinued = 234; - public static final int NETNoMoreItems = 259; - public static final int NETInvalidAddress = 487; - public static final int NETServiceDoesNotExist = 1060; - public static final int NETBadDevice = 1200; - public static final int NETNoNetOrBadPath = 1203; - public static final int NETExtendedError = 1208; - public static final int NETNoNetwork = 1222; - public static final int NETCancelled = 1223; - public static final int NETSrvNotRunning = 2114; - public static final int NETBufferTooSmall = 2123; - public static final int NETNoTransactions = 2141; - public static final int NETInvQueueName = 2150; - public static final int NETNoSuchPrintJob = 2151; - public static final int NETNotResponding = 2160; - public static final int NETSpoolerNotStarted = 2161; - public static final int NETCannotPerformOp = 2164; - public static final int NETErrLoadLogonScript = 2212; - public static final int NETLogonNotValidated = 2214; - public static final int NETLogonSrvOldSoftware = 2217; - public static final int NETUserNameNotFound = 2221; - public static final int NETUserLgnWkNotAllowed = 2240; - public static final int NETUserLgnTimeNotAllowed = 2241; - public static final int NETUserPasswordExpired = 2242; - public static final int NETPasswordCannotChange = 2243; - public static final int NETPasswordTooShort = 2246; - - // JLAN error codes - - public static final int JLANUnsupportedDevice = 1; - public static final int JLANNoMoreSessions = 2; - public static final int JLANSessionNotActive = 3; - public static final int JLANInvalidSMBReceived = 4; - public static final int JLANLargeFilesNotSupported = 5; - public static final int JLANInvalidFileInfo = 6; - public static final int JLANDceRpcNotSupported = 7; - - // NT 32-bit status code - - public static final int NTSuccess = 0; - - public static final int NTNotImplemented = 0xC0000002; - public static final int NTInvalidInfoClass = 0xC0000003; - public static final int NTInvalidParameter = 0xC000000D; - public static final int NTNoSuchFile = 0xC000000F; - public static final int NTInvalidDeviceRequest = 0xC0000010; - public static final int NTMoreProcessingRequired = 0xC0000016; - public static final int NTAccessDenied = 0xC0000022; - public static final int NTBufferTooSmall = 0xC0000023; - public static final int NTObjectNameInvalid = 0xC0000033; - public static final int NTObjectNotFound = 0xC0000034; - public static final int NTObjectNameCollision = 0xC0000035; - public static final int NTObjectPathNotFound = 0xC000003A; - public static final int NTObjectPathSyntaxBad = 0xC000003B; - public static final int NTSharingViolation = 0xC0000043; - public static final int NTLockConflict = 0xC0000054; - public static final int NTLockNotGranted = 0xC0000055; - public static final int NTLogonFailure = 0xC000006D; - public static final int NTAccountDisabled = 0xC0000072; - public static final int NTNoneMapped = 0xC0000073; - public static final int NTInvalidSecDescriptor = 0xC0000079; - public static final int NTRangeNotLocked = 0xC000007E; - public static final int NTDiskFull = 0xC000007F; - public static final int NTPipeBusy = 0xC00000AE; - public static final int NTNotSupported = 0xC00000BB; - public static final int NTBadDeviceType = 0xC00000CB; - public static final int NTBadNetName = 0xC00000CC; - public static final int NTRequestNotAccepted = 0xC00000D0; - public static final int NTNoSuchDomain = 0xC00000DF; - public static final int NTTooManyOpenFiles = 0xC000011F; - public static final int NTCancelled = 0xC0000120; - public static final int NTInvalidLevel = 0xC0000148; - public static final int NTFileOffline = 0xC0000267; - - public static final int Win32FileNotFound = 2; - public static final int Win32PathNotFound = 3; - public static final int Win32AccessDenied = 5; - public static final int Win32InvalidHandle = 6; - public static final int Win32BadDeviceType = 66; - public static final int Win32BadNetworkName = 67; - public static final int Win32AlreadyAssigned = 85; - public static final int Win32InvalidPassword = 86; - public static final int Win32MoreData = 234; - public static final int Win32NoMoreItems = 259; - public static final int Win32MoreEntries = 261; - public static final int Win32InvalidAddress = 487; - public static final int Win32ServiceDoesNotExist = 1060; - public static final int Win32ServiceMarkedForDelete = 1072; - public static final int Win32ServiceExists = 1073; - public static final int Win32ServiceDuplicateName = 1077; - public static final int Win32BadDevice = 1200; - public static final int Win32NoNetOrBadPath = 1203; - public static final int Win32ExtendedError = 1208; - public static final int Win32NoNetwork = 1222; - - public static final int NTBufferOverflow = 0x80000005; - public static final int NTNoMoreFiles = 0x80000006; - public static final int NTNotifyEnumDir = 0x0000010C; - - // DEC/RPC status codes - - public static final int DCERPC_Fault = 0; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/SeekType.java b/source/java/org/alfresco/filesys/smb/SeekType.java deleted file mode 100644 index 9d9f05c277..0000000000 --- a/source/java/org/alfresco/filesys/smb/SeekType.java +++ /dev/null @@ -1,37 +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.smb; - -/** - * Seek file position types. - */ -public class SeekType -{ - // Seek file types - - public static final int StartOfFile = 0; - public static final int CurrentPos = 1; - public static final int EndOfFile = 2; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/ServerType.java b/source/java/org/alfresco/filesys/smb/ServerType.java deleted file mode 100644 index a8bcff3398..0000000000 --- a/source/java/org/alfresco/filesys/smb/ServerType.java +++ /dev/null @@ -1,426 +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.smb; - -import org.alfresco.filesys.util.*; - -/** - * Server Type Flags Class - */ -public class ServerType -{ - - // Server type flags - - public static final int WorkStation = 0x00000001; - public static final int Server = 0x00000002; - public static final int SQLServer = 0x00000004; - public static final int DomainCtrl = 0x00000008; - public static final int DomainBakCtrl = 0x00000010; - public static final int TimeSource = 0x00000020; - public static final int AFPServer = 0x00000040; - public static final int NovellServer = 0x00000080; - public static final int DomainMember = 0x00000100; - public static final int PrintServer = 0x00000200; - public static final int DialinServer = 0x00000400; - public static final int UnixServer = 0x00000800; - public static final int NTServer = 0x00001000; - public static final int WfwServer = 0x00002000; - public static final int MFPNServer = 0x00004000; - public static final int NTNonDCServer = 0x00008000; - public static final int PotentialBrowse = 0x00010000; - public static final int BackupBrowser = 0x00020000; - public static final int MasterBrowser = 0x00040000; - public static final int DomainMaster = 0x00080000; - public static final int OSFServer = 0x00100000; - public static final int VMSServer = 0x00200000; - public static final int Win95Plus = 0x00400000; - public static final int DFSRoot = 0x00800000; - public static final int NTCluster = 0x01000000; - public static final int TerminalServer = 0x02000000; - public static final int DCEServer = 0x10000000; - public static final int AlternateXport = 0x20000000; - public static final int LocalListOnly = 0x40000000; - - public static final int DomainEnum = 0x80000000; - - // Server type strings - - private static final String[] _srvType = { - "Workstation", - "Server", - "SQLServer", - "DomainController", - "BackupDomainController", - "TimeSource", - "AFPServer", - "NovellServer", - "DomainMember", - "PrintServer", - "DialinServer", - "UnixServer", - "NTServer", - "WfwServer", - "MFPNServer", - "NtNonDCServer", - "PotentialBrowse", - "BackupBrowser", - "MasterBrowser", - "DomainMaster", - "OSFServer", - "VMSServer", - "Win95Plus", - "DFSRoot", - "NTCluster", - "TerminalServer", - "", - "", - "DCEServer" }; - - /** - * Convert server type flags to a list of server type strings - * - * @param typ int - * @return StringList - */ - public static final StringList TypeAsStrings(int typ) - { - // Allocate the vector for the strings - - StringList strs = new StringList(); - - // Test each type bit and add the appropriate type string - - for (int i = 0; i < _srvType.length; i++) - { - // Check the current type flag - - int mask = 1 << i; - if ((typ & mask) != 0) - strs.addString(_srvType[i]); - } - - // Return the list of type strings - - return strs; - } - - /** - * Check if the workstation flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isWorkStation(int typ) - { - return (typ & WorkStation) != 0 ? true : false; - } - - /** - * Check if the server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isServer(int typ) - { - return (typ & Server) != 0 ? true : false; - } - - /** - * Check if the SQL server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isSQLServer(int typ) - { - return (typ & SQLServer) != 0 ? true : false; - } - - /** - * Check if the domain controller flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDomainController(int typ) - { - return (typ & DomainCtrl) != 0 ? true : false; - } - - /** - * Check if the backup domain controller flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isBackupDomainController(int typ) - { - return (typ & DomainBakCtrl) != 0 ? true : false; - } - - /** - * Check if the time source flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isTimeSource(int typ) - { - return (typ & TimeSource) != 0 ? true : false; - } - - /** - * Check if the AFP server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isAFPServer(int typ) - { - return (typ & AFPServer) != 0 ? true : false; - } - - /** - * Check if the Novell server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isNovellServer(int typ) - { - return (typ & NovellServer) != 0 ? true : false; - } - - /** - * Check if the domain member flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDomainMember(int typ) - { - return (typ & DomainMember) != 0 ? true : false; - } - - /** - * Check if the print server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isPrintServer(int typ) - { - return (typ & PrintServer) != 0 ? true : false; - } - - /** - * Check if the dialin server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDialinServer(int typ) - { - return (typ & DialinServer) != 0 ? true : false; - } - - /** - * Check if the Unix server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isUnixServer(int typ) - { - return (typ & UnixServer) != 0 ? true : false; - } - - /** - * Check if the NT server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isNTServer(int typ) - { - return (typ & NTServer) != 0 ? true : false; - } - - /** - * Check if the WFW server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isWFWServer(int typ) - { - return (typ & WfwServer) != 0 ? true : false; - } - - /** - * Check if the MFPN server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isMFPNServer(int typ) - { - return (typ & MFPNServer) != 0 ? true : false; - } - - /** - * Check if the NT non-domain controller server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isNTNonDomainServer(int typ) - { - return (typ & NTNonDCServer) != 0 ? true : false; - } - - /** - * Check if the potential browse master flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isPotentialBrowseMaster(int typ) - { - return (typ & PotentialBrowse) != 0 ? true : false; - } - - /** - * Check if the backup browser flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isBackupBrowser(int typ) - { - return (typ & BackupBrowser) != 0 ? true : false; - } - - /** - * Check if the browse master flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isBrowserMaster(int typ) - { - return (typ & MasterBrowser) != 0 ? true : false; - } - - /** - * Check if the domain master flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDomainMaster(int typ) - { - return (typ & DomainMaster) != 0 ? true : false; - } - - /** - * Check if the OSF server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isOSFServer(int typ) - { - return (typ & OSFServer) != 0 ? true : false; - } - - /** - * Check if the VMS server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isVMSServer(int typ) - { - return (typ & VMSServer) != 0 ? true : false; - } - - /** - * Check if the Win95 plus flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isWin95Plus(int typ) - { - return (typ & Win95Plus) != 0 ? true : false; - } - - /** - * Check if the DFS root flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDFSRoot(int typ) - { - return (typ & DFSRoot) != 0 ? true : false; - } - - /** - * Check if the NT cluster flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isNTCluster(int typ) - { - return (typ & NTCluster) != 0 ? true : false; - } - - /** - * Check if the terminal server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isTerminalServer(int typ) - { - return (typ & TerminalServer) != 0 ? true : false; - } - - /** - * Check if the DCE server flag is set - * - * @param typ int - * @return boolean - */ - public static final boolean isDCEServer(int typ) - { - return (typ & DCEServer) != 0 ? true : false; - } -} diff --git a/source/java/org/alfresco/filesys/smb/SharingMode.java b/source/java/org/alfresco/filesys/smb/SharingMode.java deleted file mode 100644 index 09d74a5ff7..0000000000 --- a/source/java/org/alfresco/filesys/smb/SharingMode.java +++ /dev/null @@ -1,41 +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.smb; - -/** - * File Sharing Mode Class - */ -public class SharingMode -{ - - // File sharing mode constants - - public final static int NOSHARING = 0x0000; - public final static int READ = 0x0001; - public final static int WRITE = 0x0002; - public final static int DELETE = 0x0004; - - public final static int READWRITE = READ + WRITE; -} diff --git a/source/java/org/alfresco/filesys/smb/TcpipSMB.java b/source/java/org/alfresco/filesys/smb/TcpipSMB.java deleted file mode 100644 index cd70016816..0000000000 --- a/source/java/org/alfresco/filesys/smb/TcpipSMB.java +++ /dev/null @@ -1,36 +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.smb; - -/** - * Native TCP/IP SMB Constants Class - */ -public class TcpipSMB -{ - - // Default port for native TCP SMB - - public static final int PORT = 445; -} diff --git a/source/java/org/alfresco/filesys/smb/TransactBuffer.java b/source/java/org/alfresco/filesys/smb/TransactBuffer.java deleted file mode 100644 index 8e4e01f672..0000000000 --- a/source/java/org/alfresco/filesys/smb/TransactBuffer.java +++ /dev/null @@ -1,625 +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.smb; - -import org.alfresco.filesys.util.DataBuffer; - -/** - * Transact Buffer Class - *

- * Contains the parameters and data for a transaction, transaction2 or NT transaction request. - */ -public class TransactBuffer -{ - - // Default buffer sizes - - protected static final int DefaultSetupSize = 32; - protected static final int DefaultDataSize = 8192; - protected static final int DefaultParameterSize = 64; - - // Default maximum return buffer sizes - - protected static final int DefaultMaxSetupReturn = 16; - protected static final int DefaultMaxParameterReturn = 256; - protected static final int DefaultMaxDataReturn = 65000; - - // Tree id, connection that the transaction is for - - protected int m_treeId = -1; - - // Transaction packet type and sub-function - - protected int m_type; - protected int m_func; - - // Transaction name, for Transaction2 only - - protected String m_name; - - // Setup parameters - - protected DataBuffer m_setupBuf; - - // Parameter block - - protected DataBuffer m_paramBuf; - - // Data block and read/write position - - protected DataBuffer m_dataBuf; - - // Flag to indicate if this is a multi-packet transaction - - protected boolean m_multi; - - // Unicode strings flag - - protected boolean m_unicode; - - // Maximum setup, parameter and data bytes to return - - protected int m_maxSetup = DefaultMaxSetupReturn; - protected int m_maxParam = DefaultMaxParameterReturn; - protected int m_maxData = DefaultMaxDataReturn; - - /** - * Default constructor - */ - public TransactBuffer() - { - m_setupBuf = new DataBuffer(DefaultSetupSize); - m_paramBuf = new DataBuffer(DefaultParameterSize); - m_dataBuf = new DataBuffer(DefaultDataSize); - } - - /** - * Class constructor - * - * @param scnt int - * @param pcnt int - * @param dcnt int - */ - public TransactBuffer(int scnt, int pcnt, int dcnt) - { - - // Allocate the setup parameter buffer - - if (scnt > 0) - m_setupBuf = new DataBuffer(scnt); - - // Allocate the paramater buffer - - if (pcnt > 0) - m_paramBuf = new DataBuffer(pcnt); - - // Allocate the data buffer - - if (dcnt > 0) - m_dataBuf = new DataBuffer(dcnt); - - // Multi-packet transaction - - m_multi = true; - } - - /** - * Class constructor - * - * @param cmd int - * @param scnt int - * @param pcnt int - * @param dcnt int - */ - public TransactBuffer(int cmd, int scnt, int pcnt, int dcnt) - { - - // Set the command - - setType(cmd); - - // Allocate the setup parameter buffer - - if (scnt > 0) - m_setupBuf = new DataBuffer(scnt); - - // Allocate the paramater buffer - - if (pcnt > 0) - m_paramBuf = new DataBuffer(pcnt); - - // Allocate the data buffer - - if (dcnt > 0) - m_dataBuf = new DataBuffer(dcnt); - - // Multi-packet transaction - - m_multi = true; - } - - /** - * Class constructor - * - * @param func int - * @param name String - * @param scnt int - * @param pcnt int - * @param dcnt int - */ - public TransactBuffer(int func, String name, int scnt, int pcnt, int dcnt) - { - - // Set the name, for Transaction2 - - setName(name); - - // Allocate the setup parameter buffer - - if (scnt > 0) - m_setupBuf = new DataBuffer(scnt); - - // Allocate the paramater buffer - - if (pcnt > 0) - m_paramBuf = new DataBuffer(pcnt); - - // Allocate the data buffer - - if (dcnt > 0) - m_dataBuf = new DataBuffer(dcnt); - - // Set the function code - - setFunction(func); - - // Multi-packet transaction - - m_multi = true; - } - - /** - * Class constructor - * - * @param func int - * @param scnt int - * @param pcnt int - * @param dbuf byte[] - * @param doff int - * @param dlen int - */ - public TransactBuffer(int func, int scnt, int pcnt, byte[] dbuf, int doff, int dlen) - { - - // Allocate the setup parameter buffer - - if (scnt > 0) - m_setupBuf = new DataBuffer(scnt); - - // Allocate the paramater buffer - - if (pcnt > 0) - m_paramBuf = new DataBuffer(pcnt); - - // Allocate the data buffer - - if (dbuf != null) - m_dataBuf = new DataBuffer(dbuf, doff, dlen); - - // Set the function code - - setFunction(func); - - // Multi-packet transaction - - m_multi = true; - } - - /** - * Determine if the tree id has been set - * - * @return boolean - */ - public final boolean hasTreeId() - { - return m_treeId != -1 ? true : false; - } - - /** - * Return the tree id - * - * @return int - */ - public final int getTreeId() - { - return m_treeId; - } - - /** - * Return the transaction type (from SBMSrvPacketType, either Transaction, Transaction2 or - * NTTransact) - * - * @return int - */ - public final int isType() - { - return m_type; - } - - /** - * Return the transaction function - * - * @return int - */ - public final int getFunction() - { - return m_func; - } - - /** - * Determine if the transaction has a name - * - * @return boolean - */ - public final boolean hasName() - { - return m_name != null ? true : false; - } - - /** - * Return the transaction name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Determine if this is a multi-packet transaction - * - * @return boolean - */ - public final boolean isMultiPacket() - { - return m_multi; - } - - /** - * Determine if the client is using Unicode strings - * - * @return boolean - */ - public final boolean isUnicode() - { - return m_unicode; - } - - /** - * Determine if the transaction buffer has setup data - * - * @return boolean - */ - public final boolean hasSetupBuffer() - { - return m_setupBuf != null ? true : false; - } - - /** - * Return the setup parameter buffer - * - * @return DataBuffer - */ - public final DataBuffer getSetupBuffer() - { - return m_setupBuf; - } - - /** - * Determine if the transaction buffer has parameter data - * - * @return boolean - */ - public final boolean hasParameterBuffer() - { - return m_paramBuf != null ? true : false; - } - - /** - * Return the parameter buffer - * - * @return DataBuffer - */ - public final DataBuffer getParameterBuffer() - { - return m_paramBuf; - } - - /** - * Determine if the transaction buffer has a data block - * - * @return boolean - */ - public final boolean hasDataBuffer() - { - return m_dataBuf != null ? true : false; - } - - /** - * Return the data buffer - * - * @return DataBuffer - */ - public final DataBuffer getDataBuffer() - { - return m_dataBuf; - } - - /** - * Return the setup return data limit - * - * @return int - */ - public final int getReturnSetupLimit() - { - return m_maxSetup; - } - - /** - * Return the parameter return data limit - * - * @return int - */ - public final int getReturnParameterLimit() - { - return m_maxParam; - } - - /** - * Return the data return data limit - * - * @return int - */ - public final int getReturnDataLimit() - { - return m_maxData; - } - - /** - * Set the tree id - * - * @param tid int - */ - public final void setTreeId(int tid) - { - m_treeId = tid; - } - - /** - * Set the transaction type - * - * @param typ int - */ - public final void setType(int typ) - { - m_type = typ; - } - - /** - * Set the transaction function - * - * @param func int - */ - public final void setFunction(int func) - { - m_func = func; - } - - /** - * Set the transaction name, for Transactin2 - * - * @param name String - */ - public final void setName(String name) - { - m_name = name; - } - - /** - * Set the Unicode strings flag - * - * @param uni boolean - */ - public final void setUnicode(boolean uni) - { - m_unicode = uni; - } - - /** - * Set the limit of returned setup bytes - * - * @param limit int - */ - public final void setReturnSetupLimit(int limit) - { - m_maxSetup = limit; - } - - /** - * Set the limit of returned parameter bytes - * - * @param limit int - */ - public final void setReturnParameterLimit(int limit) - { - m_maxParam = limit; - } - - /** - * Set the limit of returned data bytes - * - * @param limit int - */ - public final void setReturnDataLimit(int limit) - { - m_maxData = limit; - } - - /** - * Set the setup, parameter and data return data limits - * - * @param slimit int - * @param plimit int - * @param dlimit int - */ - public final void setReturnLimits(int slimit, int plimit, int dlimit) - { - setReturnSetupLimit(slimit); - setReturnParameterLimit(plimit); - setReturnDataLimit(dlimit); - } - - /** - * Set the end of buffer positions for the setup, parameter and data buffers ready for reading - * the data. - */ - public final void setEndOfBuffer() - { - - // Set the end of the setup buffer - - if (m_setupBuf != null) - m_setupBuf.setEndOfBuffer(); - - // Set the end of the parameter buffer - - if (m_paramBuf != null) - m_paramBuf.setEndOfBuffer(); - - // Set the end of the data buffer - - if (m_dataBuf != null) - m_dataBuf.setEndOfBuffer(); - } - - /** - * Append setup data to the setup data buffer - * - * @param buf byte[] - * @param off int - * @param len int - */ - public final void appendSetup(byte[] buf, int off, int len) - { - m_setupBuf.appendData(buf, off, len); - } - - /** - * Append parameter data to the parameter data buffer - * - * @param buf byte[] - * @param off int - * @param len int - */ - public final void appendParameter(byte[] buf, int off, int len) - { - m_paramBuf.appendData(buf, off, len); - } - - /** - * Append data to the data buffer - * - * @param buf byte[] - * @param off int - * @param len int - */ - public final void appendData(byte[] buf, int off, int len) - { - m_dataBuf.appendData(buf, off, len); - } - - /** - * Return the transaction buffer details as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - - switch (isType()) - { - case PacketType.Transaction: - str.append("Trans"); - break; - case PacketType.Transaction2: - str.append("Trans2("); - str.append(getName()); - str.append(")"); - break; - case PacketType.NTTransact: - str.append("NTTrans"); - break; - default: - str.append("Unknown"); - break; - } - str.append("-0x"); - str.append(Integer.toHexString(getFunction())); - - str.append(": setup="); - if (m_setupBuf != null) - str.append(m_setupBuf); - else - str.append("none"); - - str.append(",param="); - if (m_paramBuf != null) - str.append(m_paramBuf); - else - str.append("none"); - - str.append(",data="); - if (m_dataBuf != null) - str.append(m_dataBuf); - else - str.append("none"); - str.append("]"); - - str.append(",max="); - str.append(getReturnSetupLimit()); - - str.append("/"); - str.append(getReturnParameterLimit()); - - str.append("/"); - str.append(getReturnDataLimit()); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/TransactionNames.java b/source/java/org/alfresco/filesys/smb/TransactionNames.java deleted file mode 100644 index 8849d312cf..0000000000 --- a/source/java/org/alfresco/filesys/smb/TransactionNames.java +++ /dev/null @@ -1,37 +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.smb; - -/** - * List of the available transaction names. - */ -public class TransactionNames -{ - - // Available transaction names - - public static final String PipeLanman = "\\PIPE\\LANMAN"; - public static final String MailslotBrowse = "\\MAILSLOT\\BROWSE"; -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/WinNT.java b/source/java/org/alfresco/filesys/smb/WinNT.java deleted file mode 100644 index e4bab114b9..0000000000 --- a/source/java/org/alfresco/filesys/smb/WinNT.java +++ /dev/null @@ -1,75 +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.smb; - -/** - * Windows NT Constants Class - */ -public class WinNT -{ - - // Compression format types - - public final static int CompressionFormatNone = 0; - public final static int CompressionFormatDefault = 1; - public final static int CompressionFormatLZNT1 = 2; - - // Get/set security descriptor flags - - public final static int SecurityOwner = 0x0001; - public final static int SecurityGroup = 0x0002; - public final static int SecurityDACL = 0x0004; - public final static int SecuritySACL = 0x0008; - - // Security impersonation levels - - public static final int SecurityAnonymous = 0; - public static final int SecurityIdentification = 1; - public static final int SecurityImpersonation = 2; - public static final int SecurityDelegation = 3; - - // Security flags - - public static final int SecurityContextTracking = 0x00040000; - public static final int SecurityEffectiveOnly = 0x00080000; - - // NTCreateAndX flags (oplocks/target) - - public static final int RequestOplock = 0x0002; - public static final int RequestBatchOplock = 0x0004; - public static final int TargetDirectory = 0x0008; - public static final int ExtendedResponse = 0x0010; - - // NTCreateAndX create options flags - - public static final int CreateFile = 0x00000000; - public static final int CreateDirectory = 0x00000001; - public static final int CreateWriteThrough = 0x00000002; - public static final int CreateSequential = 0x00000004; - - public static final int CreateNonDirectory = 0x00000040; - public static final int CreateRandomAccess = 0x00000800; - public static final int CreateDeleteOnClose = 0x00001000; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEBuffer.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEBuffer.java deleted file mode 100644 index 7d3726fe02..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEBuffer.java +++ /dev/null @@ -1,1904 +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.smb.dcerpc; - -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.TransactBuffer; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; - -/** - * DCE Buffer Class - */ -public class DCEBuffer -{ - - // Header value types - - public static final int HDR_VERMAJOR = 0; - public static final int HDR_VERMINOR = 1; - public static final int HDR_PDUTYPE = 2; - public static final int HDR_FLAGS = 3; - public static final int HDR_DATAREP = 4; - public static final int HDR_FRAGLEN = 5; - public static final int HDR_AUTHLEN = 6; - public static final int HDR_CALLID = 7; - public static final int HDR_ALLOCHINT = 8; - public static final int HDR_OPCODE = 9; - - // Header flags - - public static final int FLG_FIRSTFRAG = 0x01; - public static final int FLG_LASTFRAG = 0x02; - public static final int FLG_CANCEL = 0x04; - public static final int FLG_IDEMPOTENT = 0x20; - public static final int FLG_BROADCAST = 0x40; - - public static final int FLG_ONLYFRAG = 0x03; - - // DCE/RPC header offsets - - public static final int VERSIONMAJOR = 0; - public static final int VERSIONMINOR = 1; - public static final int PDUTYPE = 2; - public static final int HEADERFLAGS = 3; - public static final int PACKEDDATAREP = 4; - public static final int FRAGMENTLEN = 8; - public static final int AUTHLEN = 10; - public static final int CALLID = 12; - public static final int DCEDATA = 16; - - // DCE/RPC Request offsets - - public static final int ALLOCATIONHINT = 16; - public static final int PRESENTIDENT = 20; - public static final int OPERATIONID = 22; - public static final int OPERATIONDATA = 24; - - // DCE/RPC header constants - - private static final byte VAL_VERSIONMAJOR = 5; - private static final byte VAL_VERSIONMINOR = 0; - private static final int VAL_PACKEDDATAREP = 0x00000010; - - // Data alignment types - - public final static int ALIGN_NONE = -1; - public final static int ALIGN_SHORT = 0; - public final static int ALIGN_INT = 1; - public final static int ALIGN_LONG = 2; - - // Maximum string length - - public final static int MAX_STRING_LEN = 1000; - - // Alignment masks and rounding - - private final static int[] _alignMask = { 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8 }; - private final static int[] _alignRound = { 1, 3, 7 }; - - // Default buffer allocation - - private static final int DEFAULT_BUFSIZE = 8192; - - // Maximum buffer size, used when the buffer is reset to release large buffers - - private static final int MAX_BUFFER_SIZE = 65536; - - // Dummy address value to use for pointers within the buffer - - private static final int DUMMY_ADDRESS = 0x12345678; - - // Data buffer and current read/write positions - - private byte[] m_buffer; - private int m_base; - private int m_pos; - private int m_rdpos; - - // Error status - - private int m_errorCode; - - /** - * Default constructor - */ - public DCEBuffer() - { - m_buffer = new byte[DEFAULT_BUFSIZE]; - m_pos = 0; - m_rdpos = 0; - m_base = 0; - } - - /** - * Class constructor - * - * @param siz int - */ - public DCEBuffer(int siz) - { - m_buffer = new byte[siz]; - m_pos = 0; - m_rdpos = 0; - m_base = 0; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param startPos int - * @param len int - */ - public DCEBuffer(byte[] buf, int startPos, int len) - { - m_buffer = buf; - m_pos = startPos + len; - m_rdpos = startPos; - m_base = startPos; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param startPos int - */ - public DCEBuffer(byte[] buf, int startPos) - { - m_buffer = buf; - m_pos = startPos; - m_rdpos = startPos; - m_base = startPos; - } - - /** - * Class constructor - * - * @param tbuf TransactBuffer - */ - public DCEBuffer(TransactBuffer tbuf) - { - DataBuffer dataBuf = tbuf.getDataBuffer(); - m_buffer = dataBuf.getBuffer(); - m_rdpos = dataBuf.getOffset(); - m_base = dataBuf.getOffset(); - m_pos = m_rdpos + dataBuf.getLength(); - } - - /** - * Return the DCE buffer - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_buffer; - } - - /** - * Return the current used buffer length - * - * @return int - */ - public final int getLength() - { - return m_pos; - } - - /** - * Return the read buffer position - * - * @return int - */ - public final int getReadPosition() - { - return m_rdpos; - } - - /** - * Return the write buffer position - * - * @return int - */ - public final int getWritePosition() - { - return m_pos; - } - - /** - * Return the amount of data left to read - * - * @return int - */ - public final int getAvailableLength() - { - return m_pos - m_rdpos; - } - - /** - * Get a byte from the buffer - * - * @param align int - * @return int - * @exception DCEBufferException - */ - public final int getByte(int align) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 1) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the integer value - - int bval = (int) (m_buffer[m_rdpos++] & 0xFF); - alignRxPosition(align); - return bval; - } - - /** - * Get a block of bytes from the buffer - * - * @param buf byte[] - * @param len int - * @return byte[] - * @throws DCEBufferException - */ - public final byte[] getBytes(byte[] buf, int len) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < len) - throw new DCEBufferException("End of DCE buffer"); - - // Check if a return buffer should be allocated - - if (buf == null) - buf = new byte[len]; - - // Unpack the bytes - - for (int i = 0; i < len; i++) - buf[i] = m_buffer[m_rdpos++]; - return buf; - } - - /** - * Get a short from the buffer - * - * @return int - * @exception DCEBufferException - */ - public final int getShort() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 2) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the integer value - - int sval = (int) DataPacker.getIntelShort(m_buffer, m_rdpos); - m_rdpos += 2; - return sval; - } - - /** - * Get a short from the buffer and align the read pointer - * - * @param align int - * @return int - * @exception DCEBufferException - */ - public final int getShort(int align) throws DCEBufferException - { - - // Read the short - - int sval = getShort(); - - // Align the read position - - alignRxPosition(align); - - // Return the short value - - return sval; - } - - /** - * Get an integer from the buffer - * - * @return int - * @exception DCEBufferException - */ - public final int getInt() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 4) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the integer value - - int ival = DataPacker.getIntelInt(m_buffer, m_rdpos); - m_rdpos += 4; - return ival; - } - - /** - * Get a pointer from the buffer - * - * @return int - * @exception DCEBufferException - */ - public final int getPointer() throws DCEBufferException - { - return getInt(); - } - - /** - * Get a pointer from the buffer and return either an empty string if the pointer is valid or - * null. - * - * @return String - * @exception DCEBufferException - */ - public final String getStringPointer() throws DCEBufferException - { - if (getInt() == 0) - return null; - return ""; - } - - /** - * Get a character array header from the buffer and return either an empty string if the pointer - * is valid or null. - * - * @return String - * @exception DCEBufferException - */ - public final String getCharArrayPointer() throws DCEBufferException - { - - // Get the array length and size - - int len = getShort(); - int siz = getShort(); - return getStringPointer(); - } - - /** - * Get a character array from the buffer if the String variable is not null, and align on the - * specified boundary - * - * @param strVar String - * @param align int - * @return String - * @exception DCEBufferException - */ - public final String getCharArrayNotNull(String strVar, int align) throws DCEBufferException - { - - // Check if the string variable is not null - - String str = ""; - - if (strVar != null) - { - - // Read the string - - str = getCharArray(); - - // Align the read position - - alignRxPosition(align); - } - - // Return the string - - return str; - } - - /** - * Get a long (64 bit) value from the buffer - * - * @return long - * @exception DCEBufferException - */ - public final long getLong() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 8) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the integer value - - long lval = DataPacker.getIntelLong(m_buffer, m_rdpos); - m_rdpos += 8; - return lval; - } - - /** - * Return a DCE/RPC header value - * - * @param valTyp int - * @return int - */ - public final int getHeaderValue(int valTyp) - { - - int result = -1; - - switch (valTyp) - { - - // Version major - - case HDR_VERMAJOR: - result = (int) (m_buffer[m_base + VERSIONMAJOR] & 0xFF); - break; - - // Version minor - - case HDR_VERMINOR: - result = (int) (m_buffer[m_base + VERSIONMINOR] & 0xFF); - break; - - // PDU type - - case HDR_PDUTYPE: - result = (int) (m_buffer[m_base + PDUTYPE] & 0xFF); - break; - - // Flags - - case HDR_FLAGS: - result = (int) (m_buffer[m_base + HEADERFLAGS] & 0xFF); - break; - - // Data representation - - case HDR_DATAREP: - result = DataPacker.getIntelInt(m_buffer, m_base + VERSIONMINOR); - break; - - // Authorisation length - - case HDR_AUTHLEN: - result = DataPacker.getIntelInt(m_buffer, m_base + AUTHLEN); - break; - - // Fragment length - - case HDR_FRAGLEN: - result = DataPacker.getIntelInt(m_buffer, m_base + FRAGMENTLEN); - break; - - // Call id - - case HDR_CALLID: - result = DataPacker.getIntelInt(m_buffer, m_base + CALLID); - break; - - // Request allocation hint - - case HDR_ALLOCHINT: - result = DataPacker.getIntelInt(m_buffer, m_base + ALLOCATIONHINT); - break; - - // Request opcode - - case HDR_OPCODE: - result = DataPacker.getIntelShort(m_buffer, m_base + OPERATIONID); - break; - } - - // Return the header value - - return result; - } - - /** - * Set a DCE/RPC header value - * - * @param typ int - * @param val int - */ - public final void setHeaderValue(int typ, int val) - { - - switch (typ) - { - - // Version major - - case HDR_VERMAJOR: - m_buffer[m_base + VERSIONMAJOR] = (byte) (val & 0xFF); - break; - - // Version minor - - case HDR_VERMINOR: - m_buffer[m_base + VERSIONMINOR] = (byte) (val & 0xFF); - break; - - // PDU type - - case HDR_PDUTYPE: - m_buffer[m_base + PDUTYPE] = (byte) (val & 0xFF); - break; - - // Flags - - case HDR_FLAGS: - m_buffer[m_base + HEADERFLAGS] = (byte) (val & 0xFF); - break; - - // Data representation - - case HDR_DATAREP: - DataPacker.putIntelInt(val, m_buffer, m_base + PACKEDDATAREP); - break; - - // Authorisation length - - case HDR_AUTHLEN: - DataPacker.putIntelInt(val, m_buffer, m_base + AUTHLEN); - break; - - // Fragment length - - case HDR_FRAGLEN: - DataPacker.putIntelInt(val, m_buffer, m_base + FRAGMENTLEN); - break; - - // Call id - - case HDR_CALLID: - DataPacker.putIntelInt(val, m_buffer, m_base + CALLID); - break; - - // Request allocation hint - - case HDR_ALLOCHINT: - DataPacker.putIntelInt(val, m_buffer, m_base + ALLOCATIONHINT); - break; - - // Request opcode - - case HDR_OPCODE: - DataPacker.putIntelShort(val, m_buffer, m_base + OPERATIONID); - break; - } - } - - /** - * Determine if this is the first fragment - * - * @return boolean - */ - public final boolean isFirstFragment() - { - if ((getHeaderValue(HDR_FLAGS) & FLG_FIRSTFRAG) != 0) - return true; - return false; - } - - /** - * Determine if this is the last fragment - * - * @return boolean - */ - public final boolean isLastFragment() - { - if ((getHeaderValue(HDR_FLAGS) & FLG_LASTFRAG) != 0) - return true; - return false; - } - - /** - * Determine if this is the only fragment in the request - * - * @return boolean - */ - public final boolean isOnlyFragment() - { - if ((getHeaderValue(HDR_FLAGS) & FLG_ONLYFRAG) == FLG_ONLYFRAG) - return true; - return false; - } - - /** - * Check if the status indicates that there are more entries available - * - * @return boolean - */ - public final boolean hasMoreEntries() - { - return getStatusCode() == SMBStatus.Win32MoreEntries ? true : false; - } - - /** - * Check if the status indicates success - * - * @return boolean - */ - public final boolean hasSuccessStatus() - { - return getStatusCode() == SMBStatus.NTSuccess ? true : false; - } - - /** - * Skip over a number of bytes - * - * @param cnt int - * @exception DCEBufferException - */ - public final void skipBytes(int cnt) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < cnt) - throw new DCEBufferException("End of DCE buffer"); - - // Skip bytes - - m_rdpos += cnt; - } - - /** - * Skip over a pointer - * - * @exception DCEBufferException - */ - public final void skipPointer() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 4) - throw new DCEBufferException("End of DCE buffer"); - - // Skip the 32bit pointer value - - m_rdpos += 4; - } - - /** - * Set the read position - * - * @param pos int - * @exception DCEBufferException - */ - public final void positionAt(int pos) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length < pos) - throw new DCEBufferException("End of DCE buffer"); - - // Set the read position - - m_rdpos = pos; - } - - /** - * Get a number of Unicode characters from the buffer and return as a string - * - * @param len int - * @return String - * @exception DCEBufferException - */ - public final String getChars(int len) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < (len * 2)) - throw new DCEBufferException("End of DCE buffer"); - - // Build up the return string - - StringBuffer str = new StringBuffer(len); - char curChar; - - while (len-- > 0) - { - - // Get a Unicode character from the buffer - - curChar = (char) ((m_buffer[m_rdpos + 1] << 8) + m_buffer[m_rdpos]); - m_rdpos += 2; - - // Add the character to the string - - str.append(curChar); - } - - // Return the string - - return str.toString(); - } - - /** - * Get the status code from the end of the data block - * - * @return int - */ - public final int getStatusCode() - { - - // Read the integer value at the end of the buffer - - int ival = DataPacker.getIntelInt(m_buffer, m_pos - 4); - return ival; - } - - /** - * Get a string from the buffer - * - * @return String - * @exception DCEBufferException - */ - public final String getString() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 12) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the string - - int maxLen = getInt(); - skipBytes(4); // offset - int strLen = getInt(); - - String str = DataPacker.getUnicodeString(m_buffer, m_rdpos, strLen); - m_rdpos += (strLen * 2); - return str; - } - - /** - * Get a character array from the buffer - * - * @return String - * @exception DCEBufferException - */ - public final String getCharArray() throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 12) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the string - - int maxLen = getInt(); - skipBytes(4); // offset - int strLen = getInt(); // in unicode chars - - String str = null; - if (strLen > 0) - { - str = DataPacker.getUnicodeString(m_buffer, m_rdpos, strLen); - m_rdpos += (strLen * 2); - } - return str; - } - - /** - * Get a character array from the buffer and align on the specified boundary - * - * @param align int - * @return String - * @exception DCEBufferException - */ - public final String getCharArray(int align) throws DCEBufferException - { - - // Read the string - - String str = getCharArray(); - - // Align the read position - - alignRxPosition(align); - - // Return the string - - return str; - } - - /** - * Get a string from the buffer and align on the specified boundary - * - * @param align int - * @return String - * @exception DCEBufferException - */ - public final String getString(int align) throws DCEBufferException - { - - // Read the string - - String str = getString(); - - // Align the read position - - alignRxPosition(align); - - // Return the string - - return str; - } - - /** - * Get a string from the buffer if the String variable is not null, and align on the specified - * boundary - * - * @param strVar String - * @param align int - * @return String - * @exception DCEBufferException - */ - public final String getStringNotNull(String strVar, int align) throws DCEBufferException - { - - // Check if the string variable is not null - - String str = ""; - - if (strVar != null) - { - - // Read the string - - str = getString(); - - // Align the read position - - alignRxPosition(align); - } - - // Return the string - - return str; - } - - /** - * Get a string from a particular position in the buffer - * - * @param pos int - * @return String - * @exception DCEBufferException - */ - public final String getStringAt(int pos) throws DCEBufferException - { - - // Check if position is within the buffer - - if (m_buffer.length < pos) - throw new DCEBufferException("Buffer offset out of range, " + pos); - - // Unpack the string - - String str = DataPacker.getUnicodeString(m_buffer, pos, MAX_STRING_LEN); - return str; - } - - /** - * Read a Unicode string header and return the string length. -1 indicates a null pointer in the - * string header. - * - * @return int - * @exception DCEBufferException - */ - public final int getUnicodeHeaderLength() throws DCEBufferException - { - - // Check if there is enough data in the buffer for the Unicode header - - if (m_buffer.length - m_rdpos < 8) - throw new DCEBufferException("End of DCE buffer"); - - // Get the string length - - int len = (int) DataPacker.getIntelShort(m_buffer, m_rdpos); - m_rdpos += 4; // skip the max length too - int ptr = DataPacker.getIntelInt(m_buffer, m_rdpos); - m_rdpos += 4; - - // Check if the pointer is valid - - if (ptr == 0) - return -1; - return len; - } - - /** - * Get a unicode string from the current position in the buffer - * - * @return String - * @exception DCEBufferException - */ - public final String getUnicodeString() throws DCEBufferException - { - - // Check if there is any buffer to read - - if (m_buffer.length - m_rdpos <= 0) - throw new DCEBufferException("No more buffer"); - - // Unpack the string - - String str = DataPacker.getUnicodeString(m_buffer, m_rdpos, MAX_STRING_LEN); - if (str != null) - m_rdpos += (str.length() * 2) + 2; - return str; - } - - /** - * Get a data block from the buffer and align on the specified boundary - * - * @param align int - * @return byte[] - * @exception DCEBufferException - */ - public final byte[] getDataBlock(int align) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 12) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the data block - - int len = getInt(); - m_rdpos += 8; // skip undoc and max_len ints - - // Copy the raw data block - - byte[] dataBlk = null; - - if (len > 0) - { - - // Allocate the data block buffer - - dataBlk = new byte[len]; - - // Copy the raw data - - System.arraycopy(m_buffer, m_rdpos, dataBlk, 0, len); - } - - // Update the buffer position and align - - m_rdpos += len; - alignRxPosition(align); - return dataBlk; - } - - /** - * Get a UUID from the buffer - * - * @param readVer boolean - * @return UUID - * @exception DCEBufferException - */ - public final UUID getUUID(boolean readVer) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - int len = UUID.UUID_LENGTH_BINARY; - if (readVer == true) - len += 4; - - if (m_buffer.length - m_rdpos < len) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the UUID - - UUID uuid = new UUID(m_buffer, m_rdpos); - m_rdpos += UUID.UUID_LENGTH_BINARY; - - if (readVer == true) - { - int ver = getInt(); - uuid.setVersion(ver); - } - - return uuid; - } - - /** - * Get an NT 64bit time value. If the value is valid then convert to a Java time value - * - * @return long - * @throws DCEBufferException - */ - public final long getNTTime() throws DCEBufferException - { - - // Get the raw NT time value - - long ntTime = getLong(); - if (ntTime == 0 || ntTime == NTTime.InfiniteTime) - return ntTime; - - // Convert the time to a Java time value - - return NTTime.toJavaDate(ntTime); - } - - /** - * Get a byte structure that has a header - * - * @param buf byte[] - * @throws DCEBufferException - */ - public final byte[] getByteStructure(byte[] buf) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < 12) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the header - - int maxLen = getInt(); - skipBytes(4); // offset - int bytLen = getInt(); - - byte[] bytBuf = buf; - if (bytBuf.length < bytLen) - bytBuf = new byte[bytLen]; - return getBytes(bytBuf, bytLen); - } - - /** - * Get a handle from the buffer - * - * @param handle PolicyHandle - * @exception DCEBufferException - */ - public final void getHandle(PolicyHandle handle) throws DCEBufferException - { - - // Check if there is enough data in the buffer - - if (m_buffer.length - m_rdpos < PolicyHandle.POLICY_HANDLE_SIZE) - throw new DCEBufferException("End of DCE buffer"); - - // Unpack the policy handle - - m_rdpos = handle.loadPolicyHandle(m_buffer, m_rdpos); - } - - /** - * Copy data from the DCE buffer to the user buffer, and update the current read position. - * - * @param buf byte[] - * @param off int - * @param cnt int - * @return int - * @exception DCEBufferException - */ - public final int copyData(byte[] buf, int off, int cnt) throws DCEBufferException - { - - // Check if there is any more data to copy - - if (m_rdpos == m_pos) - return 0; - - // Calculate the amount of data to copy - - int siz = m_pos - m_rdpos; - if (siz > cnt) - siz = cnt; - - // Copy the data to the user buffer and update the current read position - - System.arraycopy(m_buffer, m_rdpos, buf, off, siz); - m_rdpos += siz; - - // Return the amount of data copied - - return siz; - } - - /** - * Append a raw data block to the buffer - * - * @param buf byte[] - * @param off int - * @param len int - * @exception DCEBufferException - */ - public final void appendData(byte[] buf, int off, int len) throws DCEBufferException - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < len) - extendBuffer(len); - - // Copy the data to the buffer and update the current write position - - System.arraycopy(buf, off, m_buffer, m_pos, len); - m_pos += len; - } - - /** - * Append an integer to the buffer - * - * @param ival int - */ - public final void putInt(int ival) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 4) - extendBuffer(); - - // Pack the integer value - - DataPacker.putIntelInt(ival, m_buffer, m_pos); - m_pos += 4; - } - - /** - * Append a byte value to the buffer - * - * @param bval int - */ - public final void putByte(int bval) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 1) - extendBuffer(); - - // Pack the short value - - m_buffer[m_pos++] = (byte) (bval & 0xFF); - } - - /** - * Append a byte value to the buffer and align to the specified boundary - * - * @param bval byte - * @param align int - */ - public final void putByte(byte bval, int align) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 1) - extendBuffer(); - - // Pack the short value - - m_buffer[m_pos++] = bval; - alignPosition(align); - } - - /** - * Append a byte value to the buffer and align to the specified boundary - * - * @param bval int - * @param align int - */ - public final void putByte(int bval, int align) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 1) - extendBuffer(); - - // Pack the short value - - m_buffer[m_pos++] = (byte) (bval & 0xFF); - alignPosition(align); - } - - /** - * Append a block of bytes to the buffer - * - * @param bval byte[] - * @param len int - */ - public final void putBytes(byte[] bval, int len) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < len) - extendBuffer(); - - // Pack the bytes - - for (int i = 0; i < len; i++) - m_buffer[m_pos++] = bval[i]; - } - - /** - * Append a block of bytes to the buffer - * - * @param bval byte[] - * @param len int - * @param align int - */ - public final void putBytes(byte[] bval, int len, int align) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < len) - extendBuffer(); - - // Pack the bytes - - for (int i = 0; i < len; i++) - m_buffer[m_pos++] = bval[i]; - - // Align the new buffer position - - alignPosition(align); - } - - /** - * Append a short value to the buffer - * - * @param sval int - */ - public final void putShort(int sval) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 2) - extendBuffer(); - - // Pack the short value - - DataPacker.putIntelShort(sval, m_buffer, m_pos); - m_pos += 2; - } - - /** - * Append a DCE string to the buffer - * - * @param str String - */ - public final void putString(String str) - { - - // Check if there is enough space in the buffer - - int reqLen = (str.length() * 2) + 24; - - if (m_buffer.length - m_pos < reqLen) - extendBuffer(reqLen); - - // Pack the string - - m_pos = DCEDataPacker.putDCEString(m_buffer, m_pos, str, false); - } - - /** - * Append a DCE string to the buffer and align to the specified boundary - * - * @param str String - * @param align int - */ - public final void putString(String str, int align) - { - - // Check if there is enough space in the buffer - - int reqLen = (str.length() * 2) + 24; - - if (m_buffer.length - m_pos < reqLen) - extendBuffer(reqLen); - - // Pack the string - - m_pos = DCEDataPacker.putDCEString(m_buffer, m_pos, str, false); - - // Align the new buffer position - - alignPosition(align); - } - - /** - * Append a DCE string to the buffer, specify whether the nul is included in the string length - * or not - * - * @param str String - * @param align int - * @param incNul boolean - */ - public final void putString(String str, int align, boolean incNul) - { - - // Check if there is enough space in the buffer - - int reqLen = (str.length() * 2) + 24; - if (incNul) - reqLen += 2; - - if (m_buffer.length - m_pos < reqLen) - extendBuffer(reqLen); - - // Pack the string - - m_pos = DCEDataPacker.putDCEString(m_buffer, m_pos, str, incNul); - - // Align the new buffer position - - alignPosition(align); - } - - /** - * Append string return buffer details. Some DCE/RPC requests incorrectly send output parameters - * as input. - * - * @param len int - * @param align int - */ - public final void putStringReturn(int len, int align) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 20) - extendBuffer(); - - // Pack the string return details - - DataPacker.putIntelInt(len, m_buffer, m_pos); - DataPacker.putZeros(m_buffer, m_pos + 4, 8); - DataPacker.putIntelInt(DUMMY_ADDRESS, m_buffer, m_pos + 12); - m_pos += 16; - - // Align the new buffer position - - alignPosition(align); - } - - /** - * Append a DCE string header to the buffer - * - * @param str String - * @param incNul boolean - */ - public final void putUnicodeHeader(String str, boolean incNul) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 8) - extendBuffer(); - - // Calculate the string length in bytes - - int sLen = 0; - if (str != null) - sLen = str.length() * 2; - - // Pack the string header - - if (str != null) - DataPacker.putIntelShort(incNul ? sLen + 2 : sLen, m_buffer, m_pos); - else - DataPacker.putIntelShort(0, m_buffer, m_pos); - - DataPacker.putIntelShort(sLen != 0 ? sLen + 2 : 0, m_buffer, m_pos + 2); - DataPacker.putIntelInt(str != null ? DUMMY_ADDRESS : 0, m_buffer, m_pos + 4); - - m_pos += 8; - } - - /** - * Append a Unicode return string header to the buffer. Some DCE/RPC requests incorrectly send - * output parameters as input. - * - * @param len int - */ - public final void putUnicodeReturn(int len) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 8) - extendBuffer(); - - // Pack the string header - - DataPacker.putIntelShort(0, m_buffer, m_pos); - DataPacker.putIntelShort(len, m_buffer, m_pos + 2); - DataPacker.putIntelInt(DUMMY_ADDRESS, m_buffer, m_pos + 4); - - m_pos += 8; - } - - /** - * Append a DCE string header to the buffer - * - * @param len int - * @param incNul boolean - */ - public final void putUnicodeHeader(int len) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 8) - extendBuffer(); - - // Calculate the string length in bytes - - int sLen = len * 2; - - // Pack the string header - - DataPacker.putIntelShort(sLen, m_buffer, m_pos); - DataPacker.putIntelShort(sLen + 2, m_buffer, m_pos + 2); - DataPacker.putIntelInt(sLen != 0 ? DUMMY_ADDRESS : 0, m_buffer, m_pos + 4); - - m_pos += 8; - } - - /** - * Append an ASCII string to the DCE buffer - * - * @param str String - * @param incNul boolean - */ - public final void putASCIIString(String str, boolean incNul) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < (str.length() + 1)) - extendBuffer(str.length() + 2); - - // Pack the string - - m_pos = DataPacker.putString(str, m_buffer, m_pos, incNul); - } - - /** - * Append an ASCII string to the DCE buffer, and align on the specified boundary - * - * @param str String - * @param incNul boolean - * @param align int - */ - public final void putASCIIString(String str, boolean incNul, int align) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < (str.length() + 1)) - extendBuffer(str.length() + 8); - - // Pack the string - - m_pos = DataPacker.putString(str, m_buffer, m_pos, incNul); - - // Align the buffer position - - alignPosition(align); - } - - /** - * Append a pointer to the buffer. - * - * @param obj Object - */ - public final void putPointer(Object obj) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 4) - extendBuffer(); - - // Check if the object is valid, if not then put a null pointer into the buffer - - if (obj == null) - DataPacker.putZeros(m_buffer, m_pos, 4); - else - DataPacker.putIntelInt(DUMMY_ADDRESS, m_buffer, m_pos); - m_pos += 4; - } - - /** - * Append a pointer to the buffer. - * - * @param notNull boolean - */ - public final void putPointer(boolean notNull) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 4) - extendBuffer(); - - // Check if the object is valid, if not then put a null pointer into the buffer - - if (notNull == false) - DataPacker.putZeros(m_buffer, m_pos, 4); - else - DataPacker.putIntelInt(DUMMY_ADDRESS, m_buffer, m_pos); - m_pos += 4; - } - - /** - * Append a UUID to the buffer - * - * @param uuid UUID - * @param writeVer boolean - */ - public final void putUUID(UUID uuid, boolean writeVer) - { - - // Check if there is enough space in the buffer - - int len = UUID.UUID_LENGTH_BINARY; - if (writeVer == true) - len += 4; - - if (m_buffer.length - m_pos < len) - extendBuffer(); - - // Pack the UUID - - m_pos = uuid.storeUUID(m_buffer, m_pos, writeVer); - } - - /** - * Append a policy handle to the buffer - * - * @param handle PolicyHandle - */ - public final void putHandle(PolicyHandle handle) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < PolicyHandle.POLICY_HANDLE_SIZE) - extendBuffer(PolicyHandle.POLICY_HANDLE_SIZE); - - // Pack the policy handle - - m_pos = handle.storePolicyHandle(m_buffer, m_pos); - } - - /** - * Append a DCE buffer to the current DCE buffer - * - * @param buf DCEBuffer - */ - public final void putBuffer(DCEBuffer buf) - { - try - { - appendData(buf.getBuffer(), buf.getReadPosition(), buf.getLength()); - } - catch (DCEBufferException ex) - { - } - } - - /** - * Append an error status to the buffer, also sets the error status value - * - * @param sts int - */ - public final void putErrorStatus(int sts) - { - - // Check if there is enough space in the buffer - - if (m_buffer.length - m_pos < 4) - extendBuffer(); - - // Pack the status value - - DataPacker.putIntelInt(sts, m_buffer, m_pos); - m_pos += 4; - - // Save the status value - - m_errorCode = sts; - } - - /** - * Append a DCE header to the buffer - * - * @param pdutyp int - * @param callid int - */ - public final void putHeader(int pdutyp, int callid) - { - m_buffer[m_pos++] = VAL_VERSIONMAJOR; - m_buffer[m_pos++] = VAL_VERSIONMINOR; - m_buffer[m_pos++] = (byte) (pdutyp & 0xFF); - m_buffer[m_pos++] = 0; - - DataPacker.putIntelInt(VAL_PACKEDDATAREP, m_buffer, m_pos); - m_pos += 4; - - DataPacker.putZeros(m_buffer, m_pos, 4); - m_pos += 4; - - DataPacker.putIntelInt(callid, m_buffer, m_pos); - m_pos += 4; - } - - /** - * Append a bind header to the buffer - * - * @param callid int - */ - public final void putBindHeader(int callid) - { - putHeader(DCECommand.BIND, callid); - } - - /** - * Append a bind acknowlegde header to the buffer - * - * @param callid int - */ - public final void putBindAckHeader(int callid) - { - putHeader(DCECommand.BINDACK, callid); - } - - /** - * Append a request header to the buffer - * - * @param callid int - * @param opcode int - * @param allocHint int - */ - public final void putRequestHeader(int callid, int opcode, int allocHint) - { - putHeader(DCECommand.REQUEST, callid); - DataPacker.putIntelInt(allocHint, m_buffer, m_pos); - m_pos += 4; - DataPacker.putZeros(m_buffer, m_pos, 2); - m_pos += 2; - DataPacker.putIntelShort(opcode, m_buffer, m_pos); - m_pos += 2; - } - - /** - * Append a response header to the buffer - * - * @param callid int - * @param allocHint int - */ - public final void putResponseHeader(int callid, int allocHint) - { - putHeader(DCECommand.RESPONSE, callid); - DataPacker.putIntelInt(allocHint, m_buffer, m_pos); - m_pos += 4; - DataPacker.putZeros(m_buffer, m_pos, 4); - m_pos += 4; - } - - /** - * Append zero integers to the buffer - * - * @param cnt int - */ - public final void putZeroInts(int cnt) - { - - // Check if there is enough space in the buffer - - int bytCnt = cnt * 4; - if (m_buffer.length - m_pos < bytCnt) - extendBuffer(bytCnt * 2); - - // Pack the zero integer values - - DataPacker.putZeros(m_buffer, m_pos, bytCnt); - m_pos += bytCnt; - } - - /** - * Reset the buffer pointers to reuse the buffer - */ - public final void resetBuffer() - { - - // Reset the read/write positions - - m_pos = 0; - m_rdpos = 0; - - // If the buffer is over sized release it and allocate a standard sized buffer - - if (m_buffer.length >= MAX_BUFFER_SIZE) - m_buffer = new byte[DEFAULT_BUFSIZE]; - } - - /** - * Set the new write position - * - * @param pos int - */ - public final void setWritePosition(int pos) - { - m_pos = pos; - } - - /** - * Update the write position by the specified amount - * - * @param len int - */ - public final void updateWritePosition(int len) - { - m_pos += len; - } - - /** - * Determine if there is an error status set - * - * @return boolean - */ - public final boolean hasErrorStatus() - { - return m_errorCode != 0 ? true : false; - } - - /** - * Return the error status code - * - * @return int - */ - public final int getErrorStatus() - { - return m_errorCode; - } - - /** - * Set the error status code - * - * @param sts int - */ - public final void setErrorStatus(int sts) - { - m_errorCode = sts; - } - - /** - * Extend the DCE buffer by the specified amount - * - * @param ext int - */ - private final void extendBuffer(int ext) - { - - // Create a new buffer of the required size - - byte[] newBuf = new byte[m_buffer.length + ext]; - - // Copy the data from the current buffer to the new buffer - - System.arraycopy(m_buffer, 0, newBuf, 0, m_buffer.length); - - // Set the new buffer to be the main buffer - - m_buffer = newBuf; - } - - /** - * Extend the DCE buffer, double the currently allocated buffer size - */ - private final void extendBuffer() - { - extendBuffer(m_buffer.length * 2); - } - - /** - * Align the current buffer position on the specified boundary - * - * @param align int - */ - private final void alignPosition(int align) - { - - // Range check the alignment - - if (align < 0 || align > 2) - return; - - // Align the buffer position on the required boundary - - m_pos = (m_pos + _alignRound[align]) & _alignMask[align]; - } - - /** - * Align the receive buffer position on the specified boundary - * - * @param align int - */ - private final void alignRxPosition(int align) - { - - // Range check the alignment - - if (align < 0 || align > 2 || m_rdpos >= m_buffer.length) - return; - - // Align the buffer position on the required boundary - - m_rdpos = (m_rdpos + _alignRound[align]) & _alignMask[align]; - } - - /** - * Dump the DCE buffered data - */ - public final void Dump() - { - int len = getLength(); - if (len == 0) - len = 24; - HexDump.Dump(getBuffer(), len, m_base); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEBufferException.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEBufferException.java deleted file mode 100644 index a197306013..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEBufferException.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * DCE Buffer Exception Class - */ -public class DCEBufferException extends Exception -{ - private static final long serialVersionUID = 3833460725724494132L; - - /** - * Class constructor - */ - public DCEBufferException() - { - super(); - } - - /** - * Class constructor - * - * @param str String - */ - public DCEBufferException(String str) - { - super(str); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCECommand.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCECommand.java deleted file mode 100644 index 05950d4e2d..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCECommand.java +++ /dev/null @@ -1,85 +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.smb.dcerpc; - -/** - * DCE/RPC Command Codes - */ -public class DCECommand -{ - - // DCE/RPC Packet Types - - public final static byte REQUEST = 0x00; - public final static byte RESPONSE = 0x02; - public final static byte FAULT = 0x03; - public final static byte BIND = 0x0B; - public final static byte BINDACK = 0x0C; - public final static byte ALTCONT = 0x0E; - public final static byte AUTH3 = 0x0F; - public final static byte BINDCONT = 0x10; - - /** - * Convert the command type to a string - * - * @param cmd int - * @return String - */ - public final static String getCommandString(int cmd) - { - - // Determine the PDU command type - - String ret = ""; - switch (cmd) - { - case REQUEST: - ret = "Request"; - break; - case RESPONSE: - ret = "Repsonse"; - break; - case FAULT: - ret = "Fault"; - break; - case BIND: - ret = "Bind"; - break; - case BINDACK: - ret = "BindAck"; - break; - case ALTCONT: - ret = "AltCont"; - break; - case AUTH3: - ret = "Auth3"; - break; - case BINDCONT: - ret = "BindCont"; - break; - } - return ret; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEDataPacker.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEDataPacker.java deleted file mode 100644 index cb17de9200..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEDataPacker.java +++ /dev/null @@ -1,109 +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.smb.dcerpc; - -import org.alfresco.filesys.util.DataPacker; - -/** - * DCE Data Packer Class - */ -public class DCEDataPacker -{ - - /** - * Unpack a DCE string from the buffer - * - * @param buf byte[] - * @param off int - * @return String - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static String getDCEString(byte[] buf, int off) throws IndexOutOfBoundsException - { - - // Check if the buffer is big enough to hold the String header - - if (buf.length < off + 12) - throw new IndexOutOfBoundsException(); - - // Get the maximum and actual string length - - int maxLen = DataPacker.getIntelInt(buf, off); - int strLen = DataPacker.getIntelInt(buf, off + 8); - - // Read the Unicode string - - return DataPacker.getUnicodeString(buf, off + 12, strLen); - } - - /** - * Pack a DCE string into the buffer - * - * @param buf byte[] - * @param off int - * @param str String - * @param incNul boolean - * @return int - */ - public final static int putDCEString(byte[] buf, int off, String str, boolean incNul) - { - - // Pack the string header - - DataPacker.putIntelInt(str.length() + 1, buf, off); - DataPacker.putZeros(buf, off + 4, 4); - - if (incNul == false) - DataPacker.putIntelInt(str.length(), buf, off + 8); - else - DataPacker.putIntelInt(str.length() + 1, buf, off + 8); - - // Pack the string - - return DataPacker.putUnicodeString(str, buf, off + 12, incNul); - } - - /** - * Align a buffer offset on a longword boundary - * - * @param pos int - * @return int - */ - public final static int wordAlign(int pos) - { - return (pos + 1) & 0xFFFFFFFE; - } - - /** - * Align a buffer offset on a longword boundary - * - * @param pos int - * @return int - */ - public final static int longwordAlign(int pos) - { - return (pos + 3) & 0xFFFFFFFC; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEException.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEException.java deleted file mode 100644 index 5b041b7bef..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEException.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * DCE/RPC Exception Class - */ -public class DCEException extends Exception -{ - private static final long serialVersionUID = 3258688788954625072L; - - /** - * Class constructor - * - * @param str String - */ - public DCEException(String str) - { - super(str); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEList.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEList.java deleted file mode 100644 index da840d7d79..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEList.java +++ /dev/null @@ -1,340 +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.smb.dcerpc; - -import java.util.Vector; - -/** - * DCE/RPC List Class - *

- * Base class for lists of objects that are DCE/RPC readable and/or writeable. - */ -public abstract class DCEList -{ - - // Information level - - private int m_infoLevel; - - // List of DCE/RPC readable/writeable objects - - private Vector m_dceObjects; - - /** - * Default constructor - */ - protected DCEList() - { - m_dceObjects = new Vector(); - } - - /** - * Class constructor - * - * @param infoLevel int - */ - protected DCEList(int infoLevel) - { - m_dceObjects = new Vector(); - m_infoLevel = infoLevel; - } - - /** - * Class constructor - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - protected DCEList(DCEBuffer buf) throws DCEBufferException - { - - // Read the header from the DCE/RPC buffer that contains the information level and container - // pointer - - m_infoLevel = buf.getInt(); - buf.skipBytes(4); - - if (buf.getPointer() != 0) - { - - // Indicate that the container is valid - - m_dceObjects = new Vector(); - } - else - { - - // Container is not valid, no more data to follow - - m_dceObjects = null; - } - } - - /** - * Return the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Return the number of entries in the list - * - * @return int - */ - public final int numberOfEntries() - { - return m_dceObjects != null ? m_dceObjects.size() : 0; - } - - /** - * Return the object list - * - * @return Vector - */ - public final Vector getList() - { - return m_dceObjects; - } - - /** - * Return an element from the list - * - * @param idx int - * @return Object - */ - public final Object getElement(int idx) - { - - // Range check the index - - if (m_dceObjects == null || idx < 0 || idx >= m_dceObjects.size()) - return null; - - // Return the object - - return m_dceObjects.elementAt(idx); - } - - /** - * Determine if the container is valid - * - * @return boolean - */ - protected final boolean containerIsValid() - { - return m_dceObjects != null ? true : false; - } - - /** - * Add an object to the list - * - * @param obj Object - */ - protected final void addObject(Object obj) - { - m_dceObjects.addElement(obj); - } - - /** - * Set the information level - * - * @param infoLevel int - */ - protected final void setInformationLevel(int infoLevel) - { - m_infoLevel = infoLevel; - } - - /** - * Set the object list - * - * @param list Vector - */ - protected final void setList(Vector list) - { - m_dceObjects = list; - } - - /** - * Get a new object for the list to fill in - * - * @return DCEReadable - */ - protected abstract DCEReadable getNewObject(); - - /** - * Read a list of objects from the DCE buffer - * - * @param buf DCEBuffer - * @throws DCEBufferException - */ - public void readList(DCEBuffer buf) throws DCEBufferException - { - - // Check if the container is valid, if so the object list will be valid - - if (containerIsValid() == false) - return; - - // Read the container object count and array pointer - - int numEntries = buf.getInt(); - if (buf.getPointer() != 0) - { - - // Get the array element count - - int elemCnt = buf.getInt(); - - if (elemCnt > 0) - { - - // Read in the array elements - - while (elemCnt-- > 0) - { - - // Create a readable object and add to the list - - DCEReadable element = getNewObject(); - addObject(element); - - // Load the main object details - - element.readObject(buf); - } - - // Load the strings for the readable information objects - - for (int i = 0; i < numberOfEntries(); i++) - { - - // Get a readable object - - DCEReadable element = (DCEReadable) getList().elementAt(i); - - // Load the strings for the readable object - - element.readStrings(buf); - } - } - } - } - - /** - * Write the list of objects to a DCE buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public final void writeList(DCEBuffer buf) throws DCEBufferException - { - - // Pack the container header - - buf.putInt(getInformationLevel()); - buf.putInt(getInformationLevel()); - - // Check if the object list is valid - - if (m_dceObjects != null) - { - - // Add a pointer to the container and the number of objects - - buf.putPointer(true); - buf.putInt(m_dceObjects.size()); - - // Add the pointer to the array of objects and number of objects - - buf.putPointer(true); - buf.putInt(m_dceObjects.size()); - - // Create a seperate DCE buffer to build the string list which may follow the main - // object list, depending on the object - - DCEBuffer strBuf = new DCEBuffer(); - - // Pack the object information - - for (int i = 0; i < m_dceObjects.size(); i++) - { - - // Get an object from the list - - DCEWriteable object = (DCEWriteable) m_dceObjects.elementAt(i); - - // Write the object to the buffer, strings may go into the seperate string buffer - // which will be appended - // to the main buffer after all the objects have been written - - object.writeObject(buf, strBuf); - } - - // If the string buffer has been used append it to the main buffer - - buf.putBuffer(strBuf); - - // Add the trailing list size - - buf.putInt(m_dceObjects.size()); - - // Add the enum handle - - buf.putInt(0); - } - else - { - - // Add an empty container/array - - buf.putZeroInts(4); - } - } - - /** - * Return the list as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("[Level="); - str.append(getInformationLevel()); - str.append(",Entries="); - str.append(numberOfEntries()); - str.append(",Class="); - str.append(getNewObject().getClass().getName()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEPipeType.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEPipeType.java deleted file mode 100644 index d5508b5503..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEPipeType.java +++ /dev/null @@ -1,196 +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.smb.dcerpc; - -/** - *

- * Defines the special DCE/RPC pipe names. - */ -public class DCEPipeType -{ - - // IPC$ client pipe names - - private static final String[] _pipeNames = { "\\PIPE\\srvsvc", - "\\PIPE\\samr", - "\\PIPE\\winreg", - "\\PIPE\\wkssvc", - "\\PIPE\\NETLOGON", - "\\PIPE\\lsarpc", - "\\PIPE\\spoolss", - "\\PIPE\\netdfs", - "\\PIPE\\svcctl", - "\\PIPE\\EVENTLOG", - "\\PIPE\\NETLOGON" - }; - - // IPC$ server pipe names - - private static final String[] _srvNames = { "\\PIPE\\ntsvcs", - "\\PIPE\\lsass", - "\\PIPE\\winreg", - "\\PIPE\\ntsvcs", - "\\PIPE\\lsass", - "\\PIPE\\lsass", - "\\PIPE\\spoolss", - "\\PIPE\\netdfs", - "\\PIPE\\svcctl", - "\\PIPE\\EVENTLOG" - }; - - // IPC$ pipe ids - - public static final int PIPE_SRVSVC = 0; - public static final int PIPE_SAMR = 1; - public static final int PIPE_WINREG = 2; - public static final int PIPE_WKSSVC = 3; - public static final int PIPE_NETLOGON = 4; - public static final int PIPE_LSARPC = 5; - public static final int PIPE_SPOOLSS = 6; - public static final int PIPE_NETDFS = 7; - public static final int PIPE_SVCCTL = 8; - public static final int PIPE_EVENTLOG = 9; - public static final int PIPE_NETLOGON1= 10; - - // IPC$ pipe UUIDs - - private static UUID _uuidNetLogon = new UUID("8a885d04-1ceb-11c9-9fe8-08002b104860", 2); - private static UUID _uuidWinReg = new UUID("338cd001-2244-31f1-aaaa-900038001003", 1); - private static UUID _uuidSvcCtl = new UUID("367abb81-9844-35f1-ad32-98f038001003", 2); - private static UUID _uuidLsaRpc = new UUID("12345678-1234-abcd-ef00-0123456789ab", 0); - private static UUID _uuidSrvSvc = new UUID("4b324fc8-1670-01d3-1278-5a47bf6ee188", 3); - private static UUID _uuidWksSvc = new UUID("6bffd098-a112-3610-9833-46c3f87e345a", 1); - private static UUID _uuidSamr = new UUID("12345778-1234-abcd-ef00-0123456789ac", 1); - private static UUID _uuidSpoolss = new UUID("12345778-1234-abcd-ef00-0123456789ab", 1); - private static UUID _uuidSvcctl = new UUID("367abb81-9844-35f1-ad32-98f038001003", 2); - private static UUID _uuidEventLog = new UUID("82273FDC-E32A-18C3-3F78-827929DC23EA", 0); - private static UUID _uuidNetLogon1= new UUID("12345678-1234-abcd-ef00-01234567cffb", 1); - -// private static UUID _uuidAtSvc = new UUID("1ff70682-0a51-30e8-076d-740be8cee98b", 1); - - /** - * Convert a pipe name to a type - * - * @param name String - * @return int - */ - public final static int getNameAsType(String name) - { - for (int i = 0; i < _pipeNames.length; i++) - { - if (_pipeNames[i].equals(name)) - return i; - } - return -1; - } - - /** - * Convert a pipe type to a name - * - * @param typ int - * @return String - */ - public final static String getTypeAsString(int typ) - { - if (typ >= 0 && typ < _pipeNames.length) - return _pipeNames[typ]; - return null; - } - - /** - * Convert a pipe type to a short name - * - * @param typ int - * @return String - */ - public final static String getTypeAsStringShort(int typ) - { - if (typ >= 0 && typ < _pipeNames.length) - { - String name = _pipeNames[typ]; - return name.substring(5); - } - return null; - } - - /** - * Return the UUID for the pipe type - * - * @param typ int - * @return UUID - */ - public final static UUID getUUIDForType(int typ) - { - UUID ret = null; - - switch (typ) - { - case PIPE_NETLOGON: - ret = _uuidNetLogon; - break; - case PIPE_NETLOGON1: - ret = _uuidNetLogon1; - break; - case PIPE_WINREG: - ret = _uuidWinReg; - break; - case PIPE_LSARPC: - ret = _uuidLsaRpc; - break; - case PIPE_WKSSVC: - ret = _uuidWksSvc; - break; - case PIPE_SAMR: - ret = _uuidSamr; - break; - case PIPE_SRVSVC: - ret = _uuidSrvSvc; - break; - case PIPE_SPOOLSS: - ret = _uuidSpoolss; - break; - case PIPE_SVCCTL: - ret = _uuidSvcCtl; - break; - case PIPE_EVENTLOG: - ret = _uuidEventLog; - break; - } - return ret; - } - - /** - * Get the server-side pipe name for the specified pipe - * - * @param typ int - * @return String - */ - public final static String getServerPipeName(int typ) - { - if (typ >= 0 && typ < _srvNames.length) - return _srvNames[typ]; - return null; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadable.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadable.java deleted file mode 100644 index 73c15ca08d..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadable.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * DCE/RPC Readable Interface - *

- * A class that implements the DCEReadable interface can load itself from a DCE buffer. - */ -public interface DCEReadable -{ - - /** - * Read the object state from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException; - - /** - * Read the strings for object from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readStrings(DCEBuffer buf) throws DCEBufferException; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadableList.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadableList.java deleted file mode 100644 index 8e6c93742a..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEReadableList.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * DCE/RPC Readable List Interface - *

- * A class that implements the DCEReadableList interface can read a list of DCEReadable objects from - * a DCE/RPC buffer. - */ -public interface DCEReadableList -{ - - /** - * Read the object state from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteable.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteable.java deleted file mode 100644 index db5232032b..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteable.java +++ /dev/null @@ -1,49 +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.smb.dcerpc; - -/** - * DCE/RPC Writeable Interface - *

- * A class that implements the DCEWriteable interface can save itself to a DCE buffer. - */ -public interface DCEWriteable -{ - - /** - * Write the object state to DCE/RPC buffers. - *

- * If a list of objects is being written the strings will be written after the objects so the - * second buffer will be specified. - *

- * If a single object is being written to the buffer the second buffer may be null or be the - * same buffer as the main buffer. - * - * @param buf DCEBuffer - * @param strBuf DCEBuffer - * @exception DCEBufferException - */ - public void writeObject(DCEBuffer buf, DCEBuffer strBuf) throws DCEBufferException; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteableList.java b/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteableList.java deleted file mode 100644 index d997062a0f..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/DCEWriteableList.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * DCE/RPC Writeable List Interface - *

- * A class that implements the DCEWriteableList interface can write a list of DCEWriteable objects - * to a DCE/RPC buffer. - */ -public interface DCEWriteableList -{ - - /** - * Write the object state to DCE/RPC buffers. - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void writeObject(DCEBuffer buf) throws DCEBufferException; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandle.java b/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandle.java deleted file mode 100644 index 435cae232a..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandle.java +++ /dev/null @@ -1,223 +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.smb.dcerpc; - -/** - * Policy Handle Class - */ -public class PolicyHandle -{ - - // Length of a policy handle - - public static final int POLICY_HANDLE_SIZE = 20; - - // Policy handle bytes - - private byte[] m_handle; - - // Handle name - - private String m_name; - - /** - * Default constructor - */ - public PolicyHandle() - { - setName(""); - } - - /** - * Class constructor - * - * @param buf byte[] - * @param off int - */ - public PolicyHandle(byte[] buf, int off) - { - initialize(buf, off); - setName(""); - } - - /** - * Class constructor - * - * @param name String - * @param buf byte[] - * @param off int - */ - public PolicyHandle(String name, byte[] buf, int off) - { - initialize(buf, off); - setName(name); - } - - /** - * Determine if the policy handle is valid - * - * @return boolean - */ - public final boolean isValid() - { - return m_handle != null ? true : false; - } - - /** - * Return the policy handle bytes - * - * @return byte[] - */ - public final byte[] getBytes() - { - return m_handle; - } - - /** - * Return the policy handle name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Set the policy handle name - * - * @param name String - */ - public final void setName(String name) - { - m_name = name; - } - - /** - * Store the policy handle into the specified buffer - * - * @param buf byte[] - * @param off int - * @return int - */ - public final int storePolicyHandle(byte[] buf, int off) - { - - // Check if the policy handle is valid - - if (isValid() == false) - return -1; - - // Copy the policy handle bytes to the user buffer - - for (int i = 0; i < POLICY_HANDLE_SIZE; i++) - buf[off + i] = m_handle[i]; - - // Return the new buffer position - - return off + POLICY_HANDLE_SIZE; - } - - /** - * Load the policy handle from the specified buffer - * - * @param buf byte[] - * @param off int - * @return int - */ - public final int loadPolicyHandle(byte[] buf, int off) - { - - // Load the policy handle from the buffer - - initialize(buf, off); - return off + POLICY_HANDLE_SIZE; - } - - /** - * Clear the handle - */ - protected final void clearHandle() - { - m_handle = null; - } - - /** - * Initialize the policy handle - * - * @param buf byte[] - * @param off int - */ - private final void initialize(byte[] buf, int off) - { - - // Copy the policy handle bytes - - if ((off + POLICY_HANDLE_SIZE) <= buf.length) - { - - // Allocate the policy handle buffer - - m_handle = new byte[POLICY_HANDLE_SIZE]; - - // Copy the policy handle - - for (int i = 0; i < POLICY_HANDLE_SIZE; i++) - m_handle[i] = buf[off + i]; - } - } - - /** - * Return the policy handle as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - - if (getName() != null) - str.append(getName()); - str.append(":"); - - if (isValid()) - { - for (int i = 0; i < POLICY_HANDLE_SIZE; i++) - { - int val = (int) (m_handle[i] & 0xFF); - if (val <= 16) - str.append("0"); - str.append(Integer.toHexString(val).toUpperCase()); - str.append("-"); - } - str.setLength(str.length() - 1); - str.append("]"); - } - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandleCache.java b/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandleCache.java deleted file mode 100644 index dd17153a09..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/PolicyHandleCache.java +++ /dev/null @@ -1,108 +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.smb.dcerpc; - -import java.util.Enumeration; -import java.util.Hashtable; - -/** - * Policy Handle Cache Class - */ -public class PolicyHandleCache -{ - - // Policy handles - - private Hashtable m_cache; - - /** - * Default constructor - */ - public PolicyHandleCache() - { - m_cache = new Hashtable(); - } - - /** - * Return the number of handles in the cache - * - * @return int - */ - public final int numberOfHandles() - { - return m_cache.size(); - } - - /** - * Add a handle to the cache - * - * @param name String - * @param handle PolicyHandle - */ - public final void addHandle(String name, PolicyHandle handle) - { - m_cache.put(name, handle); - } - - /** - * Return the handle for the specified index - * - * @param index String - * @return PolicyHandle - */ - public final PolicyHandle findHandle(String index) - { - return m_cache.get(index); - } - - /** - * Delete a handle from the cache - * - * @param index String - * @return PolicyHandle - */ - public final PolicyHandle removeHandle(String index) - { - return m_cache.remove(index); - } - - /** - * Enumerate the handles in the cache - * - * @return Enumeration - */ - public final Enumeration enumerateHandles() - { - return m_cache.elements(); - } - - /** - * Clear all handles from the cache - */ - public final void removeAllHandles() - { - m_cache.clear(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/Srvsvc.java b/source/java/org/alfresco/filesys/smb/dcerpc/Srvsvc.java deleted file mode 100644 index db6883a16a..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/Srvsvc.java +++ /dev/null @@ -1,103 +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.smb.dcerpc; - -/** - * Srvsvc Operation Ids Class - */ -public class Srvsvc -{ - - // Srvsvc opcodes - - public static final int NetrServerGetInfo = 0x15; - public static final int NetrServerSetInfo = 0x16; - public static final int NetrShareEnum = 0x0F; - public static final int NetrShareEnumSticky = 0x24; - public static final int NetrShareGetInfo = 0x10; - public static final int NetrShareSetInfo = 0x11; - public static final int NetrShareAdd = 0x0E; - public static final int NetrShareDel = 0x12; - public static final int NetrSessionEnum = 0x0C; - public static final int NetrSessionDel = 0x0D; - public static final int NetrConnectionEnum = 0x08; - public static final int NetrFileEnum = 0x09; - public static final int NetrRemoteTOD = 0x1C; - - /** - * Convert an opcode to a function name - * - * @param opCode int - * @return String - */ - public final static String getOpcodeName(int opCode) - { - - String ret = ""; - switch (opCode) - { - case NetrServerGetInfo: - ret = "NetrServerGetInfo"; - break; - case NetrServerSetInfo: - ret = "NetrServerSetInfo"; - break; - case NetrShareEnum: - ret = "NetrShareEnum"; - break; - case NetrShareEnumSticky: - ret = "NetrShareEnumSticky"; - break; - case NetrShareGetInfo: - ret = "NetrShareGetInfo"; - break; - case NetrShareSetInfo: - ret = "NetrShareSetInfo"; - break; - case NetrShareAdd: - ret = "NetrShareAdd"; - break; - case NetrShareDel: - ret = "NetrShareDel"; - break; - case NetrSessionEnum: - ret = "NetrSessionEnum"; - break; - case NetrSessionDel: - ret = "NetrSessionDel"; - break; - case NetrConnectionEnum: - ret = "NetrConnectionEnum"; - break; - case NetrFileEnum: - ret = "NetrFileEnum"; - break; - case NetrRemoteTOD: - ret = "NetrRemoteTOD"; - break; - } - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/UUID.java b/source/java/org/alfresco/filesys/smb/dcerpc/UUID.java deleted file mode 100644 index ee21c944c6..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/UUID.java +++ /dev/null @@ -1,415 +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.smb.dcerpc; - -import org.alfresco.filesys.util.DataPacker; - -/** - * Universal Unique Identifier Class - */ -public class UUID -{ - - // UUID constants - - public static final int UUID_LENGTH = 36; - public static final int UUID_LENGTH_BINARY = 16; - private static final String UUID_VALIDCHARS = "0123456789ABCDEFabcdef"; - - // UUID string - - private String m_uuid; - - // Interface version - - private int m_ifVersion; - - // UUID bytes - - private byte[] m_uuidBytes; - - /** - * Class constructor - * - * @param id String - */ - public UUID(String id) - { - if (validateUUID(id)) - { - m_uuid = id; - m_ifVersion = 1; - } - } - - /** - * Class constructor - * - * @param id String - * @param ver int - */ - public UUID(String id, int ver) - { - if (validateUUID(id)) - { - m_uuid = id; - m_ifVersion = ver; - } - } - - /** - * Class constructor - * - * @param buf byte[] - * @param off int - */ - public UUID(byte[] buf, int off) - { - - // Copy the UUID bytes and generate the UUID string - - if ((off + UUID_LENGTH_BINARY) <= buf.length) - { - - // Take a copy of the UUID bytes - - m_uuidBytes = new byte[UUID_LENGTH_BINARY]; - for (int i = 0; i < UUID_LENGTH_BINARY; i++) - m_uuidBytes[i] = buf[off + i]; - - // Generate the string version of the UUID - - m_uuid = generateUUIDString(m_uuidBytes); - } - } - - /** - * Determine if the UUID is valid - * - * @return boolean - */ - public final boolean isValid() - { - return m_uuid != null ? true : false; - } - - /** - * Return the UUID string - * - * @return String - */ - public final String getUUID() - { - return m_uuid; - } - - /** - * Return the interface version - * - * @return int - */ - public final int getVersion() - { - return m_ifVersion; - } - - /** - * Set the interface version - * - * @param ver int - */ - public final void setVersion(int ver) - { - m_ifVersion = ver; - } - - /** - * Return the UUID as a byte array - * - * @return byte[] - */ - public final byte[] getBytes() - { - - // Check if the byte array has been created - - if (m_uuidBytes == null) - { - - // Allocate the byte array - - m_uuidBytes = new byte[UUID_LENGTH_BINARY]; - - try - { - - // Convert the first integer and pack into the buffer - - String val = m_uuid.substring(0, 8); - long lval = Long.parseLong(val, 16); - DataPacker.putIntelInt((int) (lval & 0xFFFFFFFF), m_uuidBytes, 0); - - // Convert the second word and pack into the buffer - - val = m_uuid.substring(9, 13); - int ival = Integer.parseInt(val, 16); - DataPacker.putIntelShort(ival, m_uuidBytes, 4); - - // Convert the third word and pack into the buffer - - val = m_uuid.substring(14, 18); - ival = Integer.parseInt(val, 16); - DataPacker.putIntelShort(ival, m_uuidBytes, 6); - - // Convert the fourth word and pack into the buffer - - val = m_uuid.substring(19, 23); - ival = Integer.parseInt(val, 16); - DataPacker.putShort((short) (ival & 0xFFFF), m_uuidBytes, 8); - - // Convert the final block of hex pairs to bytes - - int strPos = 24; - int bytPos = 10; - - for (int i = 0; i < 6; i++) - { - val = m_uuid.substring(strPos, strPos + 2); - m_uuidBytes[bytPos++] = (byte) (Short.parseShort(val, 16) & 0xFF); - strPos += 2; - } - } - catch (NumberFormatException ex) - { - m_uuidBytes = null; - } - } - - // Return the UUID bytes - - return m_uuidBytes; - } - - /** - * Validate a UUID string - * - * @param idStr String - * @reutrn boolean - */ - public static final boolean validateUUID(String idStr) - { - - // Check if the UUID string is the correct length - - if (idStr == null || idStr.length() != UUID_LENGTH) - return false; - - // Check for seperators - - if (idStr.charAt(8) != '-' || idStr.charAt(13) != '-' || idStr.charAt(18) != '-' || idStr.charAt(23) != '-') - return false; - - // Check for hex digits - - int i = 0; - for (i = 0; i < 8; i++) - if (UUID_VALIDCHARS.indexOf(idStr.charAt(i)) == -1) - return false; - for (i = 9; i < 13; i++) - if (UUID_VALIDCHARS.indexOf(idStr.charAt(i)) == -1) - return false; - for (i = 14; i < 18; i++) - if (UUID_VALIDCHARS.indexOf(idStr.charAt(i)) == -1) - return false; - for (i = 19; i < 23; i++) - if (UUID_VALIDCHARS.indexOf(idStr.charAt(i)) == -1) - return false; - for (i = 24; i < 36; i++) - if (UUID_VALIDCHARS.indexOf(idStr.charAt(i)) == -1) - return false; - - // Valid UUID string - - return true; - } - - /** - * Generate a UUID string from the binary representation - * - * @param buf byte[] - * @return String - */ - public static final String generateUUIDString(byte[] buf) - { - - // Build up the UUID string - - StringBuffer str = new StringBuffer(UUID_LENGTH); - - // Convert the first longword - - int ival = DataPacker.getIntelInt(buf, 0); - str.append(Integer.toHexString(ival)); - while (str.length() != 8) - str.insert(0, ' '); - str.append("-"); - - // Convert the second word - - ival = DataPacker.getIntelShort(buf, 4) & 0xFFFF; - str.append(Integer.toHexString(ival)); - while (str.length() != 13) - str.insert(9, '0'); - str.append("-"); - - // Convert the third word - - ival = DataPacker.getIntelShort(buf, 6) & 0xFFFF; - str.append(Integer.toHexString(ival)); - while (str.length() != 18) - str.insert(14, '0'); - str.append("-"); - - // Convert the remaining bytes - - for (int i = 8; i < UUID_LENGTH_BINARY; i++) - { - - // Get the current byte value and add to the string - - ival = (int) (buf[i] & 0xFF); - if (ival < 16) - str.append('0'); - str.append(Integer.toHexString(ival)); - - // Add the final seperator - - if (i == 9) - str.append("-"); - } - - // Return the UUID string - - return str.toString(); - } - - /** - * Compare a UUID with the current UUID - * - * @param id UUID - * @return boolean - */ - public final boolean compareTo(UUID id) - { - - // Compare the UUID versions - - if (getVersion() != id.getVersion()) - return false; - - // Compare the UUID bytes - - byte[] thisBytes = getBytes(); - byte[] idBytes = id.getBytes(); - - for (int i = 0; i < UUID_LENGTH_BINARY; i++) - if (thisBytes[i] != idBytes[i]) - return false; - return true; - } - - /** - * Write the binary UUID to the specified buffer, and optionally the UUID version - * - * @param buf byte[] - * @param off int - * @param writeVer boolean - * @return int - */ - public final int storeUUID(byte[] buf, int off, boolean writeVer) - { - - // Get the UUID bytes - - int pos = off; - byte[] uuidByts = getBytes(); - if (uuidByts == null) - return pos; - - // Write the binary UUID to the buffer - - for (int i = 0; i < UUID_LENGTH_BINARY; i++) - buf[pos + i] = uuidByts[i]; - pos += UUID_LENGTH_BINARY; - - // Check if version should be written to the buffer - - if (writeVer) - { - DataPacker.putIntelInt(getVersion(), buf, pos); - pos += 4; - } - - // Return the new buffer position - - return pos; - } - - /** - * Return the UUID as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(m_uuid); - str.append(":"); - str.append(m_ifVersion); - str.append("]"); - - return str.toString(); - } - - /*********************************************************************************************** - * Test Code - * - * @param args String[] - */ - /** - * public final static void main(String[] args) { System.out.println("UUID Test"); - * System.out.println("---------"); String[] uuids = { "12345678-1234-abcd-ef00-01234567cffb", - * "8a885d04-1ceb-11c9-9fe8-08002b104860", "338cd001-2244-31f1-aaaa-900038001003", - * "367abb81-9844-35f1-ad32-98f038001003", "4b324fc8-1670-01d3-1278-5a47bf6ee188", - * "6bffd098-a112-3610-9833-46c3f87e345a", "12345678-1234-abcd-ef00-0123456789ac", - * "12345778-1234-abcd-ef00-0123456789ab", "1ff70682-0a51-30e8-076d-740be8cee98b" }; // Validate - * and convert the UUIDs for ( int i = 0; i < uuids.length; i++) { UUID u = new UUID(uuids[i]); - * if ( u.isValid()) { System.out.println("" + (i+1) + ": " + u.toString()); byte[] bytes = - * u.getBytes(); HexDump.Dump(bytes,bytes.length, 0); System.out.println("Convert to string: " + - * generateUUIDString(bytes)); } else System.out.println("Invalid UUID: " + uuids[i]); } } - */ -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/Wkssvc.java b/source/java/org/alfresco/filesys/smb/dcerpc/Wkssvc.java deleted file mode 100644 index 92558e791b..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/Wkssvc.java +++ /dev/null @@ -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.smb.dcerpc; - -/** - * Wkssvc Operation Ids Class - */ -public class Wkssvc -{ - // Wkssvc opcodes - - public static final int NetWkstaGetInfo = 0x00; - - /** - * Convert an opcode to a function name - * - * @param opCode int - * @return String - */ - public final static String getOpcodeName(int opCode) - { - String ret = ""; - switch (opCode) - { - case NetWkstaGetInfo: - ret = "NetWkstaGetInfo"; - break; - } - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfo.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfo.java deleted file mode 100644 index e1218e9993..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfo.java +++ /dev/null @@ -1,261 +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.smb.dcerpc.info; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; - -/** - * Connection Information Class - *

- * Contains the details of a connection on a remote server. - */ -public class ConnectionInfo implements DCEReadable -{ - - // Information level - - private int m_infoLevel; - - // Connection id and type - - private int m_connId; - private int m_connType; - - // Count of open files - - private int m_openFiles; - - // Number of users - - private int m_numUsers; - - // Time connected, in minutes - - private int m_connTime; - - // User name - - private String m_userName; - - // Client name - - private String m_clientName; - - /** - * Default constructor - */ - public ConnectionInfo() - { - } - - /** - * Class constructor - * - * @param infoLevel int - */ - public ConnectionInfo(int infoLevel) - { - m_infoLevel = infoLevel; - } - - /** - * Get the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Get the connection id - * - * @return int - */ - public final int getConnectionId() - { - return m_connId; - } - - /** - * Get the connection type - * - * @return int - */ - public final int getConnectionType() - { - return m_connType; - } - - /** - * Get the number of open files on the connection - * - * @return int - */ - public final int getOpenFileCount() - { - return m_openFiles; - } - - /** - * Return the number of users on the connection - * - * @return int - */ - public final int getNumberOfUsers() - { - return m_numUsers; - } - - /** - * Return the connection time in seconds - * - * @return int - */ - public final int getConnectionTime() - { - return m_connTime; - } - - /** - * Return the user name - * - * @return String - */ - public final String getUserName() - { - return m_userName; - } - - /** - * Return the client name - * - * @return String - */ - public final String getClientName() - { - return m_clientName; - } - - /** - * Read a connection information object from a DCE buffer - * - * @param buf DCEBuffer - * @throws DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException - { - - // Unpack the connection information - - switch (getInformationLevel()) - { - - // Information level 0 - - case 0: - m_connId = buf.getInt(); - m_userName = null; - m_clientName = null; - break; - - // Information level 1 - - case 1: - m_connId = buf.getInt(); - m_connType = buf.getInt(); - m_openFiles = buf.getInt(); - m_numUsers = buf.getInt(); - m_connTime = buf.getInt(); - - m_userName = buf.getPointer() != 0 ? "" : null; - m_clientName = buf.getPointer() != 0 ? "" : null; - break; - } - } - - /** - * Read the strings for this connection information from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readStrings(DCEBuffer buf) throws DCEBufferException - { - - // Read the strings for this connection information - - switch (getInformationLevel()) - { - - // Information level 1 - - case 1: - if (getUserName() != null) - m_userName = buf.getString(DCEBuffer.ALIGN_INT); - if (getClientName() != null) - m_clientName = buf.getString(DCEBuffer.ALIGN_INT); - break; - } - } - - /** - * Return the connection information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("[ID="); - str.append(getConnectionId()); - str.append(":Level="); - str.append(getInformationLevel()); - str.append(":"); - - if (getInformationLevel() == 1) - { - str.append("Type="); - str.append(getConnectionType()); - str.append(",OpenFiles="); - str.append(getOpenFileCount()); - str.append(",NumUsers="); - str.append(getNumberOfUsers()); - str.append(",Connected="); - str.append(getConnectionTime()); - str.append(",User="); - str.append(getUserName()); - str.append(",Client="); - str.append(getClientName()); - } - - str.append("]"); - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfoList.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfoList.java deleted file mode 100644 index cef8e29041..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/ConnectionInfoList.java +++ /dev/null @@ -1,66 +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.smb.dcerpc.info; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEList; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; - -/** - * Connection Information List Class - */ -public class ConnectionInfoList extends DCEList -{ - - /** - * Default constructor - */ - public ConnectionInfoList() - { - super(); - } - - /** - * Class constructor - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public ConnectionInfoList(DCEBuffer buf) throws DCEBufferException - { - super(buf); - } - - /** - * Create a new connection information object - * - * @return DCEReadable - */ - protected DCEReadable getNewObject() - { - return new ConnectionInfo(getInformationLevel()); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/ServerInfo.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/ServerInfo.java deleted file mode 100644 index 534249b294..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/ServerInfo.java +++ /dev/null @@ -1,346 +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.smb.dcerpc.info; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; -import org.alfresco.filesys.smb.dcerpc.DCEWriteable; - -/** - * Server Information Class - */ -public class ServerInfo implements DCEWriteable, DCEReadable -{ - - // Information levels supported - - public static final int InfoLevel0 = 0; - public static final int InfoLevel1 = 1; - public static final int InfoLevel101 = 101; - public static final int InfoLevel102 = 102; - - // Server platform ids - - public final static int PLATFORM_OS2 = 400; - public final static int PLATFORM_NT = 500; - - // Information level - - private int m_infoLevel; - - // Server information - - private int m_platformId; - private String m_name; - private int m_verMajor; - private int m_verMinor; - private int m_srvType; - private String m_comment; - - /** - * Default constructor - */ - public ServerInfo() - { - } - - /** - * Class constructor - * - * @param lev int - */ - public ServerInfo(int lev) - { - m_infoLevel = lev; - } - - /** - * Get the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Get the server name - * - * @return String - */ - public final String getServerName() - { - return m_name; - } - - /** - * Get the server comment - * - * @return String - */ - public final String getComment() - { - return m_comment; - } - - /** - * Get the server platform id - * - * @return int - */ - public final int getPlatformId() - { - return m_platformId; - } - - /** - * Get the servev major version - * - * @return int - */ - public final int getMajorVersion() - { - return m_verMajor; - } - - /** - * Get the server minor version - * - * @return int - */ - public final int getMinorVersion() - { - return m_verMinor; - } - - /** - * Get the server type flags - * - * @return int - */ - public final int getServerType() - { - return m_srvType; - } - - /** - * Set the server name - * - * @param name String - */ - public final void setServerName(String name) - { - m_name = name; - } - - /** - * Set the server comment - * - * @param comment String - */ - public final void setComment(String comment) - { - m_comment = comment; - } - - /** - * Set the information level - * - * @param lev int - */ - public final void setInformationLevel(int lev) - { - m_infoLevel = lev; - } - - /** - * Set the server platform id - * - * @param id int - */ - public final void setPlatformId(int id) - { - m_platformId = id; - } - - /** - * Set the server type flags - * - * @param typ int - */ - public final void setServerType(int typ) - { - m_srvType = typ; - } - - /** - * Set the server version - * - * @param verMajor int - * @param verMinor int - */ - public final void setVersion(int verMajor, int verMinor) - { - m_verMajor = verMajor; - m_verMinor = verMinor; - } - - /** - * Clear the string values - */ - protected final void clearStrings() - { - - // Clear the string values - - m_name = null; - m_comment = null; - } - - /** - * Read the server information from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException - { - - // Clear the string values - - clearStrings(); - - // Read the server information details - - m_infoLevel = buf.getInt(); - buf.skipPointer(); - - // Unpack the server information - - switch (getInformationLevel()) - { - - // Information level 0 - - case InfoLevel0: - if (buf.getPointer() != 0) - m_name = buf.getString(DCEBuffer.ALIGN_INT); - break; - - // Information level 101/1 - - case InfoLevel1: - case InfoLevel101: - m_platformId = buf.getInt(); - buf.skipPointer(); - m_verMajor = buf.getInt(); - m_verMinor = buf.getInt(); - m_srvType = buf.getInt(); - buf.skipPointer(); - - m_name = buf.getString(DCEBuffer.ALIGN_INT); - m_comment = buf.getString(); - break; - - // Level 102 - - case InfoLevel102: - break; - } - } - - /** - * Read the strings for this object from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readStrings(DCEBuffer buf) throws DCEBufferException - { - - // Not required - } - - /** - * Write a server information structure - * - * @param buf DCEBuffer - * @param strBuf DCEBuffer - */ - public void writeObject(DCEBuffer buf, DCEBuffer strBuf) - { - - // Output the server information structure - - buf.putInt(getInformationLevel()); - buf.putPointer(true); - - // Output the required information level - - switch (getInformationLevel()) - { - - // Information level 0 - - case InfoLevel0: - buf.putPointer(getServerName() != null); - if (getServerName() != null) - strBuf.putString(getServerName(), DCEBuffer.ALIGN_INT, true); - break; - - // Information level 101/1 - - case InfoLevel1: - case InfoLevel101: - buf.putInt(getPlatformId()); - buf.putPointer(true); - buf.putInt(getMajorVersion()); - buf.putInt(getMinorVersion()); - buf.putInt(getServerType()); - buf.putPointer(true); - - strBuf.putString(getServerName(), DCEBuffer.ALIGN_INT, true); - strBuf.putString(getComment() != null ? getComment() : "", DCEBuffer.ALIGN_INT, true); - break; - - // Level 102 - - case InfoLevel102: - break; - } - } - - /** - * Return the server information as a string - * - * @return String - */ - public String toString() - { - return ""; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfo.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfo.java deleted file mode 100644 index cafb921b1f..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfo.java +++ /dev/null @@ -1,618 +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.smb.dcerpc.info; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; -import org.alfresco.filesys.smb.dcerpc.DCEWriteable; - -/** - * Share Information Class - *

- * Holds the details of a share from a DCE/RPC request/response. - */ -public class ShareInfo implements DCEWriteable, DCEReadable -{ - - // Information levels supported - - public static final int InfoLevel0 = 0; - public static final int InfoLevel1 = 1; - public static final int InfoLevel2 = 2; - public static final int InfoLevel502 = 502; - public static final int InfoLevel1005 = 1005; - - // Share types - - public static final int Disk = 0x00000000; - public static final int PrintQueue = 0x00000001; - public static final int Device = 0x00000002; - public static final int IPC = 0x00000003; - public static final int Hidden = 0x80000000; - - // Share permission flags - - public static final int Read = 0x01; - public static final int Write = 0x02; - public static final int Create = 0x04; - public static final int Execute = 0x08; - public static final int Delete = 0x10; - public static final int Attrib = 0x20; - public static final int Perm = 0x40; - public static final int All = 0x7F; - - // Information level - - private int m_infoLevel; - - // Share details - - private String m_name; - private int m_type; - private String m_comment; - - private int m_permissions; - private int m_maxUsers; - private int m_curUsers; - private String m_path; - private String m_password; - - private int m_flags; - - /** - * Class constructor - */ - public ShareInfo() - { - } - - /** - * Class constructor - * - * @param lev int - */ - public ShareInfo(int lev) - { - m_infoLevel = lev; - } - - /** - * Class constructor - * - * @param lev int - * @param name String - * @param typ int - * @param comment String - */ - public ShareInfo(int lev, String name, int typ, String comment) - { - m_infoLevel = lev; - m_name = name; - m_type = typ; - m_comment = comment; - } - - /** - * Return the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Return the share name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the share type - * - * @return int - */ - public final int getType() - { - return m_type; - } - - /** - * Get the share flags - * - * @return int - */ - public final int getFlags() - { - return m_flags; - } - - /** - * Check if this share is a hidden/admin share - * - * @return boolean - */ - public final boolean isHidden() - { - return (m_type & Hidden) != 0 ? true : false; - } - - /** - * Check if this is a disk share - * - * @return boolean - */ - public final boolean isDisk() - { - return (m_type & 0x0000FFFF) == Disk ? true : false; - } - - /** - * Check if this is a printer share - * - * @return boolean - */ - public final boolean isPrinter() - { - return (m_type & 0x0000FFFF) == PrintQueue ? true : false; - } - - /** - * Check if this is a device share - * - * @return boolean - */ - public final boolean isDevice() - { - return (m_type & 0x0000FFFF) == Device ? true : false; - } - - /** - * Check if this is a named pipe share - * - * @return boolean - */ - public final boolean isNamedPipe() - { - return (m_type & 0x0000FFFF) == IPC ? true : false; - } - - /** - * Return the share permissions - * - * @return int - */ - public final int getPermissions() - { - return m_permissions; - } - - /** - * Return the maximum number of users allowed - * - * @return int - */ - public final int getMaximumUsers() - { - return m_maxUsers; - } - - /** - * Return the current number of users - * - * @return int - */ - public final int getCurrentUsers() - { - return m_curUsers; - } - - /** - * Return the share local path - * - * @return String - */ - public final String getPath() - { - return m_path; - } - - /** - * Return the share password - * - * @return String - */ - public final String getPassword() - { - return m_password; - } - - /** - * Return the share type as a string - * - * @return String - */ - public final String getTypeAsString() - { - - String typ = ""; - switch (getType() & 0xFF) - { - case Disk: - typ = "Disk"; - break; - case PrintQueue: - typ = "Printer"; - break; - case Device: - typ = "Device"; - break; - case IPC: - typ = "IPC"; - break; - } - - return typ; - } - - /** - * Return the comment - * - * @return String - */ - public final String getComment() - { - return m_comment; - } - - /** - * Set the information level - * - * @param lev int - */ - public final void setInformationLevel(int lev) - { - m_infoLevel = lev; - } - - /** - * Set the share type - * - * @param int typ - */ - public final void setType(int typ) - { - m_type = typ; - } - - /** - * Set the share flags - * - * @param flags int - */ - public final void setFlags(int flags) - { - m_flags = flags; - } - - /** - * Set the share name - * - * @param name String - */ - public final void setName(String name) - { - m_name = name; - } - - /** - * Set the share comment - * - * @param str String - */ - public final void setComment(String str) - { - m_comment = str; - } - - /** - * Set the share permissions - * - * @param perm int - */ - public final void setPermissions(int perm) - { - m_permissions = perm; - } - - /** - * Set the maximum number of users - * - * @param maxUsers int - */ - public final void setMaximumUsers(int maxUsers) - { - m_maxUsers = maxUsers; - } - - /** - * Set the current number of users - * - * @param curUsers int - */ - public final void setCurrentUsers(int curUsers) - { - m_curUsers = curUsers; - } - - /** - * Set the local path - * - * @param path String - */ - public final void setPath(String path) - { - m_path = path; - } - - /** - * Clear all string values - */ - protected final void clearStrings() - { - - // Clear the string values - - m_name = null; - m_comment = null; - m_path = null; - m_password = null; - } - - /** - * Read the share information from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException - { - - // Clear all existing strings - - clearStrings(); - - // Unpack the share information - - switch (getInformationLevel()) - { - - // Information level 0 - - case InfoLevel0: - m_name = buf.getPointer() != 0 ? "" : null; - break; - - // Information level 1 - - case InfoLevel1: - m_name = buf.getPointer() != 0 ? "" : null; - m_type = buf.getInt(); - m_comment = buf.getPointer() != 0 ? "" : null; - break; - - // Information level 2 - - case InfoLevel2: - m_name = buf.getPointer() != 0 ? "" : null; - m_type = buf.getInt(); - m_comment = buf.getPointer() != 0 ? "" : null; - m_permissions = buf.getInt(); - m_maxUsers = buf.getInt(); - m_curUsers = buf.getInt(); - m_path = buf.getPointer() != 0 ? "" : null; - m_password = buf.getPointer() != 0 ? "" : null; - break; - - // Information level 502 - - case InfoLevel502: - m_name = buf.getPointer() != 0 ? "" : null; - m_type = buf.getInt(); - m_comment = buf.getPointer() != 0 ? "" : null; - m_permissions = buf.getInt(); - m_maxUsers = buf.getInt(); - m_curUsers = buf.getInt(); - m_path = buf.getPointer() != 0 ? "" : null; - m_password = buf.getPointer() != 0 ? "" : null; - - buf.skipBytes(4); // Reserved value - - // Security descriptor - break; - } - } - - /** - * Read the strings for this share from the DCE/RPC buffer - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public void readStrings(DCEBuffer buf) throws DCEBufferException - { - - // Read the strings for this share information - - switch (getInformationLevel()) - { - - // Information level 0 - - case InfoLevel0: - if (getName() != null) - m_name = buf.getString(DCEBuffer.ALIGN_INT); - break; - - // Information level 1 - - case InfoLevel1: - if (getName() != null) - m_name = buf.getString(DCEBuffer.ALIGN_INT); - if (getComment() != null) - m_comment = buf.getString(DCEBuffer.ALIGN_INT); - break; - - // Information level 2 and 502 - - case InfoLevel2: - case InfoLevel502: - if (getName() != null) - m_name = buf.getString(DCEBuffer.ALIGN_INT); - if (getComment() != null) - m_comment = buf.getString(DCEBuffer.ALIGN_INT); - if (getPath() != null) - m_path = buf.getString(DCEBuffer.ALIGN_INT); - if (getPassword() != null) - m_password = buf.getString(DCEBuffer.ALIGN_INT); - break; - } - } - - /** - * Write the share information to the DCE buffer - * - * @param buf DCEBuffer - * @param strBuf DCEBuffer - */ - public void writeObject(DCEBuffer buf, DCEBuffer strBuf) - { - - // Pack the share information - - switch (getInformationLevel()) - { - - // Information level 0 - - case InfoLevel0: - buf.putPointer(true); - strBuf.putString(getName(), DCEBuffer.ALIGN_INT, true); - break; - - // Information level 1 - - case InfoLevel1: - buf.putPointer(true); - buf.putInt(getType()); - buf.putPointer(true); - - strBuf.putString(getName(), DCEBuffer.ALIGN_INT, true); - strBuf.putString(getComment() != null ? getComment() : "", DCEBuffer.ALIGN_INT, true); - break; - - // Information level 2 - - case InfoLevel2: - buf.putPointer(true); - buf.putInt(getType()); - buf.putPointer(true); - buf.putInt(getPermissions()); - buf.putInt(getMaximumUsers()); - buf.putInt(getCurrentUsers()); - buf.putPointer(getPath() != null); - buf.putPointer(getPassword() != null); - - strBuf.putString(getName(), DCEBuffer.ALIGN_INT, true); - strBuf.putString(getComment() != null ? getComment() : "", DCEBuffer.ALIGN_INT, true); - if (getPath() != null) - strBuf.putString(getPath(), DCEBuffer.ALIGN_INT, true); - if (getPassword() != null) - strBuf.putString(getPassword(), DCEBuffer.ALIGN_INT, true); - break; - - // Information level 502 - - case InfoLevel502: - buf.putPointer(true); - buf.putInt(getType()); - buf.putPointer(true); - buf.putInt(getPermissions()); - buf.putInt(getMaximumUsers()); - buf.putInt(getCurrentUsers()); - buf.putPointer(getPath() != null); - buf.putPointer(getPassword() != null); - buf.putInt(0); // Reserved, must be zero - buf.putPointer(false); // Security descriptor - - strBuf.putString(getName(), DCEBuffer.ALIGN_INT, true); - strBuf.putString(getComment() != null ? getComment() : "", DCEBuffer.ALIGN_INT, true); - if (getPath() != null) - strBuf.putString(getPath(), DCEBuffer.ALIGN_INT, true); - if (getPassword() != null) - strBuf.putString(getPassword(), DCEBuffer.ALIGN_INT, true); - break; - - // Information level 1005 - - case InfoLevel1005: - buf.putInt(getFlags()); - break; - } - } - - /** - * Return the share information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getName()); - str.append(":"); - str.append(getInformationLevel()); - str.append(":"); - - if (getInformationLevel() == 1) - { - str.append("0x"); - str.append(Integer.toHexString(getType())); - str.append(","); - str.append(getComment()); - } - - str.append("]"); - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfoList.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfoList.java deleted file mode 100644 index 9a3f7d63b8..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/ShareInfoList.java +++ /dev/null @@ -1,119 +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.smb.dcerpc.info; - -import java.util.Vector; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEList; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; - -/** - * Server Share Information List Class - *

- * Holds the details for a DCE/RPC share enumeration request or response. - */ -public class ShareInfoList extends DCEList -{ - - /** - * Default constructor - */ - public ShareInfoList() - { - super(); - } - - /** - * Class constructor - * - * @param buf DCEBuffer - * @exception DCEBufferException - */ - public ShareInfoList(DCEBuffer buf) throws DCEBufferException - { - super(buf); - } - - /** - * Class constructor - * - * @param infoLevel int - */ - public ShareInfoList(int infoLevel) - { - super(infoLevel); - } - - /** - * Return share information object from the list - * - * @param idx int - * @return ShareInfo - */ - public final ShareInfo getShare(int idx) - { - return (ShareInfo) getElement(idx); - } - - /** - * Create a new share information object - * - * @return DCEReadable - */ - protected DCEReadable getNewObject() - { - return new ShareInfo(getInformationLevel()); - } - - /** - * Add a share to the list - * - * @param share ShareInfo - */ - public final void addShare(ShareInfo share) - { - - // Check if the share list is valid - - if (getList() == null) - setList(new Vector()); - - // Add the share - - getList().add(share); - } - - /** - * Set the share information list - * - * @param list Vector - */ - public final void setShareList(Vector list) - { - setList(list); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/UserInfo.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/UserInfo.java deleted file mode 100644 index 558788a777..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/UserInfo.java +++ /dev/null @@ -1,781 +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.smb.dcerpc.info; - -import java.util.BitSet; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCEReadable; - -/** - * User Information Class - *

- * Contains the details of a user account on a remote server. - */ -public class UserInfo implements DCEReadable -{ - - // Information levels supported - - public static final int InfoLevel1 = 1; - public static final int InfoLevel3 = 3; - public static final int InfoLevel21 = 21; - - // public static final int InfoLevel2 = 2; - // public static final int InfoLevel4 = 4; - // public static final int InfoLevel5 = 5; - // public static final int InfoLevel6 = 6; - // public static final int InfoLevel7 = 7; - // public static final int InfoLevel8 = 8; - // public static final int InfoLevel9 = 9; - // public static final int InfoLevel10 = 10; - // public static final int InfoLevel11 = 11; - // public static final int InfoLevel12 = 12; - // public static final int InfoLevel13 = 13; - // public static final int InfoLevel14 = 14; - // public static final int InfoLevel16 = 16; - // public static final int InfoLevel17 = 17; - // public static final int InfoLevel20 = 20; - - // Account privilege levels - - public static final int PrivGuest = 0; - public static final int PrivUser = 1; - public static final int PrivAdmin = 2; - - // Account operator privileges - - public static final int OperPrint = 0; - public static final int OperComm = 1; - public static final int OperServer = 2; - public static final int OperAccounts = 3; - - // Account flags - - private static final int AccountDisabled = 0x0001; - private static final int AccountHomeDirRequired = 0x0002; - private static final int AccountPasswordNotRequired = 0x0004; - private static final int AccountTemporaryDuplicate = 0x0008; - private static final int AccountNormal = 0x0010; - private static final int AccountMNSUser = 0x0020; - private static final int AccountDomainTrust = 0x0040; - private static final int AccountWorkstationTrust = 0x0080; - private static final int AccountServerTrust = 0x0100; - private static final int AccountPasswordNotExpire = 0x0200; - private static final int AccountAutoLocked = 0x0400; - - // Information level - - private int m_infoLevel; - - // User information - - private String m_userName; - - private int m_pwdAge; - private int m_priv; - - private String m_homeDir; - private String m_comment; - private String m_description; - private String m_accComment; - - private int m_flags; - - private String m_scriptPath; - // private int m_authFlags; - - private String m_fullName; - private String m_appParam; - private String m_workStations; - - private long m_lastLogon; - private long m_lastLogoff; - private long m_acctExpires; - private long m_lastPwdChange; - private long m_pwdCanChange; - private long m_pwdMustchange; - - // private int m_maxStorage; - private int m_unitsPerWeek; - private byte[] m_logonHoursRaw; - private BitSet m_logonHours; - - private int m_badPwdCount; - private int m_numLogons; - private String logonSrv; - - private int m_countryCode; - private int m_codePage; - - private int m_userRID; - private int m_groupRID; - // private SID m_userSID; - - private String m_profile; - private String m_homeDirDrive; - - private int m_pwdExpired; - - private String m_callBack; - private String m_unknown1; - private String m_unknown2; - private String m_unknown3; - - /** - * Default constructor - */ - public UserInfo() - { - } - - /** - * Class constructor - * - * @param lev int - */ - public UserInfo(int lev) - { - m_infoLevel = lev; - } - - /** - * Get the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Return the logon server name - * - * @return String - */ - public final String getLogonServer() - { - return logonSrv; - } - - /** - * Return the date/time the account expires, or NTTime.Infinity if it does not expire - * - * @return long - */ - public final long getAccountExpires() - { - return m_acctExpires; - } - - /** - * Return the application parameter string - * - * @return String - */ - public final String getApplicationParameter() - { - return m_appParam; - } - - /** - * Return the bad password count - * - * @return int - */ - public final int getBadPasswordCount() - { - return m_badPwdCount; - } - - /** - * Return the code page - * - * @return int - */ - public final int getCodePage() - { - return m_codePage; - } - - /** - * Return the account comment - * - * @return String - */ - public final String getComment() - { - return m_comment; - } - - /** - * Return the account description - * - * @return String - */ - public final String getDescription() - { - return m_description; - } - - /** - * Return the country code - * - * @return int - */ - public final int getCountryCode() - { - return m_countryCode; - } - - /** - * Return the account flags - * - * @return int - */ - public final int getFlags() - { - return m_flags; - } - - /** - * Check if the account is disabled - * - * @return boolean - */ - public final boolean isDisabled() - { - return (m_flags & AccountDisabled) != 0 ? true : false; - } - - /** - * Check if the account does not require a home directory - * - * @return boolean - */ - public final boolean requiresHomeDirectory() - { - return (m_flags & AccountHomeDirRequired) != 0 ? true : false; - } - - /** - * Check if the account does not require a password - * - * @return boolean - */ - public final boolean requiresPassword() - { - return (m_flags & AccountPasswordNotRequired) != 0 ? false : true; - } - - /** - * Check if the account is a normal user account - * - * @return boolean - */ - public final boolean isNormalUser() - { - return (m_flags & AccountNormal) != 0 ? true : false; - } - - /** - * Check if the account is a domain trust account - * - * @return boolean - */ - public final boolean isDomainTrust() - { - return (m_flags & AccountDomainTrust) != 0 ? true : false; - } - - /** - * Check if the account is a workstation trust account - * - * @return boolean - */ - public final boolean isWorkstationTrust() - { - return (m_flags & AccountWorkstationTrust) != 0 ? true : false; - } - - /** - * Check if the account is a server trust account - * - * @return boolean - */ - public final boolean isServerTrust() - { - return (m_flags & AccountServerTrust) != 0 ? true : false; - } - - /** - * Check if the account password expires - * - * @return boolean - */ - public final boolean passwordExpires() - { - return (m_flags & AccountPasswordNotExpire) != 0 ? false : true; - } - - /** - * Check if the account is auto locked - * - * @return boolean - */ - public final boolean isAutoLocked() - { - return (m_flags & AccountAutoLocked) != 0 ? true : false; - } - - /** - * Return the full account name - * - * @return String - */ - public final String getFullName() - { - return m_fullName; - } - - /** - * Return the group resource id - * - * @return int - */ - public final int getGroupRID() - { - return m_groupRID; - } - - /** - * Return the home directory path - * - * @return String - */ - public final String getHomeDirectory() - { - return m_homeDir; - } - - /** - * Return the home drive - * - * @return String - */ - public final String getHomeDirectoryDrive() - { - return m_homeDirDrive; - } - - /** - * Return the date/time of last logoff - * - * @return long - */ - public final long getLastLogoff() - { - return m_lastLogoff; - } - - /** - * Return the date/time of last logon, to this server - * - * @return long - */ - public final long getLastLogon() - { - return m_lastLogon; - } - - /** - * Return the allowed logon hours bit set - * - * @return BitSet - */ - public final BitSet getLogonHours() - { - return m_logonHours; - } - - /** - * Return the number of logons for the account, to this server - * - * @return int - */ - public final int numberOfLogons() - { - return m_numLogons; - } - - /** - * Return the account provileges - * - * @return int - */ - public final int getPrivileges() - { - return m_priv; - } - - /** - * Return the profile path - * - * @return String - */ - public final String getProfile() - { - return m_profile; - } - - /** - * Return the password expired flag - * - * @return int - */ - public final int getPasswordExpired() - { - return m_pwdExpired; - } - - /** - * Return the logon script path - * - * @return String - */ - public final String getLogonScriptPath() - { - return m_scriptPath; - } - - /** - * Return the allowed units per week - * - * @return int - */ - public final int getUnitsPerWeek() - { - return m_unitsPerWeek; - } - - /** - * Return the account name - * - * @return String - */ - public final String getUserName() - { - return m_userName; - } - - /** - * Return the user resource id - * - * @return int - */ - public final int getUserRID() - { - return m_userRID; - } - - /** - * Return the workstations that the account is allowed to logon from - * - * @return String - */ - public final String getWorkStations() - { - return m_workStations; - } - - /** - * Return the date/time of the last password change - * - * @return long - */ - public final long getLastPasswordChange() - { - return m_lastPwdChange; - } - - /** - * Return the date/time that the password must be changed by - * - * @return long - */ - public final long getPasswordMustChangeBy() - { - return m_pwdMustchange; - } - - /** - * Clear all string values - */ - private final void clearStrings() - { - - // Clear the string values - - m_appParam = null; - m_comment = null; - m_fullName = null; - m_homeDir = null; - m_homeDirDrive = null; - m_profile = null; - m_scriptPath = null; - m_userName = null; - m_workStations = null; - m_description = null; - m_accComment = null; - } - - /** - * Read the user information from the DCE buffer - * - * @param buf DCEBuffer - * @throws DCEBufferException - */ - public void readObject(DCEBuffer buf) throws DCEBufferException - { - - // clear all existing string values - - clearStrings(); - - // Unpack the user information - - int ival = 0; - int pval = 0; - - switch (getInformationLevel()) - { - - // Information level 1 - - case InfoLevel1: - m_userName = buf.getCharArrayPointer(); - m_fullName = buf.getCharArrayPointer(); - m_groupRID = buf.getInt(); - m_description = buf.getCharArrayPointer(); - m_comment = buf.getCharArrayPointer(); - break; - - // Information level 3 - - case InfoLevel3: - m_userName = buf.getCharArrayPointer(); - m_fullName = buf.getCharArrayPointer(); - - m_userRID = buf.getInt(); - m_groupRID = buf.getInt(); - - m_homeDir = buf.getCharArrayPointer(); - m_homeDirDrive = buf.getCharArrayPointer(); - m_scriptPath = buf.getCharArrayPointer(); - m_profile = buf.getCharArrayPointer(); - m_workStations = buf.getCharArrayPointer(); - - m_lastLogon = buf.getNTTime(); - m_lastLogoff = buf.getNTTime(); - m_lastPwdChange = buf.getNTTime(); - buf.skipBytes(8); // allow password change NT time - buf.skipBytes(8); // force password change NT time - - ival = buf.getShort(DCEBuffer.ALIGN_INT); - pval = buf.getPointer(); - - if (ival != 0 && pval != 0) - m_logonHoursRaw = new byte[ival / 8]; - - m_badPwdCount = buf.getShort(); - m_numLogons = buf.getShort(); - - m_flags = buf.getInt(); - break; - - // Information level 21 - - case InfoLevel21: - m_lastLogon = buf.getNTTime(); - m_lastLogoff = buf.getNTTime(); - m_lastPwdChange = buf.getNTTime(); - m_acctExpires = buf.getNTTime(); - m_pwdCanChange = buf.getNTTime(); - m_pwdMustchange = buf.getNTTime(); - - m_userName = buf.getCharArrayPointer(); - m_fullName = buf.getCharArrayPointer(); - - m_homeDir = buf.getCharArrayPointer(); - m_homeDirDrive = buf.getCharArrayPointer(); - m_scriptPath = buf.getCharArrayPointer(); - m_profile = buf.getCharArrayPointer(); - m_description = buf.getCharArrayPointer(); - m_workStations = buf.getCharArrayPointer(); - m_accComment = buf.getCharArrayPointer(); - - m_callBack = buf.getCharArrayPointer(); - m_unknown1 = buf.getCharArrayPointer(); - m_unknown2 = buf.getCharArrayPointer(); - m_unknown3 = buf.getCharArrayPointer(); - - buf.skipBytes(8); // buffer length and pointer - - m_userRID = buf.getInt(); - m_groupRID = buf.getInt(); - - m_flags = buf.getInt(); - - buf.getInt(); // fields present flags - - ival = buf.getShort(DCEBuffer.ALIGN_INT); - pval = buf.getPointer(); - - if (ival != 0 && pval != 0) - m_logonHoursRaw = new byte[ival / 8]; - - m_badPwdCount = buf.getShort(); - m_numLogons = buf.getShort(); - - m_countryCode = buf.getShort(); - m_codePage = buf.getShort(); - - buf.skipBytes(2); // NT and LM pwd set flags - - m_pwdExpired = buf.getByte(DCEBuffer.ALIGN_INT); - break; - } - } - - /** - * Read the strings for this user information from the DCE buffer - * - * @param buf DCEBuffer - * @throws DCEBufferException - */ - public void readStrings(DCEBuffer buf) throws DCEBufferException - { - - // Read the strings/structures for this user information - - switch (getInformationLevel()) - { - - // Information level 1 - - case InfoLevel1: - m_userName = buf.getCharArrayNotNull(m_userName, DCEBuffer.ALIGN_INT); - m_fullName = buf.getCharArrayNotNull(m_fullName, DCEBuffer.ALIGN_INT); - - m_description = buf.getCharArrayNotNull(m_description, DCEBuffer.ALIGN_INT); - m_comment = buf.getCharArrayNotNull(m_comment, DCEBuffer.ALIGN_INT); - break; - - // Information level 3 - - case InfoLevel3: - m_userName = buf.getCharArrayNotNull(m_userName, DCEBuffer.ALIGN_INT); - m_fullName = buf.getCharArrayNotNull(m_fullName, DCEBuffer.ALIGN_INT); - - m_homeDir = buf.getCharArrayNotNull(m_homeDir, DCEBuffer.ALIGN_INT); - m_homeDirDrive = buf.getCharArrayNotNull(m_homeDirDrive, DCEBuffer.ALIGN_INT); - - m_scriptPath = buf.getCharArrayNotNull(m_scriptPath, DCEBuffer.ALIGN_INT); - m_profile = buf.getCharArrayNotNull(m_profile, DCEBuffer.ALIGN_INT); - m_workStations = buf.getCharArrayNotNull(m_workStations, DCEBuffer.ALIGN_INT); - - m_logonHoursRaw = buf.getByteStructure(m_logonHoursRaw); - break; - - // Information level 21 - - case InfoLevel21: - m_userName = buf.getCharArrayNotNull(m_userName, DCEBuffer.ALIGN_INT); - m_fullName = buf.getCharArrayNotNull(m_fullName, DCEBuffer.ALIGN_INT); - - m_homeDir = buf.getCharArrayNotNull(m_homeDir, DCEBuffer.ALIGN_INT); - m_homeDirDrive = buf.getCharArrayNotNull(m_homeDirDrive, DCEBuffer.ALIGN_INT); - - m_scriptPath = buf.getCharArrayNotNull(m_scriptPath, DCEBuffer.ALIGN_INT); - m_profile = buf.getCharArrayNotNull(m_profile, DCEBuffer.ALIGN_INT); - m_description = buf.getCharArrayNotNull(m_description, DCEBuffer.ALIGN_INT); - m_workStations = buf.getCharArrayNotNull(m_workStations, DCEBuffer.ALIGN_INT); - m_accComment = buf.getCharArrayNotNull(m_profile, DCEBuffer.ALIGN_INT); - - m_callBack = buf.getCharArrayNotNull(m_callBack, DCEBuffer.ALIGN_INT); - m_unknown1 = buf.getCharArrayNotNull(m_unknown1, DCEBuffer.ALIGN_INT); - m_unknown2 = buf.getCharArrayNotNull(m_unknown2, DCEBuffer.ALIGN_INT); - m_unknown3 = buf.getCharArrayNotNull(m_unknown3, DCEBuffer.ALIGN_INT); - - m_logonHoursRaw = buf.getByteStructure(m_logonHoursRaw); - break; - } - } - - /** - * Return an account type as a string - * - * @param typ int - * @return String - */ - public final static String getAccountTypeAsString(int typ) - { - String ret = ""; - switch (typ) - { - case PrivGuest: - ret = "Guest"; - break; - case PrivUser: - ret = "User"; - break; - case PrivAdmin: - ret = "Administrator"; - break; - } - return ret; - } - - /** - * Return the user information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getUserName()); - str.append(":"); - str.append(getInformationLevel()); - str.append(":"); - - str.append("]"); - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/info/WorkstationInfo.java b/source/java/org/alfresco/filesys/smb/dcerpc/info/WorkstationInfo.java deleted file mode 100644 index 5a86664bb6..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/info/WorkstationInfo.java +++ /dev/null @@ -1,345 +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.smb.dcerpc.info; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEWriteable; - -/** - * Workstation Information Class - */ -public class WorkstationInfo implements DCEWriteable -{ - - // Supported information levels - - public static final int InfoLevel100 = 100; - - // Information level - - private int m_infoLevel; - - // Server information - - private int m_platformId; - private String m_name; - private String m_domain; - private int m_verMajor; - private int m_verMinor; - - private String m_userName; - private String m_logonDomain; - private String m_otherDomain; - - /** - * Default constructor - */ - public WorkstationInfo() - { - } - - /** - * Class constructor - * - * @param lev int - */ - public WorkstationInfo(int lev) - { - m_infoLevel = lev; - } - - /** - * Get the information level - * - * @return int - */ - public final int getInformationLevel() - { - return m_infoLevel; - } - - /** - * Get the workstation name - * - * @return String - */ - public final String getWorkstationName() - { - return m_name; - } - - /** - * Get the domain/workgroup - * - * @return String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Get the workstation platform id - * - * @return int - */ - public final int getPlatformId() - { - return m_platformId; - } - - /** - * Get the workstation major version - * - * @return int - */ - public final int getMajorVersion() - { - return m_verMajor; - } - - /** - * Get the workstation minor version - * - * @return int - */ - public final int getMinorVersion() - { - return m_verMinor; - } - - /** - * Reutrn the user name - * - * @return String - */ - public final String getUserName() - { - return m_userName; - } - - /** - * Return the workstations logon domain. - * - * @return java.lang.String - */ - public String getLogonDomain() - { - return m_logonDomain; - } - - /** - * Return the list of domains that the workstation is enlisted in. - * - * @return java.lang.String - */ - public String getOtherDomains() - { - return m_otherDomain; - } - - /** - * Set the logon domain name. - * - * @param logdom java.lang.String - */ - public void setLogonDomain(String logdom) - { - m_logonDomain = logdom; - } - - /** - * Set the other domains that this workstation is enlisted in. - * - * @param othdom java.lang.String - */ - public void setOtherDomains(String othdom) - { - m_otherDomain = othdom; - } - - /** - * Set the workstation name - * - * @param name String - */ - public final void setWorkstationName(String name) - { - m_name = name; - } - - /** - * Set the domain/workgroup - * - * @param domain String - */ - public final void setDomain(String domain) - { - m_domain = domain; - } - - /** - * Set the information level - * - * @param lev int - */ - public final void setInformationLevel(int lev) - { - m_infoLevel = lev; - } - - /** - * Set the platform id - * - * @param id int - */ - public final void setPlatformId(int id) - { - m_platformId = id; - } - - /** - * Set the version - * - * @param verMajor int - * @param verMinor int - */ - public final void setVersion(int verMajor, int verMinor) - { - m_verMajor = verMajor; - m_verMinor = verMinor; - } - - /** - * Set the logged in user name - * - * @param user String - */ - public final void setUserName(String user) - { - m_userName = user; - } - - /** - * Clear the string values - */ - protected final void clearStrings() - { - - // Clear the string values - - m_userName = null; - m_domain = null; - m_logonDomain = null; - m_otherDomain = null; - } - - /** - * Write a workstation information structure - * - * @param buf DCEBuffer - * @param strBuf DCEBuffer - */ - public void writeObject(DCEBuffer buf, DCEBuffer strBuf) - { - - // Output the workstation information structure - - buf.putInt(getInformationLevel()); - buf.putPointer(true); - - // Output the required information level - - switch (getInformationLevel()) - { - - // Level 100 - - case InfoLevel100: - buf.putInt(getPlatformId()); - buf.putPointer(true); - buf.putPointer(true); - buf.putInt(getMajorVersion()); - buf.putInt(getMinorVersion()); - - strBuf.putString(getWorkstationName(), DCEBuffer.ALIGN_INT, true); - strBuf.putString(getDomain() != null ? getDomain() : "", DCEBuffer.ALIGN_INT, true); - break; - - // Level 101 - - case 101: - break; - - // Level 102 - - case 102: - break; - } - } - - /** - * Return the workstation information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - - str.append(getWorkstationName()); - str.append(":Domain="); - str.append(getDomain()); - str.append(":User="); - str.append(getUserName()); - str.append(":Id="); - str.append(getPlatformId()); - - str.append(":v"); - str.append(getMajorVersion()); - str.append("."); - str.append(getMinorVersion()); - - // Optional strings - - if (getLogonDomain() != null) - { - str.append(":Logon="); - str.append(getLogonDomain()); - } - - if (getOtherDomains() != null) - { - str.append(":Other="); - str.append(getOtherDomains()); - } - - // Return the workstation information as a string - - str.append("]"); - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEHandler.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEHandler.java deleted file mode 100644 index 647fba8dee..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEHandler.java +++ /dev/null @@ -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.smb.dcerpc.server; - -import java.io.IOException; - -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.server.SMBSrvException; -import org.alfresco.filesys.smb.server.SMBSrvSession; - -/** - * DCE Request Handler Interface - */ -public interface DCEHandler -{ - - /** - * Process a DCE/RPC request - * - * @param sess SMBSrvSession - * @param inBuf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public void processRequest(SMBSrvSession sess, DCEBuffer inBuf, DCEPipeFile pipeFile) throws IOException, - SMBSrvException; -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeFile.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeFile.java deleted file mode 100644 index 48b6b006e7..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeFile.java +++ /dev/null @@ -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.smb.dcerpc.server; - -import java.io.IOException; - -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEPipeType; - -/** - * DCE/RPC Pipe File Class - *

- * Contains the details and state of a DCE/RPC special named pipe. - */ -public class DCEPipeFile extends NetworkFile -{ - - // Maximum receive/transmit DCE fragment size - - private int m_maxRxFragSize; - private int m_maxTxFragSize; - - // Named pipe state flags - - private int m_state; - - // DCE/RPC handler for this named pipe - - private DCEHandler m_handler; - - // Current DCE buffered data - - private DCEBuffer m_dceData; - - /** - * Class constructor - * - * @param id int - */ - public DCEPipeFile(int id) - { - super(id); - setName(DCEPipeType.getTypeAsString(id)); - - // Set the DCE/RPC request handler for the pipe - - setRequestHandler(DCEPipeHandler.getHandlerForType(id)); - } - - /** - * Return the maximum receive fragment size - * - * @return int - */ - public final int getMaxReceiveFragmentSize() - { - return m_maxRxFragSize; - } - - /** - * Return the maximum transmit fragment size - * - * @return int - */ - public final int getMaxTransmitFragmentSize() - { - return m_maxTxFragSize; - } - - /** - * Return the named pipe state - * - * @return int - */ - public final int getPipeState() - { - return m_state; - } - - /** - * Return the pipe type id - * - * @return int - */ - public final int getPipeId() - { - return getFileId(); - } - - /** - * Determine if the pipe has a request handler - * - * @return boolean - */ - public final boolean hasRequestHandler() - { - return m_handler != null ? true : false; - } - - /** - * Return the pipes DCE/RPC handler - * - * @return DCEHandler - */ - public final DCEHandler getRequestHandler() - { - return m_handler; - } - - /** - * Determine if the pipe has any buffered data - * - * @return boolean - */ - public final boolean hasBufferedData() - { - return m_dceData != null ? true : false; - } - - /** - * Get the buffered data for the pipe - * - * @return DCEBuffer - */ - public final DCEBuffer getBufferedData() - { - return m_dceData; - } - - /** - * Set buffered data for the pipe - * - * @param buf DCEBuffer - */ - public final void setBufferedData(DCEBuffer buf) - { - m_dceData = buf; - } - - /** - * Set the maximum receive fragment size - * - * @param siz int - */ - public final void setMaxReceiveFragmentSize(int siz) - { - m_maxRxFragSize = siz; - } - - /** - * Set the maximum transmit fragment size - * - * @param siz int - */ - public final void setMaxTransmitFragmentSize(int siz) - { - m_maxTxFragSize = siz; - } - - /** - * Set the named pipe state flags - * - * @param state int - */ - public final void setPipeState(int state) - { - m_state = state; - } - - /** - * Set the pipes DCE/RPC handler - * - * @param handler DCEHandler - */ - public final void setRequestHandler(DCEHandler handler) - { - m_handler = handler; - } - - /** - * Dump the file details - */ - public final void DumpFile() - { - System.out.println("** DCE/RPC Named Pipe: " + getName()); - System.out.println(" File ID : " + getFileId()); - System.out.println(" State : 0x" + Integer.toHexString(getPipeState())); - System.out.println(" Max Rx : " + getMaxReceiveFragmentSize()); - System.out.println(" Max Tx : " + getMaxTransmitFragmentSize()); - System.out.println(" Handler : " + getRequestHandler()); - } - - /** - * @see NetworkFile#closeFile() - */ - public void closeFile() throws IOException - { - } - - /** - * @see NetworkFile#openFile(boolean) - */ - public void openFile(boolean createFlag) throws IOException - { - } - - /** - * @see NetworkFile#readFile(byte[], int, int, long) - */ - public int readFile(byte[] buf, int len, int pos, long fileOff) throws IOException - { - return 0; - } - - /** - * Flush any buffered output to the file - * - * @throws IOException - */ - public void flushFile() throws IOException - { - } - - /** - * @see NetworkFile#seekFile(long, int) - */ - public long seekFile(long pos, int typ) throws IOException - { - return 0; - } - - /** - * @see NetworkFile#truncateFile(long) - */ - public void truncateFile(long siz) throws IOException - { - } - - /** - * @see NetworkFile#writeFile(byte[], int, int, long) - */ - public void writeFile(byte[] buf, int len, int pos, long fileOff) throws IOException - { - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeHandler.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeHandler.java deleted file mode 100644 index cff957d886..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCEPipeHandler.java +++ /dev/null @@ -1,63 +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.smb.dcerpc.server; - -/** - * DCE Pipe Handler Class - *

- * Contains a list of the available DCE pipe handlers. - */ -public class DCEPipeHandler -{ - - // DCE/RPC pipe request handlers - - private static DCEHandler[] _handlers = { - new SrvsvcDCEHandler(), - null, // samr - null, // winreg - new WkssvcDCEHandler(), - null, // NETLOGON - null, // lsarpc - null, // spoolss - null, // netdfs - null, // service control - null, // eventlog - null // netlogon1 - }; - - /** - * Return the DCE/RPC request handler for the pipe type - * - * @param typ int - * @return DCEHandler - */ - public final static DCEHandler getHandlerForType(int typ) - { - if (typ >= 0 && typ < _handlers.length) - return _handlers[typ]; - return null; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCESrvPacket.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/DCESrvPacket.java deleted file mode 100644 index 6bc58b3cae..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/DCESrvPacket.java +++ /dev/null @@ -1,433 +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.smb.dcerpc.server; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.dcerpc.DCECommand; -import org.alfresco.filesys.smb.dcerpc.DCEDataPacker; -import org.alfresco.filesys.smb.server.SMBTransPacket; -import org.alfresco.filesys.util.DataPacker; - -/** - * DCE/RPC Server Packet Class - */ -public class DCESrvPacket extends SMBTransPacket -{ - - // DCE/RPC header offsets - - private static final int VERSIONMAJOR = 0; - private static final int VERSIONMINOR = 1; - private static final int PDUTYPE = 2; - private static final int HEADERFLAGS = 3; - private static final int PACKEDDATAREP = 4; - private static final int FRAGMENTLEN = 8; - private static final int AUTHLEN = 10; - private static final int CALLID = 12; - private static final int DCEDATA = 16; - - // DCE/RPC Request offsets - - private static final int ALLOCATIONHINT = 16; - private static final int PRESENTIDENT = 20; - private static final int OPERATIONID = 22; - private static final int OPERATIONDATA = 24; - - // Header flags - - public static final int FLG_FIRSTFRAG = 0x01; - public static final int FLG_LASTFRAG = 0x02; - public static final int FLG_ONLYFRAG = 0x03; - - // DCE/RPC header constants - - private static final byte HDR_VERSIONMAJOR = 5; - private static final byte HDR_VERSIONMINOR = 0; - private static final int HDR_PACKEDDATAREP = 0x00000010; - - // Offset to DCE/RPC header - - private int m_offset; - - /** - * Construct a DCE/RPC transaction packet - * - * @param buf Buffer that contains the SMB transaction packet. - */ - public DCESrvPacket(byte[] buf) - { - super(buf); - // m_offset = getParameterOffset(); - } - - /** - * Construct a DCE/RPC transaction packet - * - * @param siz Size of packet to allocate. - */ - public DCESrvPacket(int siz) - { - super(siz); - - // Set the multiplex id for this transaction - - setMultiplexId(getNextMultiplexId()); - } - - /** - * Return the major version number - * - * @return int - */ - public final int getMajorVersion() - { - return (int) (getBuffer()[m_offset + VERSIONMAJOR] & 0xFF); - } - - /** - * Return the minor version number - * - * @return int - */ - public final int getMinorVersion() - { - return (int) (getBuffer()[m_offset + VERSIONMINOR] & 0xFF); - } - - /** - * Return the PDU packet type - * - * @return int - */ - public final int getPDUType() - { - return (int) (getBuffer()[m_offset + PDUTYPE] & 0xFF); - } - - /** - * Return the header flags - * - * @return int - */ - public final int getHeaderFlags() - { - return (int) (getBuffer()[m_offset + HEADERFLAGS] & 0xFF); - } - - /** - * Return the packed data representation - * - * @return int - */ - public final int getPackedDataRepresentation() - { - return DataPacker.getIntelInt(getBuffer(), m_offset + PACKEDDATAREP); - } - - /** - * Return the fragment length - * - * @return int - */ - public final int getFragmentLength() - { - return DataPacker.getIntelShort(getBuffer(), m_offset + FRAGMENTLEN); - } - - /** - * Set the fragment length - * - * @param len int - */ - public final void setFragmentLength(int len) - { - - // Set the DCE header fragment length - - DataPacker.putIntelShort(len, getBuffer(), m_offset + FRAGMENTLEN); - } - - /** - * Return the authentication length - * - * @return int - */ - public final int getAuthenticationLength() - { - return DataPacker.getIntelShort(getBuffer(), m_offset + AUTHLEN); - } - - /** - * Return the call id - * - * @return int - */ - public final int getCallId() - { - return DataPacker.getIntelInt(getBuffer(), m_offset + CALLID); - } - - /** - * Determine if this is the first fragment - * - * @return boolean - */ - public final boolean isFirstFragment() - { - if ((getHeaderFlags() & FLG_FIRSTFRAG) != 0) - return true; - return false; - } - - /** - * Determine if this is the last fragment - * - * @return boolean - */ - public final boolean isLastFragment() - { - if ((getHeaderFlags() & FLG_LASTFRAG) != 0) - return true; - return false; - } - - /** - * Determine if this is the only fragment in the request - * - * @return boolean - */ - public final boolean isOnlyFragment() - { - if ((getHeaderFlags() & FLG_ONLYFRAG) == FLG_ONLYFRAG) - return true; - return false; - } - - /** - * Get the offset to the DCE/RPC data within the SMB packet - * - * @return int - */ - public final int getDCEDataOffset() - { - - // Determine the data offset from the DCE/RPC packet type - - int dataOff = -1; - switch (getPDUType()) - { - - // Bind/bind acknowledge - - case DCECommand.BIND: - case DCECommand.BINDACK: - dataOff = m_offset + DCEDATA; - break; - - // Request/response - - case DCECommand.REQUEST: - case DCECommand.RESPONSE: - dataOff = m_offset + OPERATIONDATA; - break; - } - - // Return the data offset - - return dataOff; - } - - /** - * Get the request allocation hint - * - * @return int - */ - public final int getAllocationHint() - { - return DataPacker.getIntelInt(getBuffer(), m_offset + ALLOCATIONHINT); - } - - /** - * Set the allocation hint - * - * @param alloc int - */ - public final void setAllocationHint(int alloc) - { - DataPacker.putIntelInt(alloc, getBuffer(), m_offset + ALLOCATIONHINT); - } - - /** - * Get the request presentation identifier - * - * @return int - */ - public final int getPresentationIdentifier() - { - return DataPacker.getIntelShort(getBuffer(), m_offset + PRESENTIDENT); - } - - /** - * Set the presentation identifier - * - * @param ident int - */ - public final void setPresentationIdentifier(int ident) - { - DataPacker.putIntelShort(ident, getBuffer(), m_offset + PRESENTIDENT); - } - - /** - * Get the request operation id - * - * @return int - */ - public final int getOperationId() - { - return DataPacker.getIntelShort(getBuffer(), m_offset + OPERATIONID); - } - - /** - * Initialize the DCE/RPC request. Set the SMB transaction parameter count so that the data - * offset can be calculated. - * - * @param handle int - * @param typ byte - * @param flags int - * @param callId int - */ - public final void initializeDCERequest(int handle, byte typ, int flags, int callId) - { - - // Initialize the transaction - - InitializeTransact(16, null, 0, null, 0); - - // Set the parameter byte count/offset for this packet - - int bytPos = DCEDataPacker.longwordAlign(getByteOffset()); - - setParameter(3, 0); - setParameter(4, bytPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the parameter displacement - - setParameter(5, 0); - - // Set the data byte count/offset for this packet - - setParameter(6, 0); - setParameter(7, bytPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the data displacement - - setParameter(8, 0); - - // Set up word count - - setParameter(9, 0); - - // Set the setup words - - setSetupParameter(0, PacketType.TransactNmPipe); - setSetupParameter(1, handle); - - // Reset the DCE offset for a DCE reply - - m_offset = bytPos; - - // Build the DCE/RPC header - - byte[] buf = getBuffer(); - DataPacker.putZeros(buf, m_offset, 24); - - buf[m_offset + VERSIONMAJOR] = HDR_VERSIONMAJOR; - buf[m_offset + VERSIONMINOR] = HDR_VERSIONMINOR; - buf[m_offset + PDUTYPE] = typ; - buf[m_offset + HEADERFLAGS] = (byte) (flags & 0xFF); - DataPacker.putIntelInt(HDR_PACKEDDATAREP, buf, m_offset + PACKEDDATAREP); - DataPacker.putIntelInt(0, buf, m_offset + AUTHLEN); - DataPacker.putIntelInt(callId, buf, m_offset + CALLID); - } - - /** - * Initialize the DCE/RPC reply. Set the SMB transaction parameter count so that the data offset - * can be calculated. - */ - public final void initializeDCEReply() - { - - // Set the total parameter words - - setParameterCount(10); - - // Set the total parameter/data bytes - - setParameter(0, 0); - setParameter(1, 0); - - // Set the parameter byte count/offset for this packet - - int bytPos = DCEDataPacker.longwordAlign(getByteOffset()); - - setParameter(3, 0); - setParameter(4, bytPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the parameter displacement - - setParameter(5, 0); - - // Set the data byte count/offset for this packet - - setParameter(6, 0); - setParameter(7, bytPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the data displacement - - setParameter(8, 0); - - // Set up word count - - setParameter(9, 0); - } - - /** - * Dump the DCE/RPC header details - */ - public final void DumpHeader() - { - - // Dump the PDU type - - System.out.println("** DCE/RPC Header - PDU Type = " + DCECommand.getCommandString(getPDUType())); - System.out.println(" Version : " + getMajorVersion() + "." + getMinorVersion()); - System.out.println(" Flags : 0x" + getHeaderFlags()); - System.out.println(" Packed Data Rep : 0x" + getPackedDataRepresentation()); - System.out.println(" Fragment Length : " + getFragmentLength()); - System.out.println(" Auth Length : " + getAuthenticationLength()); - System.out.println(" Call ID : " + getCallId()); - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/SrvsvcDCEHandler.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/SrvsvcDCEHandler.java deleted file mode 100644 index f1d9d8e427..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/SrvsvcDCEHandler.java +++ /dev/null @@ -1,398 +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.smb.dcerpc.server; - -import java.io.IOException; -import java.util.Enumeration; -import java.util.Vector; - -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -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.smb.SMBStatus; -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.Srvsvc; -import org.alfresco.filesys.smb.dcerpc.info.ServerInfo; -import org.alfresco.filesys.smb.dcerpc.info.ShareInfo; -import org.alfresco.filesys.smb.dcerpc.info.ShareInfoList; -import org.alfresco.filesys.smb.server.SMBServer; -import org.alfresco.filesys.smb.server.SMBSrvException; -import org.alfresco.filesys.smb.server.SMBSrvSession; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Srvsvc DCE/RPC Handler Class - */ -public class SrvsvcDCEHandler implements DCEHandler -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - /** - * Process a SrvSvc DCE/RPC request - * - * @param sess SMBSrvSession - * @param inBuf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public void processRequest(SMBSrvSession sess, DCEBuffer inBuf, DCEPipeFile pipeFile) throws IOException, - SMBSrvException - { - - // Get the operation code and move the buffer pointer to the start of the request data - - int opNum = inBuf.getHeaderValue(DCEBuffer.HDR_OPCODE); - try - { - inBuf.skipBytes(DCEBuffer.OPERATIONDATA); - } - catch (DCEBufferException ex) - { - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("DCE/RPC SrvSvc request=" + Srvsvc.getOpcodeName(opNum)); - - // Create the output DCE buffer and add the response header - - DCEBuffer outBuf = new DCEBuffer(); - outBuf.putResponseHeader(inBuf.getHeaderValue(DCEBuffer.HDR_CALLID), 0); - - // Process the request - - boolean processed = false; - - switch (opNum) - { - - // Enumerate shares - - case Srvsvc.NetrShareEnum: - processed = netShareEnum(sess, inBuf, outBuf); - break; - - // Enumerate all shares - - case Srvsvc.NetrShareEnumSticky: - processed = netShareEnum(sess, inBuf, outBuf); - break; - - // Get share information - - case Srvsvc.NetrShareGetInfo: - processed = netShareGetInfo(sess, inBuf, outBuf); - break; - - // Get server information - - case Srvsvc.NetrServerGetInfo: - processed = netServerGetInfo(sess, inBuf, outBuf); - break; - - // Unsupported function - - default: - break; - } - - // Return an error status if the request was not processed - - if (processed == false) - { - sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Set the allocation hint for the response - - outBuf.setHeaderValue(DCEBuffer.HDR_ALLOCHINT, outBuf.getLength()); - - // Attach the output buffer to the pipe file - - pipeFile.setBufferedData(outBuf); - } - - /** - * Handle a share enumeration request - * - * @param sess SMBSrvSession - * @param inBuf DCEPacket - * @param outBuf DCEPacket - * @return boolean - */ - protected final boolean netShareEnum(SMBSrvSession sess, DCEBuffer inBuf, DCEBuffer outBuf) - { - - // Decode the request - - String srvName = null; - ShareInfoList shrInfo = null; - - try - { - inBuf.skipPointer(); - srvName = inBuf.getString(DCEBuffer.ALIGN_INT); - shrInfo = new ShareInfoList(inBuf); - } - catch (DCEBufferException ex) - { - return false; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("NetShareEnum srvName=" + srvName + ", shrInfo=" + shrInfo.toString()); - - // Get the share list from the server - - SharedDeviceList shareList = sess.getServer().getShareMapper().getShareList(srvName, sess, false); - - // Check if there is an access control manager configured - - if (sess.getServer().hasAccessControlManager()) - { - - // Filter the list of available shares by applying any access control rules - - AccessControlManager aclMgr = sess.getServer().getAccessControlManager(); - - shareList = aclMgr.filterShareList(sess, shareList); - } - - // Create a list of share information objects of the required information level - - Vector infoList = new Vector(); - Enumeration enm = shareList.enumerateShares(); - - while (enm.hasMoreElements()) - { - - // Get the current shared device details - - SharedDevice share = enm.nextElement(); - - // Determine the share type - - int shrTyp = ShareInfo.Disk; - - if (share.getType() == ShareType.PRINTER) - shrTyp = ShareInfo.PrintQueue; - else if (share.getType() == ShareType.NAMEDPIPE) - shrTyp = ShareInfo.IPC; - else if (share.getType() == ShareType.ADMINPIPE) - shrTyp = ShareInfo.IPC + ShareInfo.Hidden; - - // Create a share information object with the basic information - - ShareInfo info = new ShareInfo(shrInfo.getInformationLevel(), share.getName(), shrTyp, share.getComment()); - infoList.add(info); - - // Add additional information - - switch (shrInfo.getInformationLevel()) - { - - // Level 2 - - case 2: - if (share.getContext() != null) - info.setPath(share.getContext().getDeviceName()); - break; - - // Level 502 - - case 502: - if (share.getContext() != null) - info.setPath(share.getContext().getDeviceName()); - break; - } - } - - // Set the share information list in the server share information and write the - // share information to the output DCE buffer. - - shrInfo.setShareList(infoList); - try - { - shrInfo.writeList(outBuf); - outBuf.putInt(0); // status code - } - catch (DCEBufferException ex) - { - } - - // Indicate that the request was processed successfully - - return true; - } - - /** - * Handle a get share information request - * - * @param sess SMBSrvSession - * @param inBuf DCEPacket - * @param outBuf DCEPacket - * @return boolean - */ - protected final boolean netShareGetInfo(SMBSrvSession sess, DCEBuffer inBuf, DCEBuffer outBuf) - { - - // Decode the request - - String srvName = null; - String shrName = null; - int infoLevel = 0; - - try - { - inBuf.skipPointer(); - srvName = inBuf.getString(DCEBuffer.ALIGN_INT); - shrName = inBuf.getString(DCEBuffer.ALIGN_INT); - infoLevel = inBuf.getInt(); - } - catch (DCEBufferException ex) - { - return false; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("netShareGetInfo srvname=" + srvName + ", share=" + shrName + ", infoLevel=" + infoLevel); - - // Find the required shared device - - SharedDevice share = null; - - try - { - - // Get the shared device details - - share = sess.getServer().findShare(srvName, shrName, ShareType.UNKNOWN, sess, false); - } - catch (Exception ex) - { - } - - // Check if the share details are valid - - if (share == null) - return false; - - // Determine the share type - - int shrTyp = ShareInfo.Disk; - - if (share.getType() == ShareType.PRINTER) - shrTyp = ShareInfo.PrintQueue; - else if (share.getType() == ShareType.NAMEDPIPE) - shrTyp = ShareInfo.IPC; - else if (share.getType() == ShareType.ADMINPIPE) - shrTyp = ShareInfo.IPC + ShareInfo.Hidden; - - // Create the share information - - ShareInfo shrInfo = new ShareInfo(infoLevel, share.getName(), shrTyp, share.getComment()); - - // Pack the information level, structure pointer and share information - - outBuf.putInt(infoLevel); - outBuf.putPointer(true); - - shrInfo.writeObject(outBuf, outBuf); - - // Add the status and return a success status - - outBuf.putInt(0); - return true; - } - - /** - * Handle a get server information request - * - * @param sess SMBSrvSession - * @param inBuf DCEPacket - * @param outBuf DCEPacket - * @return boolean - */ - protected final boolean netServerGetInfo(SMBSrvSession sess, DCEBuffer inBuf, DCEBuffer outBuf) - { - - // Decode the request - - String srvName = null; - int infoLevel = 0; - - try - { - inBuf.skipPointer(); - srvName = inBuf.getString(DCEBuffer.ALIGN_INT); - infoLevel = inBuf.getInt(); - } - catch (DCEBufferException ex) - { - return false; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("netServerGetInfo srvname=" + srvName + ", infoLevel=" + infoLevel); - - // Create the server information and set the common values - - ServerInfo srvInfo = new ServerInfo(infoLevel); - - SMBServer srv = sess.getSMBServer(); - srvInfo.setServerName(srv.getServerName()); - srvInfo.setComment(srv.getComment()); - srvInfo.setServerType(srv.getServerType()); - - // Return the platform id as Windows NT - - srvInfo.setPlatformId(ServerInfo.PLATFORM_NT); - srvInfo.setVersion(5, 1); - - // Write the server information to the DCE response - - srvInfo.writeObject(outBuf, outBuf); - outBuf.putInt(0); - - // Indicate that the request was processed successfully - - return true; - } -} diff --git a/source/java/org/alfresco/filesys/smb/dcerpc/server/WkssvcDCEHandler.java b/source/java/org/alfresco/filesys/smb/dcerpc/server/WkssvcDCEHandler.java deleted file mode 100644 index 8520a72bda..0000000000 --- a/source/java/org/alfresco/filesys/smb/dcerpc/server/WkssvcDCEHandler.java +++ /dev/null @@ -1,175 +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.smb.dcerpc.server; - -import java.io.IOException; - -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.Wkssvc; -import org.alfresco.filesys.smb.dcerpc.info.ServerInfo; -import org.alfresco.filesys.smb.dcerpc.info.WorkstationInfo; -import org.alfresco.filesys.smb.server.SMBServer; -import org.alfresco.filesys.smb.server.SMBSrvException; -import org.alfresco.filesys.smb.server.SMBSrvSession; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Wkssvc DCE/RPC Handler Class - */ -public class WkssvcDCEHandler implements DCEHandler -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - /** - * Process a WksSvc DCE/RPC request - * - * @param sess SMBSrvSession - * @param inBuf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public void processRequest(SMBSrvSession sess, DCEBuffer inBuf, DCEPipeFile pipeFile) throws IOException, - SMBSrvException - { - - // Get the operation code and move the buffer pointer to the start of the request data - - int opNum = inBuf.getHeaderValue(DCEBuffer.HDR_OPCODE); - try - { - inBuf.skipBytes(DCEBuffer.OPERATIONDATA); - } - catch (DCEBufferException ex) - { - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("DCE/RPC WksSvc request=" + Wkssvc.getOpcodeName(opNum)); - - // Create the output DCE buffer and add the response header - - DCEBuffer outBuf = new DCEBuffer(); - outBuf.putResponseHeader(inBuf.getHeaderValue(DCEBuffer.HDR_CALLID), 0); - - // Process the request - - boolean processed = false; - - switch (opNum) - { - - // Get workstation information - - case Wkssvc.NetWkstaGetInfo: - processed = netWkstaGetInfo(sess, inBuf, outBuf); - break; - - // Unsupported function - - default: - break; - } - - // Return an error status if the request was not processed - - if (processed == false) - { - sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Set the allocation hint for the response - - outBuf.setHeaderValue(DCEBuffer.HDR_ALLOCHINT, outBuf.getLength()); - - // Attach the output buffer to the pipe file - - pipeFile.setBufferedData(outBuf); - } - - /** - * Get workstation infomation - * - * @param sess SMBSrvSession - * @param inBuf DCEPacket - * @param outBuf DCEPacket - * @return boolean - */ - protected final boolean netWkstaGetInfo(SMBSrvSession sess, DCEBuffer inBuf, DCEBuffer outBuf) - { - - // Decode the request - - String srvName = null; - int infoLevel = 0; - - try - { - inBuf.skipPointer(); - srvName = inBuf.getString(DCEBuffer.ALIGN_INT); - infoLevel = inBuf.getInt(); - } - catch (DCEBufferException ex) - { - return false; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("NetWkstaGetInfo srvName=" + srvName + ", infoLevel=" + infoLevel); - - // Create the workstation information and set the common values - - WorkstationInfo wkstaInfo = new WorkstationInfo(infoLevel); - - SMBServer srv = sess.getSMBServer(); - wkstaInfo.setWorkstationName(srv.getServerName()); - wkstaInfo.setDomain(srv.getConfiguration().getDomainName()); - - // Return the platform type as Windows NT - - wkstaInfo.setPlatformId(ServerInfo.PLATFORM_NT); - wkstaInfo.setVersion(5, 1); - - // Write the server information to the DCE response - - wkstaInfo.writeObject(outBuf, outBuf); - outBuf.putInt(0); - - // Indicate that the request was processed successfully - - return true; - } -} diff --git a/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java b/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java deleted file mode 100644 index 904ea77bbc..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/HostAnnouncer.java +++ /dev/null @@ -1,555 +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.smb.mailslot; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; -import org.alfresco.filesys.smb.ServerType; -import org.alfresco.filesys.smb.TransactionNames; -import org.alfresco.filesys.util.StringList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - *

- * The host announcer class periodically broadcasts a host announcement datagram to inform other - * Windows networking hosts of the local hosts existence and capabilities. - */ -public abstract class HostAnnouncer extends Thread -{ - - // Debug logging - - protected static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.mailslot"); - - // Shutdown announcement interval and message count - - public static final int SHUTDOWN_WAIT = 2000; // 2 seconds - public static final int SHUTDOWN_COUNT = 3; - - // Starting announcement interval, doubles until it reaches the configured interval - - public static final long STARTING_INTERVAL = 5000; // 5 seconds - - // Local host name(s) to announce - - private StringList m_names; - - // Domain to announce to - - private String m_domain; - - // Server comment string - - private String m_comment; - - // Announcement interval in minutes - - private int m_interval; - - // Server type flags, see org.alfresco.filesys.smb.SMBServerInfo - - private int m_srvtype = ServerType.WorkStation + ServerType.Server; - - // SMB mailslot packet - - private SMBMailslotPacket m_smbPkt; - - // Update count for the host announcement packet - - private byte m_updateCount; - - // Error count - - private int m_errorCount; - - // Shutdown flag, host announcer should remove the announced name as it shuts down - - private boolean m_shutdown = false; - - // Debug output enable - - private boolean m_debug; - - /** - * HostAnnouncer constructor. - */ - public HostAnnouncer() - { - - // Common constructor - - commonConstructor(); - } - - /** - * Create a host announcer. - * - * @param name Host name to announce - * @param domain Domain name to announce to - * @param intval Announcement interval, in minutes - */ - public HostAnnouncer(String name, String domain, int intval) - { - - // Common constructor - - commonConstructor(); - - // Add the host to the list of names to announce - - addHostName(name); - setDomain(domain); - setInterval(intval); - } - - /** - * Common constructor code - */ - private final void commonConstructor() - { - - // Allocate the host name list - - m_names = new StringList(); - } - - /** - * Return the server comment string. - * - * @return java.lang.String - */ - public final String getComment() - { - return m_comment; - } - - /** - * Return the domain name that the host announcement is directed to. - * - * @return java.lang.String - */ - public final String getDomain() - { - return m_domain; - } - - /** - * Return the number of names being announced - * - * @return int - */ - public final int numberOfNames() - { - return m_names.numberOfStrings(); - } - - /** - * Return the error count - * - * @return int - */ - protected final int getErrorCount() - { - return m_errorCount; - } - - /** - * Return the specified host name being announced. - * - * @param idx int - * @return java.lang.String - */ - public final String getHostName(int idx) - { - if (idx < 0 || idx > m_names.numberOfStrings()) - return null; - return m_names.getStringAt(idx); - } - - /** - * Return the announcement interval, in minutes. - * - * @return int - */ - public final int getInterval() - { - return m_interval; - } - - /** - * Return the server type flags. - * - * @return int - */ - public final int getServerType() - { - return m_srvtype; - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Enable/disable debug output - * - * @param dbg true or false - */ - public final void setDebug(boolean dbg) - { - m_debug = dbg; - } - - /** - * Initialize the host announcement SMB. - * - * @param name String - */ - protected final void initHostAnnounceSMB(String name) - { - - // Allocate the transact SMB - - if (m_smbPkt == null) - m_smbPkt = new SMBMailslotPacket(); - - // Create the host announcement structure - - byte[] data = new byte[256]; - int pos = MailSlot.createHostAnnouncement(data, 0, name, m_comment, m_srvtype, m_interval, m_updateCount++); - - // Create the mailslot SMB - - m_smbPkt.initializeMailslotSMB(TransactionNames.MailslotBrowse, data, pos); - } - - /** - * Start the host announcer thread. - */ - public void run() - { - - // Initialize the host announcer - - try - { - - // Initialize the host announcer datagram socket - - initialize(); - } - catch (Exception ex) - { - - // Debug - - logger.error("HostAnnouncer initialization error", ex); - return; - } - - // Clear the shutdown flag - - m_shutdown = false; - - // Send the host announcement datagram - - long sleepTime = STARTING_INTERVAL; - long sleepNormal = getInterval() * 60 * 1000; - - while (m_shutdown == false) - { - - try - { - - // Check if the network connection is valid - - if (isNetworkEnabled()) - { - - // Loop through the host names to be announced - - for (int i = 0; i < m_names.numberOfStrings(); i++) - { - - // Create a host announcement transact SMB - - String hostName = getHostName(i); - initHostAnnounceSMB(hostName); - - // Send the host announce datagram - - sendAnnouncement(hostName, m_smbPkt.getBuffer(), 0, m_smbPkt.getLength()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("HostAnnouncer: Announced host " + hostName); - } - } - else - { - - // Reset the sleep interval to the starting interval as the network connection - // is not - // available - - sleepTime = STARTING_INTERVAL; - } - - // Sleep for a while - - sleep(sleepTime); - - // Update the sleep interval, if the network connection is enabled - - if (isNetworkEnabled() && sleepTime < sleepNormal) - { - - // Double the sleep interval until it exceeds the configured announcement - // interval. - // This is to send out more broadcasts when the server first starts. - - sleepTime *= 2; - if (sleepTime > sleepNormal) - sleepTime = sleepNormal; - } - } - catch (WinsockNetBIOSException ex) - { - // Debug - - if (m_shutdown == false) - logger.error("HostAnnouncer error", ex); - m_shutdown = true; - } - catch ( IOException ex) - { - // Debug - - if (m_shutdown == false) - { - logger.error("HostAnnouncer error", ex); - logger.error(" Check setting in file-servers.xml"); - } - m_shutdown = true; - } - catch (Exception ex) - { - // Debug - - if (m_shutdown == false) - logger.error("HostAnnouncer error", ex); - m_shutdown = true; - } - } - - // Set the announcement interval to zero to indicate that the host is leaving Network - // Neighborhood - - setInterval(0); - - // Clear the server flag in the announced host type - - if ((m_srvtype & ServerType.Server) != 0) - m_srvtype -= ServerType.Server; - - // Send out a number of host announcement to remove the host name(s) from Network - // Neighborhood - - for (int j = 0; j < SHUTDOWN_COUNT; j++) - { - - // Loop through the host names to be announced - - for (int i = 0; i < m_names.numberOfStrings(); i++) - { - - // Create a host announcement transact SMB - - String hostName = getHostName(i); - initHostAnnounceSMB(hostName); - - // Send the host announce datagram - - try - { - - // Send the host announcement - - sendAnnouncement(hostName, m_smbPkt.getBuffer(), 0, m_smbPkt.getLength()); - } - catch (Exception ex) - { - } - } - - // Sleep for a while - - try - { - sleep(SHUTDOWN_WAIT); - } - catch (InterruptedException ex) - { - } - } - } - - /** - * Initialize the host announcer. - * - * @exception Exception - */ - protected void initialize() throws Exception - { - } - - /** - * Determine if the network connection used for the host announcement is valid - * - * @return boolean - */ - public abstract boolean isNetworkEnabled(); - - /** - * Send an announcement broadcast. - * - * @param hostName Host name being announced - * @param buf Buffer containing the host announcement mailslot message. - * @param offset Offset to the start of the host announcement message. - * @param len Host announcement message length. - */ - protected abstract void sendAnnouncement(String hostName, byte[] buf, int offset, int len) throws Exception; - - /** - * Set the server comment string. - * - * @param comment java.lang.String - */ - public final void setComment(String comment) - { - m_comment = comment; - if (m_comment != null && m_comment.length() > 80) - m_comment = m_comment.substring(0, 80); - } - - /** - * Set the domain name that the host announcement are directed to. - * - * @param name java.lang.String - */ - public final void setDomain(String name) - { - m_domain = name.toUpperCase(); - } - - /** - * Add a host name to the list of names to announce - * - * @param name java.lang.String - */ - public final void addHostName(String name) - { - m_names.addString(NetBIOSName.toUpperCaseName(name)); - } - - /** - * Add a list of names to the announcement list - * - * @param names StringList - */ - public final void addHostNames(StringList names) - { - m_names.addStrings(names); - } - - /** - * Set the announcement interval, in minutes. - * - * @param intval int - */ - public final void setInterval(int intval) - { - m_interval = intval; - } - - /** - * Set the server type flags. - * - * @param typ int - */ - public final void setServerType(int typ) - { - m_srvtype = typ; - } - - /** - * Increment the error count - * - * @return int - */ - protected final int incrementErrorCount() - { - return ++m_errorCount; - } - - /** - * Clear the error count - */ - protected final void clearErrorCount() - { - m_errorCount = 0; - } - - /** - * Shutdown the host announcer and remove the announced name from Network Neighborhood. - */ - public final synchronized void shutdownAnnouncer() - { - - // Set the shutdown flag and wakeup the main host announcer thread - - m_shutdown = true; - interrupt(); - - try - { - join(2000); - } - catch (InterruptedException ex) - { - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/mailslot/MailSlot.java b/source/java/org/alfresco/filesys/smb/mailslot/MailSlot.java deleted file mode 100644 index 28772f7fab..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/MailSlot.java +++ /dev/null @@ -1,148 +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.smb.mailslot; - -import org.alfresco.filesys.util.DataPacker; - -/** - * Mail slot constants class. - */ -public final class MailSlot -{ - - // Mail slot opcodes - - public static final int WRITE = 0x01; - - // Mail slot classes - - public static final int UNRELIABLE = 0x02; - - // Mailslot \MAILSLOT\BROWSE opcodes - - public static final int HostAnnounce = 1; - public static final int AnnouncementRequest = 2; - public static final int RequestElection = 8; - public static final int GetBackupListReq = 9; - public static final int GetBackupListResp = 10; - public static final int BecomeBackup = 11; - public static final int DomainAnnouncement = 12; - public static final int MasterAnnouncement = 13; - public static final int LocalMasterAnnouncement = 15; - - /** - * Create a host announcement mailslot structure - * - * @param buf byte[] - * @param off int - * @param host String - * @param comment String - * @param typ int - * @param interval int - * @param upd int - * @return int - */ - public final static int createHostAnnouncement(byte[] buf, int off, String host, String comment, int typ, - int interval, int upd) - { - - // Set the command code and update count - - buf[off] = MailSlot.HostAnnounce; - buf[off + 1] = 0; // (byte) (upd & 0xFF); - - // Set the announce interval, in minutes - - DataPacker.putIntelInt(interval * 60000, buf, off + 2); - - // Pack the host name - - byte[] hostByt = host.getBytes(); - for (int i = 0; i < 16; i++) - { - if (i < hostByt.length) - buf[off + 6 + i] = hostByt[i]; - else - buf[off + 6 + i] = 0; - } - - // Major/minor version number - - buf[off + 22] = 5; // major version - buf[off + 23] = 1; // minor version - - // Set the server type flags - - DataPacker.putIntelInt(typ, buf, off + 24); - - // Browser election version and browser constant - - DataPacker.putIntelShort(0x010F, buf, off + 28); - DataPacker.putIntelShort(0xAA55, buf, off + 30); - - // Add the server comment string, or a null string - - int pos = off + 33; - - if (comment != null) - pos = DataPacker.putString(comment, buf, off + 32, true); - - // Return the end of data position - - return pos; - } - - /** - * Create an announcement request mailslot structure - * - * @param buf byte[] - * @param off int - * @param host String - * @return int - */ - public final static int createAnnouncementRequest(byte[] buf, int off, String host) - { - - // Set the command code - - buf[off] = MailSlot.AnnouncementRequest; - buf[off + 1] = 0; - - // Pack the host name - - byte[] hostByt = host.getBytes(); - for (int i = 0; i < 16; i++) - { - if (i < hostByt.length) - buf[off + 2 + i] = hostByt[i]; - else - buf[off + 2 + i] = 0; - } - - // Return the end of buffer position - - return off + 17; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/mailslot/SMBMailslotPacket.java b/source/java/org/alfresco/filesys/smb/mailslot/SMBMailslotPacket.java deleted file mode 100644 index 1c6532ad47..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/SMBMailslotPacket.java +++ /dev/null @@ -1,993 +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.smb.mailslot; - -import org.alfresco.filesys.util.DataPacker; - -/** - * SMB Mailslot Packet Class - */ -public class SMBMailslotPacket -{ - // SMB packet offsets - - public static final int SIGNATURE = 0; - public static final int COMMAND = 4; - public static final int ERRORCODE = 5; - public static final int ERRORCLASS = 5; - public static final int ERROR = 7; - public static final int FLAGS = 9; - public static final int FLAGS2 = 10; - public static final int PIDHIGH = 12; - public static final int SID = 18; - public static final int SEQNO = 20; - public static final int TID = 24; - public static final int PID = 26; - public static final int UID = 28; - public static final int MID = 30; - public static final int WORDCNT = 32; - public static final int ANDXCOMMAND = 33; - public static final int ANDXRESERVED= 34; - public static final int PARAMWORDS = 33; - - // SMB packet header length for a transaction type request - - public static final int TRANS_HEADERLEN = 66; - - // Minimum receive length for a valid SMB packet - - public static final int MIN_RXLEN = 32; - - // Default buffer size to allocate for SMB mailslot packets - - public static final int DEFAULT_BUFSIZE = 500; - - // Flag bits - - public static final int FLG_SUBDIALECT = 0x01; - public static final int FLG_CASELESS = 0x08; - public static final int FLG_CANONICAL = 0x10; - public static final int FLG_OPLOCK = 0x20; - public static final int FLG_NOTIFY = 0x40; - public static final int FLG_RESPONSE = 0x80; - - // Flag2 bits - - public static final int FLG2_LONGFILENAMES = 0x0001; - public static final int FLG2_EXTENDEDATTRIB = 0x0002; - public static final int FLG2_READIFEXE = 0x2000; - public static final int FLG2_LONGERRORCODE = 0x4000; - public static final int FLG2_UNICODE = 0x8000; - - // SMB packet buffer and offset - - private byte[] m_smbbuf; - private int m_offset; - - // Define the number of standard parameters for a server response - - private static final int STD_PARAMS = 14; - - // SMB packet types we expect to receive in a mailslot - - public static final int Transaction = 0x25; - public static final int Transaction2 = 0x32; - - /** - * Default constructor - */ - public SMBMailslotPacket() - { - m_smbbuf = new byte[DEFAULT_BUFSIZE]; - m_offset = 0; - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public SMBMailslotPacket(byte[] buf) - { - m_smbbuf = buf; - m_offset = 0; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param off int - */ - public SMBMailslotPacket(byte[] buf, int off) - { - m_smbbuf = buf; - m_offset = off; - } - - /** - * Reset the mailslot packet to use the specified buffer and offset - * - * @param buf byte[] - * @param offset int - */ - public final void resetPacket(byte[] buf, int offset) - { - m_smbbuf = buf; - m_offset = offset; - } - - /** - * Get the secondary command code - * - * @return Secondary command code - */ - public final int getAndXCommand() - { - return (int) (m_smbbuf[ANDXCOMMAND + m_offset] & 0xFF); - } - - /** - * Return the byte array used for the SMB packet - * - * @return Byte array used for the SMB packet. - */ - public final byte[] getBuffer() - { - return m_smbbuf; - } - - /** - * Return the total buffer size available to the SMB request - * - * @return Total SMB buffer length available. - */ - public final int getBufferLength() - { - return m_smbbuf.length - m_offset; - } - - /** - * Get the data byte count for the SMB packet - * - * @return Data byte count - */ - public final int getByteCount() - { - - // Calculate the offset of the byte count - - int pos = PARAMWORDS + (2 * getParameterCount()); - return (int) DataPacker.getIntelShort(m_smbbuf, pos); - } - - /** - * Get the data byte area offset within the SMB packet - * - * @return Data byte offset within the SMB packet. - */ - public final int getByteOffset() - { - - // Calculate the offset of the byte buffer - - int pCnt = getParameterCount(); - int pos = WORDCNT + (2 * pCnt) + 3 + m_offset; - return pos; - } - - /** - * Get the SMB command - * - * @return SMB command code. - */ - public final int getCommand() - { - return (int) (m_smbbuf[COMMAND + m_offset] & 0xFF); - } - - /** - * Determine if normal or long error codes have been returned - * - * @return boolean - */ - public final boolean hasLongErrorCode() - { - if ((getFlags2() & FLG2_LONGERRORCODE) == 0) - return false; - return true; - } - - /** - * Get the SMB error class - * - * @return SMB error class. - */ - public final int getErrorClass() - { - return (int) m_smbbuf[ERRORCLASS + m_offset] & 0xFF; - } - - /** - * Get the SMB error code - * - * @return SMB error code. - */ - public final int getErrorCode() - { - return (int) m_smbbuf[ERROR + m_offset] & 0xFF; - } - - /** - * Get the SMB flags value. - * - * @return SMB flags value. - */ - public final int getFlags() - { - return (int) m_smbbuf[FLAGS + m_offset] & 0xFF; - } - - /** - * Get the SMB flags2 value. - * - * @return SMB flags2 value. - */ - public final int getFlags2() - { - return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2 + m_offset); - } - - /** - * Calculate the total used packet length. - * - * @return Total used packet length. - */ - public final int getLength() - { - return (getByteOffset() + getByteCount()) - m_offset; - } - - /** - * Get the long SMB error code - * - * @return Long SMB error code. - */ - public final int getLongErrorCode() - { - return DataPacker.getIntelInt(m_smbbuf, ERRORCODE + m_offset); - } - - /** - * Get the multiplex identifier. - * - * @return Multiplex identifier. - */ - public final int getMultiplexId() - { - return DataPacker.getIntelShort(m_smbbuf, MID + m_offset); - } - - /** - * Get a parameter word from the SMB packet. - * - * @param idx Parameter index (zero based). - * @return Parameter word value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getParameterCount()) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = WORDCNT + (2 * idx) + 1 + m_offset; - return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); - } - - /** - * Get the parameter count - * - * @return Parameter word count. - */ - public final int getParameterCount() - { - return (int) m_smbbuf[WORDCNT + m_offset]; - } - - /** - * Get the process indentifier (PID) - * - * @return Process identifier value. - */ - public final int getProcessId() - { - return DataPacker.getIntelShort(m_smbbuf, PID + m_offset); - } - - /** - * Get the tree identifier (TID) - * - * @return Tree identifier (TID) - */ - public final int getTreeId() - { - return DataPacker.getIntelShort(m_smbbuf, TID + m_offset); - } - - /** - * Get the user identifier (UID) - * - * @return User identifier (UID) - */ - public final int getUserId() - { - return DataPacker.getIntelShort(m_smbbuf, UID + m_offset); - } - - /** - * Return the offset to the data block within the SMB packet. The data block is word aligned - * within the byte buffer area of the SMB packet. This method must be called after the parameter - * count and parameter block length have been set. - * - * @return int Offset to the data block area. - */ - public final int getDataBlockOffset() - { - - // Get the position of the parameter block - - int pos = (getParameterBlockOffset() + getParameter(3)) + m_offset; - if ((pos & 0x01) != 0) - pos++; - return pos; - } - - /** - * Return the offset to the data block within the SMB packet. The data block is word aligned - * within the byte buffer area of the SMB packet. This method must be called after the parameter - * count has been set. - * - * @param prmLen Parameter block length, in bytes. - * @return int Offset to the data block area. - */ - public final int getDataBlockOffset(int prmLen) - { - - // Get the position of the parameter block - - int pos = getParameterBlockOffset() + prmLen; - if ((pos & 0x01) != 0) - pos++; - return pos; - } - - /** - * Return the parameter block offset where the parameter bytes should be placed. This method - * must be called after the paramter count has been set. The parameter offset is word aligned. - * - * @return int Offset to the parameter block area. - */ - public final int getParameterBlockOffset() - { - - // Get the offset to the byte buffer area of the SMB packet - - int pos = getByteOffset() + m_offset; - if ((pos & 0x01) != 0) - pos++; - return pos; - } - - /** - * Return the data block offset. - * - * @return int Offset to data block within packet. - */ - public final int getRxDataBlock() - { - return getParameter(12) + m_offset; - } - - /** - * Return the received transaction data block length. - * - * @return int - */ - public final int getRxDataBlockLength() - { - return getParameter(11); - } - - /** - * Get the required transact parameter word (16 bit). - * - * @param prmIdx int - * @return int - */ - public final int getRxParameter(int prmIdx) - { - - // Get the parameter block offset - - int pos = getRxParameterBlock(); - - // Get the required transact parameter word. - - pos += prmIdx * 2; // 16 bit words - return DataPacker.getIntelShort(getBuffer(), pos); - } - - /** - * Return the position of the parameter block within the received packet. - * - * @param prmblk Array to unpack the parameter block words into. - */ - public final int getRxParameterBlock() - { - - // Get the offset to the parameter words - - return getParameter(10) + m_offset; - } - - /** - * Return the received transaction parameter block length. - * - * @return int - */ - public final int getRxParameterBlockLength() - { - return getParameter(9); - } - - /** - * Return the received transaction setup parameter count. - * - * @return int - */ - public final int getRxParameterCount() - { - return getParameterCount() - STD_PARAMS; - } - - /** - * Get the required transact parameter int value (32-bit). - * - * @param prmIdx int - * @return int - */ - public final int getRxParameterInt(int prmIdx) - { - - // Get the parameter block offset - - int pos = getRxParameterBlock(); - - // Get the required transact parameter word. - - pos += prmIdx * 2; // 16 bit words - return DataPacker.getIntelInt(getBuffer(), pos); - } - - /** - * Get the required transact parameter string. - * - * @param pos Offset to the string within the parameter block. - * @return int - */ - public final String getRxParameterString(int pos) - { - - // Get the parameter block offset - - pos += getRxParameterBlock(); - - // Get the transact parameter string - - byte[] buf = getBuffer(); - int len = (buf[pos++] & 0x00FF); - return DataPacker.getString(buf, pos, len); - } - - /** - * Get the required transact parameter string. - * - * @param pos Offset to the string within the parameter block. - * @param len Length of the string. - * @return int - */ - public final String getRxParameterString(int pos, int len) - { - - // Get the parameter block offset - - pos += getRxParameterBlock(); - - // Get the transact parameter string - - byte[] buf = getBuffer(); - return DataPacker.getString(buf, pos, len); - } - - /** - * Return the received transaction name. - * - * @return java.lang.String - */ - public final String getRxTransactName() - { - - // Check if the transaction has a name - - if (getCommand() == Transaction2) - return ""; - - // Unpack the transaction name string - - int pos = getByteOffset(); - return DataPacker.getString(getBuffer(), pos, getByteCount()); - } - - /** - * Return the specified transaction setup parameter. - * - * @param idx Setup parameter index. - */ - public final int getSetupParameter(int idx) throws java.lang.ArrayIndexOutOfBoundsException - { - - // Check if the setup parameter index is valid - - if (idx >= getRxParameterCount()) - throw new java.lang.ArrayIndexOutOfBoundsException(); - - // Get the setup parameter - - return getParameter(idx + STD_PARAMS); - } - - /** - * Return the mailslot opcode - * - * @return int - */ - public final int getMailslotOpcode() - { - try - { - return getSetupParameter(0); - } - catch (ArrayIndexOutOfBoundsException ex) - { - } - return -1; - } - - /** - * Return the mailslot priority - * - * @return int - */ - public final int getMailslotPriority() - { - try - { - return getSetupParameter(1); - } - catch (ArrayIndexOutOfBoundsException ex) - { - } - return -1; - } - - /** - * Return the mailslot class of service - * - * @return int - */ - public final int getMailslotClass() - { - try - { - return getSetupParameter(2); - } - catch (ArrayIndexOutOfBoundsException ex) - { - } - return -1; - } - - /** - * Return the mailslot sub-opcode, the first byte from the mailslot data - * - * @return int - */ - public final int getMailslotSubOpcode() - { - return (int) (m_smbbuf[getMailslotDataOffset()] & 0xFF); - } - - /** - * Return the mailslot data offset - * - * @return int - */ - public final int getMailslotDataOffset() - { - return getRxDataBlock(); - } - - /** - * Initialize a mailslot SMB - * - * @param name Mailslot name - * @param data Request data bytes - * @param dlen Data length - */ - public final void initializeMailslotSMB(String name, byte[] data, int dlen) - { - - // Initialize the SMB packet header - - initializeBuffer(); - - // Clear header values - - setFlags(0); - setFlags2(0); - setUserId(0); - setMultiplexId(0); - setTreeId(0); - setProcessId(0); - - // Initialize the transaction - - initializeTransact(name, 17, null, 0, data, dlen); - - // Initialize the transactin setup parameters for a mailslot write - - setSetupParameter(0, MailSlot.WRITE); - setSetupParameter(1, 1); - setSetupParameter(2, MailSlot.UNRELIABLE); - } - - /** - * Initialize the transact SMB packet - * - * @param name Transaction name - * @param pcnt Total parameter count for this transaction - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - */ - protected final void initializeTransact(String name, int pcnt, byte[] paramblk, int plen, byte[] datablk, int dlen) - { - - // Set the SMB command code - - if (name == null) - setCommand(Transaction2); - else - setCommand(Transaction); - - // Set the parameter count - - setParameterCount(pcnt); - - // Initialize the parameters - - setParameter(0, plen); // total parameter bytes being sent - setParameter(1, dlen); // total data bytes being sent - - for (int i = 2; i < 9; setParameter(i++, 0)) - ; - - setParameter(6, 1000); // timeout 1 second - setParameter(9, plen); // parameter bytes sent in this packet - setParameter(11, dlen); // data bytes sent in this packet - - setParameter(13, pcnt - STD_PARAMS); // number of setup words - - // Get the data byte offset - - int pos = getByteOffset(); - int startPos = pos; - - // Check if this is a named transaction, if so then store the name - - int idx; - byte[] buf = getBuffer(); - - if (name != null) - { - - // Store the transaction name - - byte[] nam = name.getBytes(); - - for (idx = 0; idx < nam.length; idx++) - buf[pos++] = nam[idx]; - } - - // Word align the buffer offset - - if ((pos % 2) > 0) - pos++; - - // Store the parameter block - - if (paramblk != null) - { - - // Set the parameter block offset - - setParameter(10, pos - m_offset); - - // Store the parameter block - - for (idx = 0; idx < plen; idx++) - buf[pos++] = paramblk[idx]; - } - else - { - - // Clear the parameter block offset - - setParameter(10, 0); - } - - // Word align the data block - - if ((pos % 2) > 0) - pos++; - - // Store the data block - - if (datablk != null) - { - - // Set the data block offset - - setParameter(12, pos - m_offset); - - // Store the data block - - for (idx = 0; idx < dlen; idx++) - buf[pos++] = datablk[idx]; - } - else - { - - // Zero the data block offset - - setParameter(12, 0); - } - - // Set the byte count for the SMB packet - - setByteCount(pos - startPos); - } - - /** - * Set the secondary SMB command - * - * @param cmd Secondary SMB command code. - */ - public final void setAndXCommand(int cmd) - { - m_smbbuf[ANDXCOMMAND + m_offset] = (byte) cmd; - m_smbbuf[ANDXRESERVED + m_offset] = (byte) 0; - } - - /** - * Set the data byte count for this SMB packet - * - * @param cnt Data byte count. - */ - public final void setByteCount(int cnt) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(cnt, m_smbbuf, offset); - } - - /** - * Set the data byte area in the SMB packet - * - * @param byts Byte array containing the data to be copied to the SMB packet. - */ - public final void setBytes(byte[] byts) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(byts.length, m_smbbuf, offset); - - offset += 2; - - for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) - ; - } - - /** - * Set the SMB command - * - * @param cmd SMB command code - */ - public final void setCommand(int cmd) - { - m_smbbuf[COMMAND + m_offset] = (byte) cmd; - } - - /** - * Set the SMB error class. - * - * @param cl SMB error class. - */ - public final void setErrorClass(int cl) - { - m_smbbuf[ERRORCLASS + m_offset] = (byte) (cl & 0xFF); - } - - /** - * Set the SMB error code - * - * @param sts SMB error code. - */ - public final void setErrorCode(int sts) - { - m_smbbuf[ERROR + m_offset] = (byte) (sts & 0xFF); - } - - /** - * Set the SMB flags value. - * - * @param flg SMB flags value. - */ - public final void setFlags(int flg) - { - m_smbbuf[FLAGS + m_offset] = (byte) flg; - } - - /** - * Set the SMB flags2 value. - * - * @param flg SMB flags2 value. - */ - public final void setFlags2(int flg) - { - DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2 + m_offset); - } - - /** - * Set the multiplex identifier. - * - * @param mid Multiplex identifier - */ - public final void setMultiplexId(int mid) - { - DataPacker.putIntelShort(mid, m_smbbuf, MID + m_offset); - } - - /** - * Set the specified parameter word. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - public final void setParameter(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1 + m_offset; - DataPacker.putIntelShort(val, m_smbbuf, pos); - } - - /** - * Set the parameter count - * - * @param cnt Parameter word count. - */ - public final void setParameterCount(int cnt) - { - m_smbbuf[WORDCNT + m_offset] = (byte) cnt; - } - - /** - * Set the process identifier value (PID). - * - * @param pid Process identifier value. - */ - public final void setProcessId(int pid) - { - DataPacker.putIntelShort(pid, m_smbbuf, PID + m_offset); - } - - /** - * Set the packet sequence number, for connectionless commands. - * - * @param seq Sequence number. - */ - public final void setSeqNo(int seq) - { - DataPacker.putIntelShort(seq, m_smbbuf, SEQNO + m_offset); - } - - /** - * Set the session id. - * - * @param sid Session id. - */ - public final void setSID(int sid) - { - DataPacker.putIntelShort(sid, m_smbbuf, SID + m_offset); - } - - /** - * Set the tree identifier (TID) - * - * @param tid Tree identifier value. - */ - public final void setTreeId(int tid) - { - DataPacker.putIntelShort(tid, m_smbbuf, TID + m_offset); - } - - /** - * Set the user identifier (UID) - * - * @param uid User identifier value. - */ - public final void setUserId(int uid) - { - DataPacker.putIntelShort(uid, m_smbbuf, UID + m_offset); - } - - /** - * Set the specifiec setup parameter within the SMB packet. - * - * @param idx Setup parameter index. - * @param val Setup parameter value. - */ - public final void setSetupParameter(int idx, int val) - { - setParameter(STD_PARAMS + idx, val); - } - - /** - * Initialize the SMB packet buffer. - */ - private final void initializeBuffer() - { - - // Set the packet signature - - m_smbbuf[SIGNATURE + m_offset] = (byte) 0xFF; - m_smbbuf[SIGNATURE + 1 + m_offset] = (byte) 'S'; - m_smbbuf[SIGNATURE + 2 + m_offset] = (byte) 'M'; - m_smbbuf[SIGNATURE + 3 + m_offset] = (byte) 'B'; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/mailslot/TcpipNetBIOSHostAnnouncer.java b/source/java/org/alfresco/filesys/smb/mailslot/TcpipNetBIOSHostAnnouncer.java deleted file mode 100644 index 2805e522d3..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/TcpipNetBIOSHostAnnouncer.java +++ /dev/null @@ -1,240 +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.smb.mailslot; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import org.alfresco.filesys.netbios.NetBIOSDatagram; -import org.alfresco.filesys.netbios.NetBIOSDatagramSocket; -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetworkSettings; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; - -/** - *

- * TCP/IP NetBIOS host announcer implementation. Periodically broadcasts a host announcement - * datagram to inform other Windows networking hosts of the local hosts existence and capabilities. - */ -public class TcpipNetBIOSHostAnnouncer extends HostAnnouncer -{ - - // Default port and announcement interval - - public static final int PORT = RFCNetBIOSProtocol.DATAGRAM; - public static final int INTERVAL = 1; // minutes - - // Local address to bind to, port to use - - private InetAddress m_bindAddress; - private int m_port; - - // Broadcast address and port - - private InetAddress m_bcastAddr; - - // NetBIOS datagram - - private NetBIOSDatagram m_nbdgram; - - /** - * Default constructor. - */ - public TcpipNetBIOSHostAnnouncer() - { - - // Set the default port and interval - - setPort(PORT); - setInterval(INTERVAL); - } - - /** - * Create a host announcer. - * - * @param name Host name to announce - * @param domain Domain name to announce to - * @param intval Announcement interval, in minutes - * @param port Port to use - */ - public TcpipNetBIOSHostAnnouncer(String name, String domain, int intval, int port) - { - - // Add the host to the list of names to announce - - addHostName(name); - setDomain(domain); - setInterval(intval); - - // If port is zero then use the default port - - if (port == 0) - setPort(PORT); - else - setPort(port); - } - - /** - * Get the local address that the announcer should bind to. - * - * @return java.net.InetAddress - */ - public final InetAddress getBindAddress() - { - return m_bindAddress; - } - - /** - * Return the socket/port number that the announcer is using. - * - * @return int - */ - public final int getPort() - { - return m_port; - } - - /** - * Check if the announcer should bind to a particular local address, or all local addresses. - * - * @return boolean - */ - public final boolean hasBindAddress() - { - return m_bindAddress != null ? true : false; - } - - /** - * Set the broadcast address - * - * @param addr String - * @exception UnknownHostException - */ - public final void setBroadcastAddress(String addr) throws UnknownHostException - { - m_bcastAddr = InetAddress.getByName(addr); - } - - /** - * Set the broadcast address and port - * - * @param addr String - * @param int port - * @exception UnknownHostException - */ - public final void setBroadcastAddress(String addr, int port) throws UnknownHostException - { - m_bcastAddr = InetAddress.getByName(addr); - m_port = port; - } - - /** - * Initialize the host announcer. - * - * @exception Exception - */ - protected void initialize() throws Exception - { - - // Set this thread to be a daemon, set the thread name - - if (hasBindAddress() == false) - setName("TCPHostAnnouncer"); - else - setName("TCPHostAnnouncer_" + getBindAddress().getHostAddress()); - - // Check if at least one host name has been set, if not then use the local host name - - if (numberOfNames() == 0) - { - - // Get the local host name - - addHostName(InetAddress.getLocalHost().getHostName()); - } - - // Allocate the NetBIOS datagram - - m_nbdgram = new NetBIOSDatagram(512); - - // If the broadcast address has not been set, generate a broadcast address - - if (m_bcastAddr == null) - m_bcastAddr = InetAddress.getByName(NetworkSettings.GenerateBroadcastMask(null)); - } - - /** - * Determine if the network connection used for the host announcement is valid - * - * @return boolean - */ - public boolean isNetworkEnabled() - { - return true; - } - - /** - * Send an announcement broadcast. - * - * @param hostName Host name being announced - * @param buf Buffer containing the host announcement mailslot message. - * @param offset Offset to the start of the host announcement message. - * @param len Host announcement message length. - */ - protected void sendAnnouncement(String hostName, byte[] buf, int offset, int len) throws Exception - { - // DEBUG - - if ( logger.isDebugEnabled()) - logger.debug("Send NetBIOS host announcement to " + m_bcastAddr.getHostAddress() + ", port " + getPort()); - - // Send the host announce datagram - - m_nbdgram.SendDatagram(NetBIOSDatagram.DIRECT_GROUP, hostName, NetBIOSName.FileServer, getDomain(), - NetBIOSName.MasterBrowser, buf, len, offset, m_bcastAddr, getPort()); - } - - /** - * Set the local address to bind to. - * - * @param addr java.net.InetAddress - */ - public final void setBindAddress(InetAddress addr) - { - m_bindAddress = addr; - NetBIOSDatagramSocket.setBindAddress(addr); - } - - /** - * Set the socket/port number to use. - * - * @param port int - */ - public final void setPort(int port) - { - m_port = port; - NetBIOSDatagramSocket.setDefaultPort(port); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/mailslot/Win32NetBIOSHostAnnouncer.java b/source/java/org/alfresco/filesys/smb/mailslot/Win32NetBIOSHostAnnouncer.java deleted file mode 100644 index 9f1b8b5b32..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/Win32NetBIOSHostAnnouncer.java +++ /dev/null @@ -1,167 +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.smb.mailslot; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.win32.NetBIOS; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.smb.server.win32.Win32NetBIOSSessionSocketHandler; - -/** - *

- * The host announcer class periodically broadcasts a host announcement datagram to inform other - * Windows networking hosts of the local hosts existence and capabilities. - *

- * The Win32 NetBIOS host announcer sends out the announcements using datagrams sent via the Win32 - * Netbios() Netapi32 call. - */ -public class Win32NetBIOSHostAnnouncer extends HostAnnouncer -{ - - // Number of send errors before marking the LANA as offline - - private static final int SendErrorCount = 3; - - // Associated session handler - - Win32NetBIOSSessionSocketHandler m_handler; - - /** - * Create a host announcer. - * - * @param sessHandler Win32NetBIOSSessionSocketHandler - * @param domain Domain name to announce to - * @param intval Announcement interval, in minutes - */ - public Win32NetBIOSHostAnnouncer(Win32NetBIOSSessionSocketHandler handler, String domain, int intval) - { - - // Save the handler - - m_handler = handler; - - // Add the host to the list of names to announce - - addHostName(handler.getServerName()); - setDomain(domain); - setInterval(intval); - } - - /** - * Return the LANA - * - * @return int - */ - public final int getLana() - { - return m_handler.getLANANumber(); - } - - /** - * Return the host name NetBIOS number - * - * @return int - */ - public final int getNameNumber() - { - return m_handler.getNameNumber(); - } - - /** - * Initialize the host announcer. - * - * @exception Exception - */ - protected void initialize() throws Exception - { - - // Set the thread name - - setName("Win32HostAnnouncer_L" + getLana()); - } - - /** - * Determine if the network connection used for the host announcement is valid - * - * @return boolean - */ - public boolean isNetworkEnabled() - { - return m_handler.isLANAValid(); - } - - /** - * Send an announcement broadcast. - * - * @param hostName Host name being announced - * @param buf Buffer containing the host announcement mailslot message. - * @param offset Offset to the start of the host announcement message. - * @param len Host announcement message length. - */ - protected void sendAnnouncement(String hostName, byte[] buf, int offset, int len) throws Exception - { - - // Build the destination NetBIOS name using the domain/workgroup name - - NetBIOSName destNbName = new NetBIOSName(getDomain(), NetBIOSName.MasterBrowser, false); - byte[] destName = destNbName.getNetBIOSName(); - - // Send the host announce datagram via the Win32 Netbios() API call - - int sts = Win32NetBIOS.SendDatagram(getLana(), getNameNumber(), destName, buf, 0, len); - if ( sts != NetBIOS.NRC_GoodRet) - { - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Host announce error " + NetBIOS.getErrorString( -sts) + - " (LANA " + getLana() + ")"); - - // Update the error count - - if ( incrementErrorCount() == SendErrorCount) - { - // Mark the LANA as offline - - m_handler.lanaStatusChange( getLana(), false); - - // Clear the error count - - clearErrorCount(); - - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Marked LANA as unavailable due to send errors"); - } - } - else - { - // Clear the error count - - clearErrorCount(); - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/mailslot/WinsockNetBIOSHostAnnouncer.java b/source/java/org/alfresco/filesys/smb/mailslot/WinsockNetBIOSHostAnnouncer.java deleted file mode 100644 index 884cd80d3e..0000000000 --- a/source/java/org/alfresco/filesys/smb/mailslot/WinsockNetBIOSHostAnnouncer.java +++ /dev/null @@ -1,178 +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.smb.mailslot; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.win32.NetBIOS; -import org.alfresco.filesys.netbios.win32.NetBIOSSocket; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.smb.server.win32.Win32NetBIOSSessionSocketHandler; - -/** - * Winsock NetBIOS Host Announcer Class - * - *

- * The host announcer class periodically broadcasts a host announcement datagram to inform other - * Windows networking hosts of the local hosts existence and capabilities. - * - *

- * The Win32 NetBIOS host announcer sends out the announcements using datagrams sent via Winsock calls. - */ -public class WinsockNetBIOSHostAnnouncer extends HostAnnouncer -{ - // Number of send errors before marking the LANA as offline - - private static final int SendErrorCount = 3; - - // Associated session handler - - private Win32NetBIOSSessionSocketHandler m_handler; - - // Winsock NetBIOS datagram socket - - private NetBIOSSocket m_dgramSocket; - - /** - * Create a host announcer. - * - * @param sessHandler Win32NetBIOSSessionSocketHandler - * @param domain Domain name to announce to - * @param intval Announcement interval, in minutes - */ - public WinsockNetBIOSHostAnnouncer(Win32NetBIOSSessionSocketHandler handler, String domain, int intval) - { - - // Save the handler - - m_handler = handler; - - // Add the host to the list of names to announce - - addHostName(handler.getServerName()); - setDomain(domain); - setInterval(intval); - } - - /** - * Return the LANA - * - * @return int - */ - public final int getLana() - { - return m_handler.getLANANumber(); - } - - /** - * Initialize the host announcer. - * - * @exception Exception - */ - protected void initialize() throws Exception - { - // Set the thread name - - setName("WinsockHostAnnouncer_L" + getLana()); - - // Create the Winsock NetBIOS datagram socket - - m_dgramSocket = NetBIOSSocket.createDatagramSocket(getLana()); - } - - /** - * Determine if the network connection used for the host announcement is valid - * - * @return boolean - */ - public boolean isNetworkEnabled() - { - return m_handler.isLANAValid(); - } - - /** - * Send an announcement broadcast. - * - * @param hostName Host name being announced - * @param buf Buffer containing the host announcement mailslot message. - * @param offset Offset to the start of the host announcement message. - * @param len Host announcement message length. - */ - protected void sendAnnouncement(String hostName, byte[] buf, int offset, int len) throws Exception - { - - // Build the destination NetBIOS name using the domain/workgroup name - - NetBIOSName destNbName = new NetBIOSName(getDomain(), NetBIOSName.MasterBrowser, false); - - // Send the host announce datagram via the Win32 Netbios() API call - - boolean txOK = false; - - try - { - int sts = m_dgramSocket.sendDatagram(destNbName, buf, 0, len); - if ( sts == len) - txOK = true; - } - catch ( IOException ex) - { - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Host announce error, " + ex.getMessage() + ", (LANA " + getLana() + ")"); - } - - // Check if the send was successful - - if ( txOK == false) - { - // Update the error count - - if ( incrementErrorCount() == SendErrorCount) - { - // Mark the LANA as offline - - m_handler.lanaStatusChange( getLana(), false); - - // Clear the error count - - clearErrorCount(); - - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Marked LANA as unavailable due to send errors, (LANA " + getLana() + ")"); - } - } - else - { - // Clear the error count - - clearErrorCount(); - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/AdminSharedDevice.java b/source/java/org/alfresco/filesys/smb/server/AdminSharedDevice.java deleted file mode 100644 index fa0a5c24a4..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/AdminSharedDevice.java +++ /dev/null @@ -1,46 +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.smb.server; - -import org.alfresco.filesys.server.core.*; - -/** - * Administration shared device, IPC$. - */ -final class AdminSharedDevice extends SharedDevice -{ - - /** - * Class constructor - */ - protected AdminSharedDevice() - { - super("IPC$", ShareType.ADMINPIPE, null); - - // Set the device attributes - - setAttributes(SharedDevice.Admin + SharedDevice.Hidden); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java deleted file mode 100644 index 2705cfa50a..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/CoreProtocolHandler.java +++ /dev/null @@ -1,3871 +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.smb.server; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.auth.InvalidUserException; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.ShareType; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.filesys.AccessDeniedException; -import org.alfresco.filesys.server.filesys.AccessMode; -import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.FileAccess; -import org.alfresco.filesys.server.filesys.FileAction; -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.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.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.TooManyFilesException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.VolumeInfo; -import org.alfresco.filesys.smb.Capability; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.InvalidUNCPathException; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.WildCard; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Core SMB protocol handler class. - */ -class CoreProtocolHandler extends ProtocolHandler -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Special resume ids for '.' and '..' pseudo directories - - private static final int RESUME_START = 0x00008003; - private static final int RESUME_DOT = 0x00008002; - private static final int RESUME_DOTDOT = 0x00008001; - - // Maximum value that can be stored in a parameter word - - private static final int MaxWordValue = 0x0000FFFF; - - // Invalid file name characters - - private static final String InvalidFileNameChars = "\"/:|<>*?"; - private static final String InvalidFileNameCharsSearch = "\"/:|<>"; - - // SMB packet class - - protected SMBSrvPacket m_smbPkt; - - /** - * Create a new core SMB protocol handler. - */ - protected CoreProtocolHandler() - { - } - - /** - * Class constructor - * - * @param sess SMBSrvSession - */ - protected CoreProtocolHandler(SMBSrvSession sess) - { - super(sess); - } - - /** - * Return the protocol name - * - * @return String - */ - public String getName() - { - return "Core Protocol"; - } - - /** - * Map a Java exception class to an SMB error code, and return an error response to the caller. - * - * @param ex java.lang.Exception - */ - protected final void MapExceptionToSMBError(Exception ex) - { - - } - - /** - * Check if a path contains any illegal characters, for file/create open/create/rename/get info - * - * @param path String - * @return boolean - */ - protected boolean isValidPath(String path) - { - // Scan the path for invalid path characters - - for ( int i = 0; i < InvalidFileNameChars.length(); i++) - { - if ( path.indexOf( InvalidFileNameChars.charAt( i)) != -1) - return false; - } - - // Path looks valid - - return true; - } - - /** - * Check if a path contains any illegal characters, for a folder search - * - * @param path String - * @return boolean - */ - protected boolean isValidSearchPath(String path) - { - // Scan the path for invalid path characters - - for ( int i = 0; i < InvalidFileNameCharsSearch.length(); i++) - { - if ( path.indexOf( InvalidFileNameCharsSearch.charAt( i)) != -1) - return false; - } - - // Path looks valid - - return true; - } - - /** - * Pack file information for a search into the specified buffer. - * - * @param buf byte[] Buffer to store data. - * @param bufpos int Position to start storing data. - * @param searchStr Search context string. - * @param resumeId int Resume id - * @param searchId Search context id - * @param info File data to be packed. - * @return int Next available buffer position. - */ - protected final int packSearchInfo(byte[] buf, int bufPos, String searchStr, int resumeId, int searchId, - FileInfo info) - { - - // Pack the resume key - - CoreResumeKey.putResumeKey(buf, bufPos, searchStr, resumeId + (searchId << 16)); - bufPos += CoreResumeKey.LENGTH; - - // Pack the file information - - buf[bufPos++] = (byte) (info.getFileAttributes() & 0x00FF); - - SMBDate dateTime = new SMBDate(info.getModifyDateTime()); - if (dateTime != null) - { - DataPacker.putIntelShort(dateTime.asSMBTime(), buf, bufPos); - DataPacker.putIntelShort(dateTime.asSMBDate(), buf, bufPos + 2); - } - else - { - DataPacker.putIntelShort(0, buf, bufPos); - DataPacker.putIntelShort(0, buf, bufPos + 2); - } - bufPos += 4; - - DataPacker.putIntelInt((int) info.getSize(), buf, bufPos); - bufPos += 4; - - StringBuffer strBuf = new StringBuffer(); - strBuf.append(info.getFileName()); - - while (strBuf.length() < 13) - strBuf.append('\0'); - - if (strBuf.length() > 12) - strBuf.setLength(12); - - DataPacker.putString(strBuf.toString().toUpperCase(), buf, bufPos, true); - bufPos += 13; - - // Return the new buffer position - - return bufPos; - } - - /** - * Check if the specified path exists, and is a directory. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException if an SMB protocol error occurs - */ - protected void procCheckDirectory(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid check directory request - - if (m_smbPkt.checkPacketIsValid(0, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the directory name - - String dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (dirName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( dirName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Directory Check [" + treeId + "] name=" + dirName); - - // Access the disk interface and check for the directory - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check that the specified path exists, and it is a directory - - if (disk.fileExists(m_sess, conn, dirName) == FileStatus.DirectoryExists) - { - - // The path exists and is a directory, build the valid path response. - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - else - { - - // The path does not exist, or is not a directory. - // - // DOS clients depend on the 'Directory Invalid' (SMB_ERR_BAD_PATH) message being - // returned. - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to delete the directory - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); - return; - } - } - - /** - * Close a file that has been opened on the server. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procCloseFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file close request - - if (m_smbPkt.checkPacketIsValid(3, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - int ftime = m_smbPkt.getParameter(1); - int fdate = m_smbPkt.getParameter(2); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File close [" + treeId + "] fid=" + fid); - - // Close the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Close the file - // - // The disk interface may be null if the file is a named pipe file - - if (disk != null) - disk.closeFile(m_sess, conn, netFile); - - // Indicate that the file has been closed - - netFile.setClosed(true); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - } - - // Remove the file from the connections list of open files - - conn.removeFile(fid, getSession()); - - // Build the close file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Create a new directory. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procCreateDirectory(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid create directory request - - if (m_smbPkt.checkPacketIsValid(0, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the directory name - - String dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (dirName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( dirName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Directory Create [" + treeId + "] name=" + dirName); - - // Access the disk interface and create the new directory - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Directory creation parameters - - FileOpenParams params = new FileOpenParams(dirName, FileAction.CreateNotExist, AccessMode.ReadWrite, - FileAttribute.NTDirectory); - - // Create the new directory - - disk.createDirectory(m_sess, conn, params); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (FileExistsException ex) - { - - // Failed to create the directory - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to create directory - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to create the directory - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); - return; - } - - // Build the create directory response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Create a new file on the server. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procCreateFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file create request - - if (m_smbPkt.checkPacketIsValid(3, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the file name - - String fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( fileName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the required file attributes for the new file - - int attr = m_smbPkt.getParameter(0); - - // Create the file parameters to be passed to the disk interface - - FileOpenParams params = new FileOpenParams(fileName, FileAction.CreateNotExist, AccessMode.ReadWrite, attr); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Create [" + treeId + "] params=" + params); - - // Access the disk interface and create the new file - - int fid; - NetworkFile netFile = null; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Create the new file - - netFile = disk.createFile(m_sess, conn, params); - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (FileExistsException ex) - { - - // File with the requested name already exists - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileAlreadyExists, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the create file response - - outPkt.setParameterCount(1); - outPkt.setParameter(0, fid); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Create a temporary file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procCreateTemporaryFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - } - - /** - * Delete a directory. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procDeleteDirectory(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid delete directory request - - if (m_smbPkt.checkPacketIsValid(0, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the directory name - - String dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - - if (dirName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( dirName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Directory Delete [" + treeId + "] name=" + dirName); - - // Access the disk interface and delete the directory - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Delete the directory - - disk.deleteDirectory(m_sess, conn, dirName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to delete the directory - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (DirectoryNotEmptyException ex) - { - - // Directory not empty - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryNotEmpty, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to delete the directory - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); - return; - } - - // Build the delete directory response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Delete a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procDeleteFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file delete request - - if (m_smbPkt.checkPacketIsValid(1, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the file name - - String fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( fileName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Delete [" + treeId + "] name=" + fileName); - - // Access the disk interface and delete the file(s) - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Delete file(s) - - disk.deleteFile(m_sess, conn, fileName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the delete file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Get disk attributes processing. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procDiskAttributes(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Get disk attributes"); - - // Parameter and byte count should be zero - - if (m_smbPkt.getParameterCount() != 0 && m_smbPkt.getByteCount() != 0) - { - - // Send an error response - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the disk interface from the shared device - - DiskInterface disk = null; - DiskDeviceContext diskCtx = null; - - try - { - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - diskCtx = (DiskDeviceContext) conn.getContext(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Create a disk information object and ask the disk interface to fill in the details - - SrvDiskInfo diskInfo = getDiskInformation(disk, diskCtx); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Disk info - total=" + diskInfo.getTotalUnits() + ", free=" + diskInfo.getFreeUnits() - + ", blocksPerUnit=" + diskInfo.getBlocksPerAllocationUnit() + ", blockSize=" - + diskInfo.getBlockSize()); - - // Check if the disk size information needs scaling to fit into 16bit values - - long totUnits = diskInfo.getTotalUnits(); - long freeUnits = diskInfo.getFreeUnits(); - int blocksUnit = diskInfo.getBlocksPerAllocationUnit(); - - while (totUnits > MaxWordValue && blocksUnit <= MaxWordValue) - { - - // Increase the blocks per unit and decrease the total/free units - - blocksUnit *= 2; - - totUnits = totUnits / 2L; - freeUnits = freeUnits / 2L; - } - - // Check if the total/free units fit into a 16bit value - - if (totUnits > MaxWordValue || blocksUnit > MaxWordValue) - { - - // Just use dummy values, cannot fit the disk size into 16bits - - totUnits = MaxWordValue; - - if (freeUnits > MaxWordValue) - freeUnits = MaxWordValue / 2; - - if (blocksUnit > MaxWordValue) - blocksUnit = MaxWordValue; - } - - // Build the reply SMB - - outPkt.setParameterCount(5); - - outPkt.setParameter(0, (int) totUnits); - outPkt.setParameter(1, blocksUnit); - outPkt.setParameter(2, diskInfo.getBlockSize()); - outPkt.setParameter(3, (int) freeUnits); - outPkt.setParameter(4, 0); - - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Echo packet request. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procEcho(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid echo request - - if (m_smbPkt.checkPacketIsValid(1, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the echo count from the request - - int echoCnt = m_smbPkt.getParameter(0); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_ECHO)) - logger.debug("Echo - Count = " + echoCnt); - - // Loop until all echo packets have been sent - - int echoSeq = 1; - - while (echoCnt > 0) - { - - // Set the echo response sequence number - - outPkt.setParameter(0, echoSeq++); - - // Echo the received packet - - m_sess.sendResponseSMB(outPkt); - echoCnt--; - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_ECHO)) - logger.debug("Echo Packet, Seq = " + echoSeq); - } - } - - /** - * Flush the specified file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procFlushFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file flush request - - if (m_smbPkt.checkPacketIsValid(1, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Flush [" + netFile.getFileId() + "]"); - - // Flush the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Flush the file - - disk.flushFile(m_sess, conn, netFile); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Flush Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - - // Send the flush response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Get the file attributes for the specified file. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procGetFileAttributes(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid query file information request - - if (m_smbPkt.checkPacketIsValid(0, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the file name - - String fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name is valid - - if ( isValidPath( fileName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Get File Information [" + treeId + "] name=" + fileName); - - // Access the disk interface and get the file information - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the specified file/directory - - FileInfo finfo = disk.getFileInformation(m_sess, conn, fileName); - if (finfo != null) - { - - // Check if the share is read-only, if so then force the read-only flag for the file - - if (conn.getSharedDevice().isReadOnly() && finfo.isReadOnly() == false) - { - - // Make sure the read-only attribute is set - - finfo.setFileAttributes(finfo.getFileAttributes() + FileAttribute.ReadOnly); - } - - // Return the file information - - outPkt.setParameterCount(10); - outPkt.setParameter(0, finfo.getFileAttributes()); - if (finfo.getModifyDateTime() != 0L) - { - SMBDate dateTime = new SMBDate(finfo.getModifyDateTime()); - outPkt.setParameter(1, dateTime.asSMBTime()); - outPkt.setParameter(2, dateTime.asSMBDate()); - } - else - { - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); - } - outPkt.setParameter(3, (int) finfo.getSize() & 0x0000FFFF); - outPkt.setParameter(4, (int) (finfo.getSize() & 0xFFFF0000) >> 16); - - for (int i = 5; i < 10; i++) - outPkt.setParameter(i, 0); - - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - return; - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - } - - // Failed to get the file information - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - } - - /** - * Get file information. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procGetFileInformation(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid query file information2 request - - if (m_smbPkt.checkPacketIsValid(1, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Get File Information 2 [" + netFile.getFileId() + "]"); - - // Access the disk interface and get the file information - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the specified file/directory - - FileInfo finfo = disk.getFileInformation(m_sess, conn, netFile.getFullName()); - if (finfo != null) - { - - // Check if the share is read-only, if so then force the read-only flag for the file - - if (conn.getSharedDevice().isReadOnly() && finfo.isReadOnly() == false) - { - - // Make sure the read-only attribute is set - - finfo.setFileAttributes(finfo.getFileAttributes() + FileAttribute.ReadOnly); - } - - // Initialize the return packet, no data bytes - - outPkt.setParameterCount(11); - outPkt.setByteCount(0); - - // Return the file information - // - // Creation date/time - - SMBDate dateTime = new SMBDate(0); - - if (finfo.getCreationDateTime() != 0L) - { - dateTime.setTime(finfo.getCreationDateTime()); - outPkt.setParameter(0, dateTime.asSMBDate()); - outPkt.setParameter(1, dateTime.asSMBTime()); - } - else - { - outPkt.setParameter(0, 0); - outPkt.setParameter(1, 0); - } - - // Access date/time - - if (finfo.getAccessDateTime() != 0L) - { - dateTime.setTime(finfo.getAccessDateTime()); - outPkt.setParameter(2, dateTime.asSMBDate()); - outPkt.setParameter(3, dateTime.asSMBTime()); - } - else - { - outPkt.setParameter(2, 0); - outPkt.setParameter(3, 0); - } - - // Modify date/time - - if (finfo.getModifyDateTime() != 0L) - { - dateTime.setTime(finfo.getModifyDateTime()); - outPkt.setParameter(4, dateTime.asSMBDate()); - outPkt.setParameter(5, dateTime.asSMBTime()); - } - else - { - outPkt.setParameter(4, 0); - outPkt.setParameter(5, 0); - } - - // File data size - - outPkt.setParameter(6, (int) finfo.getSize() & 0x0000FFFF); - outPkt.setParameter(7, (int) (finfo.getSize() & 0xFFFF0000) >> 16); - - // File allocation size - - outPkt.setParameter(8, (int) finfo.getSize() & 0x0000FFFF); - outPkt.setParameter(9, (int) (finfo.getSize() & 0xFFFF0000) >> 16); - - // File attributes - - outPkt.setParameter(10, finfo.getFileAttributes()); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - return; - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - } - - // Failed to get the file information - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - } - - /** - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procLockFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid lock file request - - if (m_smbPkt.checkPacketIsValid(5, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - long lockcnt = m_smbPkt.getParameterLong(1); - long lockoff = m_smbPkt.getParameterLong(3); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Lock [" + netFile.getFileId() + "] : Offset=" + lockoff + " ,Count=" + lockcnt); - - // ***** Always return a success status, simulated locking **** - // - // Build the lock file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Open a file on the server. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procOpenFile(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file open request - - if (m_smbPkt.checkPacketIsValid(2, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the file name - - String fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the required access mode and the file attributes - - int mode = m_smbPkt.getParameter(0); - int attr = m_smbPkt.getParameter(1); - - // Create the file open parameters to be passed to the disk interface - - FileOpenParams params = new FileOpenParams(fileName, mode, AccessMode.ReadWrite, attr); - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Open [" + treeId + "] params=" + params); - - // Access the disk interface and open the requested file - - int fid; - NetworkFile netFile = null; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Open the requested file - - netFile = disk.openFile(m_sess, conn, params); - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // File is not accessible, or file is actually a directory - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileSharingConflict, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the open file response - - outPkt.setParameterCount(7); - - outPkt.setParameter(0, fid); - outPkt.setParameter(1, 0); // file attributes - - if (netFile.hasModifyDate()) - { - outPkt.setParameterLong(2, (int) (netFile.getModifyDate() / 1000L)); - - // SMBDate smbDate = new SMBDate(netFile.getModifyDate()); - // outPkt.setParameter(2, smbDate.asSMBTime()); // last write time - // outPkt.setParameter(3, smbDate.asSMBDate()); // last write date - } - else - outPkt.setParameterLong(2, 0); - - outPkt.setParameterLong(4, netFile.getFileSizeInt()); // file size - outPkt.setParameter(6, netFile.getGrantedAccess()); - - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process exit, close all open files. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procProcessExit(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid process exit request - - if (m_smbPkt.checkPacketIsValid(0, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Process Exit - Open files = " + conn.openFileCount()); - - // Close all open files - - if (conn.openFileCount() > 0) - { - - // Close all files on the connection - - conn.closeConnection(getSession()); - } - - // Build the process exit response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Read from a file that has been opened on the server. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procReadFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file read request - - if (m_smbPkt.checkPacketIsValid(5, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - int reqcnt = m_smbPkt.getParameter(1); - int reqoff = m_smbPkt.getParameter(2) + (m_smbPkt.getParameter(3) << 16); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read [" + netFile.getFileId() + "] : Size=" + reqcnt + " ,Pos=" + reqoff); - - // Read data from the file - - byte[] buf = outPkt.getBuffer(); - int rdlen = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check if the required read size will fit into the reply packet - - int dataOff = outPkt.getByteOffset() + 3; - int availCnt = buf.length - dataOff; - if (m_sess.hasClientCapability(Capability.LargeRead) == false) - availCnt = m_sess.getClientMaximumBufferSize() - dataOff; - - if (availCnt < reqcnt) - { - - // Limit the file read size - - reqcnt = availCnt; - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read [" + netFile.getFileId() + "] Limited to " + availCnt); - } - - // Read from the file - - rdlen = disk.readFile(m_sess, conn, netFile, buf, outPkt.getByteOffset() + 3, reqcnt, reqoff); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd); - return; - } - - // Return the data block - - int bytOff = outPkt.getByteOffset(); - buf[bytOff] = (byte) DataType.DataBlock; - DataPacker.putIntelShort(rdlen, buf, bytOff + 1); - outPkt.setByteCount(rdlen + 3); // data type + 16bit length - - outPkt.setParameter(0, rdlen); - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); - outPkt.setParameter(3, 0); - outPkt.setParameter(4, 0); - - // Send the read response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Rename a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procRenameFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid rename file request - - if (m_smbPkt.checkPacketIsValid(1, 4) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the old file name - - boolean isUni = m_smbPkt.isUnicode(); - String oldName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni); - if (oldName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Update the data position - - if (isUni) - { - int len = (oldName.length() * 2) + 2; - dataPos = DataPacker.wordAlign(dataPos + 1) + len; - dataLen -= len; - } - else - { - dataPos += oldName.length() + 2; // string length + null + data type - dataLen -= oldName.length() + 2; - } - - // Extract the new file name - - String newName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni); - if (newName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Rename [" + treeId + "] old name=" + oldName + ", new name=" + newName); - - // Access the disk interface and rename the requested file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Rename the requested file - - disk.renameFile(m_sess, conn, oldName, newName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the rename file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Start/continue a directory search operation. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procSearch(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - // Check that the received packet looks like a valid search request - - if (m_smbPkt.checkPacketIsValid(2, 5) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection( m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the maximum number of entries to return and the search file attributes - - int maxFiles = m_smbPkt.getParameter(0); - int srchAttr = m_smbPkt.getParameter(1); - - // Check if this is a volume label request - - if ((srchAttr & FileAttribute.Volume) != 0) - { - - // Process the volume label request - - procSearchVolumeLabel(outPkt); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the search file name - - String srchPath = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - - if (srchPath == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidFunc, SMBStatus.ErrDos); - return; - } - - // Check if the search path is valid - - if ( isValidSearchPath( srchPath) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Update the received data position - - dataPos += srchPath.length() + 2; - dataLen -= srchPath.length() + 2; - - int resumeLen = 0; - - if (buf[dataPos++] == DataType.VariableBlock) - { - - // Extract the resume key length - - resumeLen = DataPacker.getIntelShort(buf, dataPos); - - // Adjust remaining the data length and position - - dataLen -= 3; // block type + resume key length short - dataPos += 2; // resume key length short - - // Check that we received enough data - - if (resumeLen > dataLen) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - } - - // Access the shared devices disk interface - - SearchContext ctx = null; - DiskInterface disk = null; - - try - { - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if this is the start of a new search - - byte[] resumeKey = null; - int searchId = -1; - - // Default resume point is at the start of the directory, at the '.' directory if - // directories are - // being returned. - - int resumeId = RESUME_START; - - if (resumeLen == 0 && srchPath.length() > 0) - { - - // Allocate a search slot for the new search - - searchId = vc.allocateSearchSlot(); - if (searchId == -1) - { - - // Try and find any 'leaked' searches, ie. searches that have been started but not - // closed. - // - // Windows Explorer seems to leak searches after a new folder has been created, a - // search for '????????.???' - // is started but never continued. - - int idx = 0; - ctx = vc.getSearchContext(idx); - - while (ctx != null && searchId == -1) - { - - // Check if the current search context looks like a leaked search. - - if (ctx.getSearchString().compareTo("????????.???") == 0) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Release leaked search [" + idx + "]"); - - // Deallocate the search context - - vc.deallocateSearchSlot(idx); - - // Allocate the slot for the new search - - searchId = vc.allocateSearchSlot(); - } - else - { - - // Update the search index and get the next search context - - ctx = vc.getSearchContext(++idx); - } - } - - // Check if we freed up a search slot - - if (searchId == -1) - { - - // Failed to allocate a slot for the new search - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); - return; - } - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Start search [" + searchId + "] - " + srchPath + ", attr=0x" - + Integer.toHexString(srchAttr) + ", maxFiles=" + maxFiles); - - // Start a new search - - ctx = disk.startSearch(m_sess, conn, srchPath, srchAttr); - if (ctx != null) - { - - // Store details of the search in the context - - ctx.setTreeId(m_smbPkt.getTreeId()); - ctx.setMaximumFiles(maxFiles); - } - - // Save the search context - - vc.setSearchContext(searchId, ctx); - } - else - { - - // Take a copy of the resume key - - resumeKey = new byte[CoreResumeKey.LENGTH]; - CoreResumeKey.getResumeKey(buf, dataPos, resumeKey); - - // Get the search context slot id from the resume key, and get the search context. - - int id = CoreResumeKey.getServerArea(resumeKey, 0); - searchId = (id & 0xFFFF0000) >> 16; - ctx = vc.getSearchContext(searchId); - - // Check if the search context is valid - - if (ctx == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the resume id from the resume key - - resumeId = id & 0x0000FFFF; - - // Restart the search at the resume point, check if the resume point is already set, ie. - // we are just continuing the search. - - if (resumeId < RESUME_DOTDOT && ctx.getResumeId() != resumeId) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search resume at " + resumeId); - - // Restart the search at the specified point - - if (ctx.restartAt(resumeId) == false) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search restart failed"); - - // Failed to restart the search - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - return; - } - } - } - - // Check if the search context is valid - - if (ctx == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check that the search context and tree connection match - - if (ctx.getTreeId() != m_smbPkt.getTreeId()) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Start building the search response packet - - outPkt.setParameterCount(1); - int bufPos = outPkt.getByteOffset(); - buf[bufPos] = (byte) DataType.VariableBlock; - bufPos += 3; // save two bytes for the actual block length - int fileCnt = 0; - - // Check if this is the start of a wildcard search and includes directories - - if ((srchAttr & FileAttribute.Directory) != 0 && resumeId >= RESUME_DOTDOT - && WildCard.containsWildcards(srchPath)) - { - - // The first entries in the search should be the '.' and '..' entries for the - // current/parent - // directories. - // - // Remove the file name from the search path, and get the file information for the - // search - // directory. - - String workDir = FileName.removeFileName(srchPath); - FileInfo dirInfo = disk.getFileInformation(m_sess, conn, workDir); - - // Check if we have valid information for the working directory - - if (dirInfo != null) - dirInfo = new FileInfo(".", 0, FileAttribute.Directory); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search adding . and .. entries: " + dirInfo.toString()); - - // Reset the file name to '.' and pack the directory information - - if (resumeId == RESUME_START) - { - - // Pack the '.' file information - - dirInfo.setFileName("."); - resumeId = RESUME_DOT; - bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), RESUME_DOT, searchId, dirInfo); - - // Update the file count - - fileCnt++; - } - - // Reset the file name to '..' and pack the directory information - - if (resumeId == RESUME_DOT) - { - - // Pack the '..' file information - - dirInfo.setFileName(".."); - bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), RESUME_DOTDOT, searchId, dirInfo); - - // Update the file count - - fileCnt++; - } - } - - // Get files from the search and pack into the return packet - - FileInfo fileInfo = new FileInfo(); - - while (fileCnt < ctx.getMaximumFiles() && ctx.nextFileInfo(fileInfo) == true) - { - - // Check for . files, ignore them. - // - // ** Should check for . and .. file names ** - - if (fileInfo.getFileName().startsWith(".")) - continue; - - // Get the resume id for the current file/directory - - resumeId = ctx.getResumeId(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search return file " + fileInfo.toString() + ", resumeId=" + resumeId); - - // Check if the share is read-only, if so then force the read-only flag for the file - - if (conn.getSharedDevice().isReadOnly() && fileInfo.isReadOnly() == false) - { - - // Make sure the read-only attribute is set - - fileInfo.setFileAttributes(fileInfo.getFileAttributes() + FileAttribute.ReadOnly); - } - - // Pack the file information - - bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), resumeId, searchId, fileInfo); - - // Update the file count, reset the current file information - - fileCnt++; - fileInfo.resetInfo(); - } - - // Check if any files were found - - if (fileCnt == 0) - { - - // Send a repsonse that indicates that the search has finished - - outPkt.setParameterCount(1); - outPkt.setParameter(0, 0); - outPkt.setByteCount(0); - - outPkt.setErrorClass(SMBStatus.ErrDos); - outPkt.setErrorCode(SMBStatus.DOSNoMoreFiles); - - m_sess.sendResponseSMB(outPkt); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End search [" + searchId + "]"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - else - { - - // Set the actual data length - - dataLen = bufPos - outPkt.getByteOffset(); - outPkt.setByteCount(dataLen); - - // Set the variable data block length and returned file count parameter - - bufPos = outPkt.getByteOffset() + 1; - DataPacker.putIntelShort(dataLen - 3, buf, bufPos); - outPkt.setParameter(0, fileCnt); - - // Send the search response packet - - m_sess.sendResponseSMB(outPkt); - - // Check if the search string contains wildcards and this is the start of a new search, - // if not then - // release the search context now as the client will not continue the search. - - if (fileCnt == 1 && resumeLen == 0 && WildCard.containsWildcards(srchPath) == false) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End search [" + searchId + "] (Not wildcard)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - } - } - - /** - * Process a search request that is for the volume label. - * - * @param outPkt SMBSrvPacket - */ - protected final void procSearchVolumeLabel(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Start Search - Volume Label"); - - // Access the shared devices disk interface - - DiskInterface disk = null; - DiskDeviceContext diskCtx = null; - - try - { - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - diskCtx = (DiskDeviceContext) conn.getContext(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the volume label - - VolumeInfo volInfo = diskCtx.getVolumeInformation(); - String volLabel = ""; - if (volInfo != null) - volLabel = volInfo.getVolumeLabel(); - - // Start building the search response packet - - outPkt.setParameterCount(1); - int bufPos = outPkt.getByteOffset(); - byte[] buf = outPkt.getBuffer(); - buf[bufPos++] = (byte) DataType.VariableBlock; - - // Calculate the data length - - int dataLen = CoreResumeKey.LENGTH + 22; - DataPacker.putIntelShort(dataLen, buf, bufPos); - bufPos += 2; - - // Pack the resume key - - CoreResumeKey.putResumeKey(buf, bufPos, volLabel, -1); - bufPos += CoreResumeKey.LENGTH; - - // Pack the file information - - buf[bufPos++] = (byte) (FileAttribute.Volume & 0x00FF); - - // Zero the date/time and file length fields - - for (int i = 0; i < 8; i++) - buf[bufPos++] = (byte) 0; - - StringBuffer volBuf = new StringBuffer(); - volBuf.append(volLabel); - - while (volBuf.length() < 13) - volBuf.append(" "); - - if (volBuf.length() > 12) - volBuf.setLength(12); - - bufPos = DataPacker.putString(volBuf.toString().toUpperCase(), buf, bufPos, true); - - // Set the actual data length - - dataLen = bufPos - m_smbPkt.getByteOffset(); - outPkt.setByteCount(dataLen); - - // Send the search response packet - - m_sess.sendResponseSMB(outPkt); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Volume label for " + conn.toString() + " is " + volLabel); - return; - } - - /** - * Seek to the specified file position within the open file. - * - * @param pkt SMBSrvPacket - */ - protected final void procSeekFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file seek request - - if (m_smbPkt.checkPacketIsValid(4, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - int seekMode = m_smbPkt.getParameter(1); - long seekPos = (long) m_smbPkt.getParameterLong(2); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Seek [" + netFile.getFileId() + "] : Mode = " + seekMode + ", Pos = " + seekPos); - - // Seek to the specified position within the file - - long pos = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Seek to the file position - - pos = disk.seekFile(m_sess, conn, netFile, seekPos, seekMode); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Seek Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to seek the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd); - return; - } - - // Return the new file position - - outPkt.setParameterCount(2); - outPkt.setParameterLong(0, (int) (pos & 0x0FFFFFFFFL)); - outPkt.setByteCount(0); - - // Send the seek response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the SMB session setup request. - * - * @param outPkt Response SMB packet. - */ - - protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException, - TooManyConnectionsException - { - // Return an access denied error, require a logon - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - } - - /** - * Set the file attributes for a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procSetFileAttributes(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid set file attributes request - - if (m_smbPkt.checkPacketIsValid(8, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the file name - - String fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Get the file attributes - - int fattr = m_smbPkt.getParameter(0); - int setFlags = FileInfo.SetAttributes; - - FileInfo finfo = new FileInfo(fileName, 0, fattr); - - int fdate = m_smbPkt.getParameter(1); - int ftime = m_smbPkt.getParameter(2); - - if (fdate != 0 && ftime != 0) - { - finfo.setModifyDateTime(new SMBDate(fdate, ftime).getTime()); - setFlags += FileInfo.SetModifyDate; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Set File Attributes [" + treeId + "] name=" + fileName + ", attr=0x" - + Integer.toHexString(fattr) + ", fdate=" + fdate + ", ftime=" + ftime); - - // Access the disk interface and set the file attributes - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the specified file/directory - - finfo.setFileInformationFlags(setFlags); - disk.setFileInformation(m_sess, conn, fileName, finfo); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - } - - // Return the set file attributes response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Set file information. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procSetFileInformation(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid set file information2 request - - if (m_smbPkt.checkPacketIsValid(7, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request, and get the network file details. - - int fid = m_smbPkt.getParameter(0); - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Get the creation date/time from the request - - int setFlags = 0; - FileInfo finfo = new FileInfo(netFile.getName(), 0, 0); - - int fdate = m_smbPkt.getParameter(1); - int ftime = m_smbPkt.getParameter(2); - - if (fdate != 0 && ftime != 0) - { - finfo.setCreationDateTime(new SMBDate(fdate, ftime).getTime()); - setFlags += FileInfo.SetCreationDate; - } - - // Get the last access date/time from the request - - fdate = m_smbPkt.getParameter(3); - ftime = m_smbPkt.getParameter(4); - - if (fdate != 0 && ftime != 0) - { - finfo.setAccessDateTime(new SMBDate(fdate, ftime).getTime()); - setFlags += FileInfo.SetAccessDate; - } - - // Get the last write date/time from the request - - fdate = m_smbPkt.getParameter(5); - ftime = m_smbPkt.getParameter(6); - - if (fdate != 0 && ftime != 0) - { - finfo.setModifyDateTime(new SMBDate(fdate, ftime).getTime()); - setFlags += FileInfo.SetModifyDate; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Set File Information 2 [" + netFile.getFileId() + "] " + finfo.toString()); - - // Access the disk interface and set the file information - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Get the file information for the specified file/directory - - finfo.setFileInformationFlags(setFlags); - disk.setFileInformation(m_sess, conn, netFile.getFullName(), finfo); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - } - - // Return the set file information response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the SMB tree connect request. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - * @exception TooManyConnectionsException Too many concurrent connections on this session. - */ - - protected void procTreeConnect(SMBSrvPacket outPkt) throws SMBSrvException, TooManyConnectionsException, - java.io.IOException - { - - // Check that the received packet looks like a valid tree connect request - - if (m_smbPkt.checkPacketIsValid(0, 4) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the requested share name, as a UNC path - - boolean isUni = m_smbPkt.isUnicode(); - String uncPath = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni); - if (uncPath == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Extract the password string - - if (isUni) - { - dataPos = DataPacker.wordAlign(dataPos + 1) + (uncPath.length() * 2) + 2; - dataLen -= (uncPath.length() * 2) + 2; - } - else - { - dataPos += uncPath.length() + 2; - dataLen -= uncPath.length() + 2; - } - - String pwd = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni); - if (pwd == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Extract the service type string - - if (isUni) - { - dataPos = DataPacker.wordAlign(dataPos + 1) + (pwd.length() * 2) + 2; - dataLen -= (pwd.length() * 2) + 2; - } - else - { - dataPos += pwd.length() + 2; - dataLen -= pwd.length() + 2; - } - - String service = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni); - if (service == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Convert the service type to a shared device type - - int servType = ShareType.ServiceAsType(service); - if (servType == ShareType.UNKNOWN) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree connect - " + uncPath + ", " + service); - - // Parse the requested share name - - PCShare share = null; - - try - { - share = new PCShare(uncPath); - } - catch (InvalidUNCPathException ex) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Map the IPC$ share to the admin pipe type - - if (servType == ShareType.NAMEDPIPE && share.getShareName().compareTo("IPC$") == 0) - servType = ShareType.ADMINPIPE; - - // Find the requested shared device - - SharedDevice shareDev = null; - - try - { - - // Get/create the shared device - - shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType, - getSession(), true); - } - catch (InvalidUserException ex) - { - - // Return a logon failure status - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (Exception ex) - { - - // Return a general status, bad network name - - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); - return; - } - - // Check if the share is valid - - if (shareDev == null || shareDev.getType() != servType) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Allocate a tree id for the new connection - - int treeId = vc.addConnection(shareDev); - - // Authenticate the share connection depending upon the security mode the server is running - // under - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - int filePerm = FileAccess.Writeable; - - if (auth != null) - { - - // Validate the share connection - - filePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); - if (filePerm < 0) - { - - // Invalid share connection request - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - } - - // Set the file permission that this user has been granted for this share - - TreeConnection tree = m_sess.findTreeConnection( m_smbPkt); - tree.setPermission(filePerm); - - // Build the tree connect response - - outPkt.setParameterCount(2); - - outPkt.setParameter(0, buf.length - RFCNetBIOSProtocol.HEADER_LEN); - outPkt.setParameter(1, treeId); - outPkt.setByteCount(0); - - // Clear any chained request - - outPkt.setAndXCommand(0xFF); - m_sess.sendResponseSMB(outPkt); - - // Inform the driver that a connection has been opened - - if (tree.getInterface() != null) - tree.getInterface().treeOpened(m_sess, tree); - } - - /** - * Process the SMB tree disconnect request. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procTreeDisconnect(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid tree disconnect request - - if (m_smbPkt.checkPacketIsValid(0, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree disconnect - " + treeId + ", " + conn.toString()); - - // Remove the specified connection from the session - - vc.removeConnection(treeId, m_sess); - - // Build the tree disconnect response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - m_sess.sendResponseSMB(outPkt); - - // Inform the driver that a connection has been closed - - if (conn.getInterface() != null) - conn.getInterface().treeClosed(m_sess, conn); - } - - /** - * Unlock a byte range in the specified file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procUnLockFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid unlock file request - - if (m_smbPkt.checkPacketIsValid(5, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - long lockcnt = m_smbPkt.getParameterLong(1); - long lockoff = m_smbPkt.getParameterLong(3); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File UnLock [" + netFile.getFileId() + "] : Offset=" + lockoff + " ,Count=" + lockcnt); - - // ***** Always return a success status, simulated locking **** - // - // Build the unlock file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Unsupported SMB procesing. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procUnsupported(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Send an unsupported error response - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - - /** - * Write to a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procWriteFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file write request - - if (m_smbPkt.checkPacketIsValid(5, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - int wrtcnt = m_smbPkt.getParameter(1); - long wrtoff = (m_smbPkt.getParameter(2) + (m_smbPkt.getParameter(3) << 16)) & 0xFFFFFFFFL; - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write [" + netFile.getFileId() + "] : Size=" + wrtcnt + " ,Pos=" + wrtoff); - - // Write data to the file - - byte[] buf = m_smbPkt.getBuffer(); - int pos = m_smbPkt.getByteOffset(); - int wrtlen = 0; - - // Check that the data block is valid - - if (buf[pos] != DataType.DataBlock) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Update the buffer position to the start of the data to be written - - pos += 3; - - // Check for a zero length write, this should truncate/extend the file to the write - // offset position - - if (wrtcnt == 0) - { - - // Truncate/extend the file to the write offset - - disk.truncateFile(m_sess, conn, netFile, wrtoff); - } - else - { - - // Write to the file - - wrtlen = disk.writeFile(m_sess, conn, netFile, buf, pos, wrtcnt, wrtoff); - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - - // Return the count of bytes actually written - - outPkt.setParameterCount(1); - outPkt.setParameter(0, wrtlen); - outPkt.setByteCount(0); - - // Send the write response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Write to a file then close the file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procWriteAndCloseFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file write and close request - - if (m_smbPkt.checkPacketIsValid(6, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection( m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - int wrtcnt = m_smbPkt.getParameter(1); - int wrtoff = m_smbPkt.getParameterLong(2); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write And Close [" + netFile.getFileId() + "] : Size=" + wrtcnt + " ,Pos=" + wrtoff); - - // Write data to the file - - byte[] buf = m_smbPkt.getBuffer(); - int pos = m_smbPkt.getByteOffset() + 1; // word align - int wrtlen = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Write to the file - - wrtlen = disk.writeFile(m_sess, conn, netFile, buf, pos, wrtcnt, wrtoff); - - // Close the file - // - // The disk interface may be null if the file is a named pipe file - - if (disk != null) - disk.closeFile(m_sess, conn, netFile); - - // Indicate that the file has been closed - - netFile.setClosed(true); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - - // Return the count of bytes actually written - - outPkt.setParameterCount(1); - outPkt.setParameter(0, wrtlen); - outPkt.setByteCount(0); - - outPkt.setError(0, 0); - - // Send the write response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Run the core SMB protocol handler. - * - * @return boolean true if the packet was processed, else false - */ - public boolean runProtocol() throws java.io.IOException, SMBSrvException, TooManyConnectionsException - { - - // Check if the SMB packet is initialized - - if (m_smbPkt == null) - m_smbPkt = new SMBSrvPacket(m_sess.getBuffer()); - - // Determine the SMB command type - - boolean handledOK = true; - SMBSrvPacket outPkt = m_smbPkt; - - switch (m_smbPkt.getCommand()) - { - - // Session setup - - case PacketType.SessionSetupAndX: - procSessionSetup(outPkt); - break; - - // Tree connect - - case PacketType.TreeConnect: - procTreeConnect(outPkt); - break; - - // Tree disconnect - - case PacketType.TreeDisconnect: - procTreeDisconnect(outPkt); - break; - - // Search - - case PacketType.Search: - procSearch(outPkt); - break; - - // Get disk attributes - - case PacketType.DiskInformation: - procDiskAttributes(outPkt); - break; - - // Get file attributes - - case PacketType.GetFileAttributes: - procGetFileAttributes(outPkt); - break; - - // Set file attributes - - case PacketType.SetFileAttributes: - procSetFileAttributes(outPkt); - break; - - // Get file information - - case PacketType.QueryInformation2: - procGetFileInformation(outPkt); - break; - - // Set file information - - case PacketType.SetInformation2: - procSetFileInformation(outPkt); - break; - - // Open a file - - case PacketType.OpenFile: - procOpenFile(outPkt); - break; - - // Read from a file - - case PacketType.ReadFile: - procReadFile(outPkt); - break; - - // Seek file - - case PacketType.SeekFile: - procSeekFile(outPkt); - break; - - // Close a file - - case PacketType.CloseFile: - procCloseFile(outPkt); - break; - - // Create a new file - - case PacketType.CreateFile: - case PacketType.CreateNew: - procCreateFile(outPkt); - break; - - // Write to a file - - case PacketType.WriteFile: - procWriteFile(outPkt); - break; - - // Write to a file, then close the file - - case PacketType.WriteAndClose: - procWriteAndCloseFile(outPkt); - break; - - // Flush file - - case PacketType.FlushFile: - procFlushFile(outPkt); - break; - - // Rename a file - - case PacketType.RenameFile: - procRenameFile(outPkt); - break; - - // Delete a file - - case PacketType.DeleteFile: - procDeleteFile(outPkt); - break; - - // Create a new directory - - case PacketType.CreateDirectory: - procCreateDirectory(outPkt); - break; - - // Delete a directory - - case PacketType.DeleteDirectory: - procDeleteDirectory(outPkt); - break; - - // Check if a directory exists - - case PacketType.CheckDirectory: - procCheckDirectory(outPkt); - break; - - // Unsupported requests - - case PacketType.IOCtl: - procUnsupported(outPkt); - break; - - // Echo request - - case PacketType.Echo: - procEcho(outPkt); - break; - - // Process exit request - - case PacketType.ProcessExit: - procProcessExit(outPkt); - break; - - // Create temoporary file request - - case PacketType.CreateTemporary: - procCreateTemporaryFile(outPkt); - break; - - // Lock file request - - case PacketType.LockFile: - procLockFile(outPkt); - break; - - // Unlock file request - - case PacketType.UnLockFile: - procUnLockFile(outPkt); - break; - - // Default - - default: - - // Indicate that the protocol handler did not process the SMB request - - handledOK = false; - break; - } - - // Return the handled status - - return handledOK; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/CoreResumeKey.java b/source/java/org/alfresco/filesys/smb/server/CoreResumeKey.java deleted file mode 100644 index 702fadfebf..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/CoreResumeKey.java +++ /dev/null @@ -1,229 +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.smb.server; - -import java.io.PrintStream; - -import org.alfresco.filesys.util.DataPacker; - -/** - * Core protocol search resume key. - */ -class CoreResumeKey -{ - // Resume key offsets/lengths - - private static final int RESBITS = 0; - private static final int FILENAME = 1; - private static final int RESSERVER = 12; - private static final int RESCONSUMER = 17; - - private static final int FILENAMELEN = 11; - private static final int RESSRVLEN = 5; - private static final int RESCONSUMLEN = 4; - - public static final int LENGTH = 21; - - /** - * Dump the resume key to the specified output stream. - * - * @param out java.io.PrintStream - * @param buf byte[] - * @param pos int - */ - public final static void DumpKey(PrintStream out, byte[] buf, int pos) - { - - // Output the various resume key fields - - out.print("[" + getReservedByte(buf, pos) + ", "); - out.print(getFileName(buf, pos, false) + "]"); - } - - /** - * Return the consumer area of the resume key. - * - * @return byte[] - */ - public static final byte[] getConsumerArea(byte[] buf, int pos) - { - byte[] conArea = new byte[RESCONSUMLEN]; - for (int i = 0; i < RESCONSUMLEN; i++) - conArea[i] = buf[pos + RESCONSUMER + i]; - return conArea; - } - - /** - * Return the file name from the resume key. - * - * @return java.lang.String - */ - public static final String getFileName(byte[] buf, int pos, boolean dot) - { - - // Check if we should return the file name in 8.3 format - - if (dot) - { - - // Build the 8.3 file name - - StringBuffer name = new StringBuffer(); - name.append(new String(buf, pos + FILENAMELEN, 8).trim()); - name.append("."); - name.append(new String(buf, pos + FILENAMELEN + 8, 3).trim()); - - return name.toString(); - } - - // Return the raw string - - return new String(buf, pos + FILENAME, FILENAMELEN).trim(); - } - - /** - * Return the reserved byte from the resume key. - * - * @return byte - */ - public static final byte getReservedByte(byte[] buf, int pos) - { - return buf[pos]; - } - - /** - * Copy the resume key from the buffer to the user buffer. - * - * @param buf byte[] - * @param pos int - * @param key byte[] - */ - public final static void getResumeKey(byte[] buf, int pos, byte[] key) - { - - // Copy the resume key bytes - - System.arraycopy(buf, pos, key, 0, LENGTH); - } - - /** - * Return the server area resume key value. This is the search context index in our case. - * - * @return int Server resume key value ( search context index). - */ - public static final int getServerArea(byte[] buf, int pos) - { - return DataPacker.getIntelInt(buf, pos + RESSERVER + 1); - } - - /** - * Generate a resume key with the specified filename and search context id. - * - * @param buf byte[] - * @param pos - * @param fileName java.lang.String - * @param ctxId int - */ - public final static void putResumeKey(byte[] buf, int pos, String fileName, int ctxId) - { - - // Clear the reserved area - - buf[pos + RESBITS] = 0x16; - - // Put the file name in resume key format - - setFileName(buf, pos, fileName); - - // Put the server side reserved area - - setServerArea(buf, pos, ctxId); - // setServerArea( buf, pos, 0); - } - - /** - * Set the consumer reserved area value. - * - * @param conArea byte[] - */ - public static final void setConsumerArea(byte[] buf, int pos, byte[] conArea) - { - for (int i = 0; i < RESCONSUMLEN; i++) - buf[pos + RESCONSUMER + i] = conArea[i]; - } - - /** - * Set the resume key file name string. - * - * @param name java.lang.String - */ - public static final void setFileName(byte[] buf, int pos, String name) - { - - // Split the file name string - - StringBuffer str = new StringBuffer(); - int dot = name.indexOf("."); - if (dot != -1) - { - str.append(name.substring(0, dot)); - while (str.length() < 8) - str.append(" "); - str.append(name.substring(dot + 1, name.length())); - } - else - str.append(name); - - // Space fill the file name to 11 characters - - while (str.length() < FILENAMELEN) - str.append(" "); - - // Pack the file name string into the resume key - - DataPacker.putString(str.toString(), buf, pos + FILENAME, false); - } - - /** - * Set the resume key reserved byte value. - * - * @param param byte - */ - public static final void setReservedByte(byte[] buf, int pos, byte val) - { - buf[pos] = val; - } - - /** - * Set the resume key server area value. This is the search context index in our case. - * - * @param srvVal int - */ - public static final void setServerArea(byte[] buf, int pos, int srvVal) - { - buf[pos + RESSERVER] = 1; - DataPacker.putIntelInt(srvVal, buf, pos + RESSERVER + 1); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java b/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java deleted file mode 100644 index 559b71a3c4..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/DCERPCHandler.java +++ /dev/null @@ -1,804 +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.smb.server; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.TransactBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBuffer; -import org.alfresco.filesys.smb.dcerpc.DCEBufferException; -import org.alfresco.filesys.smb.dcerpc.DCECommand; -import org.alfresco.filesys.smb.dcerpc.DCEDataPacker; -import org.alfresco.filesys.smb.dcerpc.DCEPipeType; -import org.alfresco.filesys.smb.dcerpc.UUID; -import org.alfresco.filesys.smb.dcerpc.server.DCEPipeFile; -import org.alfresco.filesys.smb.dcerpc.server.DCESrvPacket; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * DCE/RPC Protocol Handler Class - */ -public class DCERPCHandler -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - /** - * Process a DCE/RPC request - * - * @param sess SMBSrvSession - * @param srvTrans SMBSrvTransPacket - * @param outPkt SMBSrvPacket - * @exception IOException - * @exception SMBSrvException - */ - public static final void processDCERPCRequest(SMBSrvSession sess, SMBSrvTransPacket srvTrans, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection( srvTrans); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the file id and validate - - int fid = srvTrans.getSetupParameter(1); - int maxData = srvTrans.getParameter(3) - DCEBuffer.OPERATIONDATA; - - // Get the IPC pipe file for the specified file id - - DCEPipeFile pipeFile = (DCEPipeFile) conn.findFile(fid); - if (pipeFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Create a DCE/RPC buffer from the received data - - DCEBuffer dceBuf = new DCEBuffer(srvTrans.getBuffer(), srvTrans.getParameter(10) - + RFCNetBIOSProtocol.HEADER_LEN); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("TransactNmPipe pipeFile=" + pipeFile.getName() + ", fid=" + fid + ", dceCmd=0x" - + Integer.toHexString(dceBuf.getHeaderValue(DCEBuffer.HDR_PDUTYPE))); - - // Process the received DCE buffer - - processDCEBuffer(sess, dceBuf, pipeFile); - - // Check if there is a reply buffer to return to the caller - - if (pipeFile.hasBufferedData() == false) - return; - - DCEBuffer txBuf = pipeFile.getBufferedData(); - - // Initialize the reply - - DCESrvPacket dcePkt = new DCESrvPacket(outPkt.getBuffer()); - - // Always only one fragment as the data either fits into the first reply fragment or the - // client will read the remaining data by issuing read requests on the pipe - - int flags = DCESrvPacket.FLG_ONLYFRAG; - - dcePkt.initializeDCEReply(); - txBuf.setHeaderValue(DCEBuffer.HDR_FLAGS, flags); - - // Build the reply data - - byte[] buf = dcePkt.getBuffer(); - int pos = DCEDataPacker.longwordAlign(dcePkt.getByteOffset()); - - // Set the DCE fragment size and send the reply DCE/RPC SMB - - int dataLen = txBuf.getLength(); - txBuf.setHeaderValue(DCEBuffer.HDR_FRAGLEN, dataLen); - - // Copy the data from the DCE output buffer to the reply SMB packet - - int len = txBuf.getLength(); - int sts = SMBStatus.NTSuccess; - - if (len > maxData) - { - - // Write the maximum transmit fragment to the reply - - len = maxData + DCEBuffer.OPERATIONDATA; - dataLen = maxData + DCEBuffer.OPERATIONDATA; - - // Indicate a buffer overflow status - - sts = SMBStatus.NTBufferOverflow; - } - else - { - - // Clear the DCE/RPC pipe buffered data, the reply will fit into a single response - // packet - - pipeFile.setBufferedData(null); - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("Reply DCEbuf flags=0x" + Integer.toHexString(flags) + ", len=" + len + ", status=0x" - + Integer.toHexString(sts)); - - // Copy the reply data to the reply packet - - try - { - pos += txBuf.copyData(buf, pos, len); - } - catch (DCEBufferException ex) - { - sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Set the SMB transaction data length - - int byteLen = pos - dcePkt.getByteOffset(); - dcePkt.setParameter(1, dataLen); - dcePkt.setParameter(6, dataLen); - dcePkt.setByteCount(byteLen); - dcePkt.setFlags2(SMBPacket.FLG2_LONGERRORCODE); - dcePkt.setLongErrorCode(sts); - - sess.sendResponseSMB(dcePkt); - } - - /** - * Process a DCE/RPC request - * - * @param sess SMBSrvSession - * @param vc VirtualCircuit - * @param tbuf TransactBuffer - * @param outPkt SMBSrvPacket - * @exception IOException - * @exception SMBSrvException - */ - public static final void processDCERPCRequest(SMBSrvSession sess, VirtualCircuit vc, TransactBuffer tbuf, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check if the transaction buffer has setup and data buffers - - if (tbuf.hasSetupBuffer() == false || tbuf.hasDataBuffer() == false) - { - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = vc.findConnection( tbuf.getTreeId()); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the file id and validate - - DataBuffer setupBuf = tbuf.getSetupBuffer(); - - setupBuf.skipBytes(2); - int fid = setupBuf.getShort(); - int maxData = tbuf.getReturnDataLimit() - DCEBuffer.OPERATIONDATA; - - // Get the IPC pipe file for the specified file id - - DCEPipeFile pipeFile = (DCEPipeFile) conn.findFile(fid); - if (pipeFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Create a DCE/RPC buffer from the received transaction data - - DCEBuffer dceBuf = new DCEBuffer(tbuf); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("TransactNmPipe pipeFile=" + pipeFile.getName() + ", fid=" + fid + ", dceCmd=0x" - + Integer.toHexString(dceBuf.getHeaderValue(DCEBuffer.HDR_PDUTYPE))); - - // Process the received DCE buffer - - processDCEBuffer(sess, dceBuf, pipeFile); - - // Check if there is a reply buffer to return to the caller - - if (pipeFile.hasBufferedData() == false) - return; - - DCEBuffer txBuf = pipeFile.getBufferedData(); - - // Initialize the reply - - DCESrvPacket dcePkt = new DCESrvPacket(outPkt.getBuffer()); - - // Always only one fragment as the data either fits into the first reply fragment or the - // client will read the remaining data by issuing read requests on the pipe - - int flags = DCESrvPacket.FLG_ONLYFRAG; - - dcePkt.initializeDCEReply(); - txBuf.setHeaderValue(DCEBuffer.HDR_FLAGS, flags); - - // Build the reply data - - byte[] buf = dcePkt.getBuffer(); - int pos = DCEDataPacker.longwordAlign(dcePkt.getByteOffset()); - - // Set the DCE fragment size and send the reply DCE/RPC SMB - - int dataLen = txBuf.getLength(); - txBuf.setHeaderValue(DCEBuffer.HDR_FRAGLEN, dataLen); - - // Copy the data from the DCE output buffer to the reply SMB packet - - int len = txBuf.getLength(); - int sts = SMBStatus.NTSuccess; - - if (len > maxData) - { - - // Write the maximum transmit fragment to the reply - - len = maxData + DCEBuffer.OPERATIONDATA; - dataLen = maxData + DCEBuffer.OPERATIONDATA; - - // Indicate a buffer overflow status - - sts = SMBStatus.NTBufferOverflow; - } - else - { - - // Clear the DCE/RPC pipe buffered data, the reply will fit into a single response - // packet - - pipeFile.setBufferedData(null); - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("Reply DCEbuf flags=0x" + Integer.toHexString(flags) + ", len=" + len + ", status=0x" - + Integer.toHexString(sts)); - - // Copy the reply data to the reply packet - - try - { - pos += txBuf.copyData(buf, pos, len); - } - catch (DCEBufferException ex) - { - sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Set the SMB transaction data length - - int byteLen = pos - dcePkt.getByteOffset(); - dcePkt.setParameter(1, dataLen); - dcePkt.setParameter(6, dataLen); - dcePkt.setByteCount(byteLen); - dcePkt.setFlags2(SMBPacket.FLG2_LONGERRORCODE); - dcePkt.setLongErrorCode(sts); - - sess.sendResponseSMB(dcePkt); - } - - /** - * Process a DCE/RPC write request to the named pipe file - * - * @param sess SMBSrvSession - * @param inPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - * @exception IOException - * @exception SMBSrvException - */ - public static final void processDCERPCRequest(SMBSrvSession sess, SMBSrvPacket inPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection( inPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Determine if this is a write or write andX request - - int cmd = inPkt.getCommand(); - - // Get the file id and validate - - int fid = -1; - if (cmd == PacketType.WriteFile) - fid = inPkt.getParameter(0); - else - fid = inPkt.getParameter(2); - - // Get the IPC pipe file for the specified file id - - DCEPipeFile pipeFile = (DCEPipeFile) conn.findFile(fid); - if (pipeFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Create a DCE buffer for the received data - - DCEBuffer dceBuf = null; - byte[] buf = inPkt.getBuffer(); - int pos = 0; - int len = 0; - - if (cmd == PacketType.WriteFile) - { - - // Get the data offset - - pos = inPkt.getByteOffset(); - - // Check that the received data is valid - - if (buf[pos++] != DataType.DataBlock) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - len = DataPacker.getIntelShort(buf, pos); - pos += 2; - - } - else - { - - // Get the data offset and length - - len = inPkt.getParameter(10); - pos = inPkt.getParameter(11) + RFCNetBIOSProtocol.HEADER_LEN; - } - - // Create a DCE buffer mapped to the received packet - - dceBuf = new DCEBuffer(buf, pos); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("Write pipeFile=" + pipeFile.getName() + ", fid=" + fid + ", dceCmd=0x" - + Integer.toHexString(dceBuf.getHeaderValue(DCEBuffer.HDR_PDUTYPE))); - - // Process the DCE buffer - - processDCEBuffer(sess, dceBuf, pipeFile); - - // Check if there is a valid reply buffered - - int bufLen = 0; - if (pipeFile.hasBufferedData()) - bufLen = pipeFile.getBufferedData().getLength(); - - // Send the write/write andX reply - - if (cmd == PacketType.WriteFile) - { - - // Build the write file reply - - outPkt.setParameterCount(1); - outPkt.setParameter(0, len); - outPkt.setByteCount(0); - } - else - { - - // Build the write andX reply - - outPkt.setParameterCount(6); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); - outPkt.setParameter(2, len); - outPkt.setParameter(3, bufLen); - outPkt.setParameter(4, 0); - outPkt.setParameter(5, 0); - outPkt.setByteCount(0); - } - - // Send the write reply - - outPkt.setFlags2(SMBPacket.FLG2_LONGERRORCODE); - sess.sendResponseSMB(outPkt); - } - - /** - * Process a DCE/RPC pipe read request - * - * @param sess SMBSrvSession - * @param inPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - * @exception IOException - * @exception SMBSrvException - */ - public static final void processDCERPCRead(SMBSrvSession sess, SMBSrvPacket inPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection( inPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Determine if this is a read or read andX request - - int cmd = inPkt.getCommand(); - - // Get the file id and read length, and validate - - int fid = -1; - int rdLen = -1; - - if (cmd == PacketType.ReadFile) - { - fid = inPkt.getParameter(0); - rdLen = inPkt.getParameter(1); - } - else - { - fid = inPkt.getParameter(2); - rdLen = inPkt.getParameter(5); - } - - // Get the IPC pipe file for the specified file id - - DCEPipeFile pipeFile = (DCEPipeFile) conn.findFile(fid); - if (pipeFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("Read pipeFile=" + pipeFile.getName() + ", fid=" + fid + ", rdLen=" + rdLen); - - // Check if there is a valid reply buffered - - if (pipeFile.hasBufferedData()) - { - - // Get the buffered data - - DCEBuffer bufData = pipeFile.getBufferedData(); - int bufLen = bufData.getAvailableLength(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug(" Buffered data available=" + bufLen); - - // Check if there is less data than the read size - - if (rdLen > bufLen) - rdLen = bufLen; - - // Build the read response - - if (cmd == PacketType.ReadFile) - { - - // Build the read response - - outPkt.setParameterCount(5); - outPkt.setParameter(0, rdLen); - for (int i = 1; i < 5; i++) - outPkt.setParameter(i, 0); - outPkt.setByteCount(rdLen + 3); - - // Copy the data to the response - - byte[] buf = outPkt.getBuffer(); - int pos = outPkt.getByteOffset(); - - buf[pos++] = (byte) DataType.DataBlock; - DataPacker.putIntelShort(rdLen, buf, pos); - pos += 2; - - try - { - bufData.copyData(buf, pos, rdLen); - } - catch (DCEBufferException ex) - { - logger.error("DCR/RPC read", ex); - } - } - else - { - - // Build the read andX response - - outPkt.setParameterCount(12); - outPkt.setAndXCommand(0xFF); - for (int i = 1; i < 12; i++) - outPkt.setParameter(i, 0); - - // Copy the data to the response - - byte[] buf = outPkt.getBuffer(); - int pos = DCEDataPacker.longwordAlign(outPkt.getByteOffset()); - - outPkt.setParameter(5, rdLen); - outPkt.setParameter(6, pos - RFCNetBIOSProtocol.HEADER_LEN); - outPkt.setByteCount((pos + rdLen) - outPkt.getByteOffset()); - - try - { - bufData.copyData(buf, pos, rdLen); - } - catch (DCEBufferException ex) - { - logger.error("DCE/RPC error", ex); - } - } - } - else - { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug(" No buffered data available"); - - // Return a zero length read response - - if (cmd == PacketType.ReadFile) - { - - // Initialize the read response - - outPkt.setParameterCount(5); - for (int i = 0; i < 5; i++) - outPkt.setParameter(i, 0); - outPkt.setByteCount(0); - } - else - { - - // Return a zero length read andX response - - outPkt.setParameterCount(12); - - outPkt.setAndXCommand(0xFF); - for (int i = 1; i < 12; i++) - outPkt.setParameter(i, 0); - outPkt.setByteCount(0); - } - } - - // Clear the status code - - outPkt.setLongErrorCode(SMBStatus.NTSuccess); - - // Send the read reply - - outPkt.setFlags2(SMBPacket.FLG2_LONGERRORCODE); - sess.sendResponseSMB(outPkt); - } - - /** - * Process the DCE/RPC request buffer - * - * @param sess SMBSrvSession - * @param buf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public static final void processDCEBuffer(SMBSrvSession sess, DCEBuffer dceBuf, DCEPipeFile pipeFile) - throws IOException, SMBSrvException - { - - // Process the DCE/RPC request - - switch (dceBuf.getHeaderValue(DCEBuffer.HDR_PDUTYPE)) - { - - // DCE Bind - - case DCECommand.BIND: - procDCEBind(sess, dceBuf, pipeFile); - break; - - // DCE Request - - case DCECommand.REQUEST: - procDCERequest(sess, dceBuf, pipeFile); - break; - - default: - sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - break; - } - } - - /** - * Process a DCE bind request - * - * @param sess SMBSrvSession - * @param dceBuf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public static final void procDCEBind(SMBSrvSession sess, DCEBuffer dceBuf, DCEPipeFile pipeFile) - throws IOException, SMBSrvException - { - - try - { - - // DEBUG - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("DCE Bind"); - - // Get the call id and skip the DCE header - - int callId = dceBuf.getHeaderValue(DCEBuffer.HDR_CALLID); - dceBuf.skipBytes(DCEBuffer.DCEDATA); - - // Unpack the bind request - - int maxTxSize = dceBuf.getShort(); - int maxRxSize = dceBuf.getShort(); - int groupId = dceBuf.getInt(); - int ctxElems = dceBuf.getByte(DCEBuffer.ALIGN_INT); - int presCtxId = dceBuf.getByte(DCEBuffer.ALIGN_SHORT); - int trfSyntax = dceBuf.getByte(DCEBuffer.ALIGN_SHORT); - - UUID uuid1 = dceBuf.getUUID(true); - UUID uuid2 = dceBuf.getUUID(true); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - { - logger.debug("Bind: maxTx=" + maxTxSize + ", maxRx=" + maxRxSize + ", groupId=" + groupId - + ", ctxElems=" + ctxElems + ", presCtxId=" + presCtxId + ", trfSyntax=" + trfSyntax); - logger.debug(" uuid1=" + uuid1.toString()); - logger.debug(" uuid2=" + uuid2.toString()); - } - - // Update the IPC pipe file - - pipeFile.setMaxTransmitFragmentSize(maxTxSize); - pipeFile.setMaxReceiveFragmentSize(maxRxSize); - - // Create an output DCE buffer for the reply and add the bind acknowledge header - - DCEBuffer txBuf = new DCEBuffer(); - txBuf.putBindAckHeader(dceBuf.getHeaderValue(DCEBuffer.HDR_CALLID)); - txBuf.setHeaderValue(DCEBuffer.HDR_FLAGS, DCEBuffer.FLG_ONLYFRAG); - - // Pack the bind acknowledge DCE reply - - txBuf.putShort(maxTxSize); - txBuf.putShort(maxRxSize); - txBuf.putInt(0x53F0); - - String srvPipeName = DCEPipeType.getServerPipeName(pipeFile.getPipeId()); - txBuf.putShort(srvPipeName.length() + 1); - txBuf.putASCIIString(srvPipeName, true, DCEBuffer.ALIGN_INT); - txBuf.putInt(1); - txBuf.putShort(0); - txBuf.putShort(0); - txBuf.putUUID(uuid2, true); - - txBuf.setHeaderValue(DCEBuffer.HDR_FRAGLEN, txBuf.getLength()); - - // Attach the reply buffer to the pipe file - - pipeFile.setBufferedData(txBuf); - } - catch (DCEBufferException ex) - { - sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - } - - /** - * Process a DCE request - * - * @param sess SMBSrvSession - * @param dceBuf DCEBuffer - * @param pipeFile DCEPipeFile - * @exception IOException - * @exception SMBSrvException - */ - public static final void procDCERequest(SMBSrvSession sess, DCEBuffer inBuf, DCEPipeFile pipeFile) - throws IOException, SMBSrvException - { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_DCERPC)) - logger.debug("DCE Request opNum=0x" + Integer.toHexString(inBuf.getHeaderValue(DCEBuffer.HDR_OPCODE))); - - // Pass the request to the DCE pipe request handler - - if (pipeFile.hasRequestHandler()) - pipeFile.getRequestHandler().processRequest(sess, inBuf, pipeFile); - else - sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/DiskInfoPacker.java b/source/java/org/alfresco/filesys/smb/server/DiskInfoPacker.java deleted file mode 100644 index 2ab915428b..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/DiskInfoPacker.java +++ /dev/null @@ -1,308 +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.smb.server; - -import org.alfresco.filesys.server.filesys.DiskInfo; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.VolumeInfo; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; - -/** - * Disk information packer class. - */ -class DiskInfoPacker -{ - - // Disk information levels - - public static final int InfoStandard = 1; - public static final int InfoVolume = 2; - public static final int InfoFsVolume = 0x102; - public static final int InfoFsSize = 0x103; - public static final int InfoFsDevice = 0x104; - public static final int InfoFsAttribute = 0x105; - public static final int InfoCifsUnix = 0x200; - public static final int InfoMacFsInfo = 0x301; - public static final int InfoFullFsSize = 0x3EF; - - // Mac support flags - - public static final int MacAccessControl = 0x0010; - public static final int MacGetSetComments = 0x0020; - public static final int MacDesktopDbCalls = 0x0040; - public static final int MacUniqueIds = 0x0080; - public static final int MacNoStreamsOrMacSupport = 0x0100; - - /** - * Class constructor. - */ - public DiskInfoPacker() - { - super(); - } - - /** - * Pack the standard disk information, InfoStandard. - * - * @param info SMBDiskInfo to be packed. - * @param buf Buffer to pack the data into. - */ - public final static void packStandardInfo(DiskInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG File system identifier, always 0 ? - // ULONG Sectors per allocation unit. - // ULONG Total allocation units. - // ULONG Total available allocation units. - // USHORT Number of bytes per sector. - - // Pack the file system identifier, 0 = NT file system - - buf.putZeros(4); - // buf.putInt(999); - - // Pack the disk unit information - - buf.putInt(info.getBlocksPerAllocationUnit()); - buf.putInt((int) info.getTotalUnits()); - buf.putInt((int) info.getFreeUnits()); - buf.putShort(info.getBlockSize()); - } - - /** - * Pack the volume label information, InfoVolume. - * - * @param info Volume information - * @param buf Buffer to pack data into. - * @param uni Use Unicode strings if true, else use ASCII strings - */ - public final static void packVolumeInfo(VolumeInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG Volume serial number - // UCHAR Volume label length - // STRING Volume label - - // Pack the volume serial number - - buf.putInt(info.getSerialNumber()); - - // Pack the volume label length and string - - buf.putByte(info.getVolumeLabel().length()); - buf.putString(info.getVolumeLabel(), uni); - } - - /** - * Pack the filesystem size information, InfoFsSize - * - * @param info Disk size information - * @param buf Buffer to pack data into. - */ - public final static void packFsSizeInformation(SrvDiskInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG Disk size (in units) - // ULONG Free size (in units) - // UINT Unit size in blocks - // UINT Block size in bytes - - buf.putLong(info.getTotalUnits()); - buf.putLong(info.getFreeUnits()); - buf.putInt(info.getBlocksPerAllocationUnit()); - buf.putInt(info.getBlockSize()); - } - - /** - * Pack the filesystem volume information, InfoFsVolume - * - * @param info Volume information - * @param buf Buffer to pack data into. - * @param uni Use Unicode strings if true, else use ASCII strings - */ - public final static void packFsVolumeInformation(VolumeInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG Volume creation date/time (NT 64bit time fomat) - // UINT Volume serial number - // UINT Volume label length - // SHORT Reserved - // STRING Volume label (no null) - - if (info.hasCreationDateTime()) - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - else - buf.putZeros(8); - - if (info.hasSerialNumber()) - buf.putInt(info.getSerialNumber()); - else - buf.putZeros(4); - - int len = info.getVolumeLabel().length(); - if (uni) - len *= 2; - buf.putInt(len); - - buf.putZeros(2); // reserved - buf.putString(info.getVolumeLabel(), uni, false); - } - - /** - * Pack the filesystem device information, InfoFsDevice - * - * @param typ Device type - * @param devChar Device characteristics - * @param buf Buffer to pack data into. - */ - public final static void packFsDevice(int typ, int devChar, DataBuffer buf) - { - - // Information format :- - // UINT Device type - // UINT Characteristics - - buf.putInt(typ); - buf.putInt(devChar); - } - - /** - * Pack the filesystem attribute information, InfoFsAttribute - * - * @param attr Attribute flags - * @param maxName Maximum file name component length - * @param fsType File system type name - * @param uni Unicode strings required - * @param buf Buffer to pack data into. - */ - public final static void packFsAttribute(int attr, int maxName, String fsType, boolean uni, DataBuffer buf) - { - - // Information format :- - // UINT Attribute flags - // UINT Maximum filename component length (usually 255) - // UINT Filesystem type length - // STRING Filesystem type string - - buf.putInt(attr); - buf.putInt(maxName); - - if (uni) - buf.putInt(fsType.length() * 2); - else - buf.putInt(fsType.length()); - buf.putString(fsType, uni, false); - } - - /** - * Pack the Mac filesystem information, InfoMacFsInfo - * - * @param diskInfo SMBDiskInfo to be packed. - * @param volInfo Volume information to be packed - * @param ntfs Filesystem supports NTFS streams - * @param buf Buffer to pack the data into. - */ - public final static void packMacFsInformation(DiskInfo diskInfo, VolumeInfo volInfo, boolean ntfs, DataBuffer buf) - { - - // Information format :- - // LARGE_INTEGER Volume creation time (NT format) - // LARGE_INTEGER Volume modify time (NT format) - // LARGE_INTEGER Volume backup time (NT format) - // ULONG Allocation blocks - // ULONG Allocation block size (multiple of 512) - // ULONG Free blocks on the volume - // UCHAR[32] Finder info - // LONG Number of files in root directory (zero if unknown) - // LONG Number of directories in the root directory (zero if unknown) - // LONG Number of files on the volume (zero if unknown) - // LONG Number of directories on the volume (zero if unknown) - // LONG Mac support flags (big endian) - - // Pack the volume creation time - - if (volInfo.hasCreationDateTime()) - { - long ntTime = NTTime.toNTTime(volInfo.getCreationDateTime()); - buf.putLong(ntTime); - buf.putLong(ntTime); - buf.putLong(ntTime); - } - else - buf.putZeros(24); - - // Pack the number of allocation blocks, block size and free block count - - buf.putInt((int) diskInfo.getTotalUnits()); - buf.putInt(diskInfo.getBlockSize() * diskInfo.getBlocksPerAllocationUnit()); - buf.putInt((int) diskInfo.getFreeUnits()); - - // Pack the finder information area - - buf.putZeros(32); - - // Pack the file/directory counts - - buf.putInt(0); - buf.putInt(0); - buf.putInt(0); - buf.putInt(0); - - // Pack the Mac support flags - - DataPacker.putIntelInt(ntfs ? 0 : MacNoStreamsOrMacSupport, buf.getBuffer(), buf.getPosition()); - buf.setPosition(buf.getPosition() + 4); - } - - /** - * Pack the filesystem size information, InfoFsSize - * - * @param userLimit User free units - * @param info Disk size information - * @param buf Buffer to pack data into. - */ - public final static void packFullFsSizeInformation(long userLimit, SrvDiskInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG Disk size (in units) - // ULONG User free size (in units) - // ULONG Free size (in units) - // UINT Unit size in blocks - // UINT Block size in bytes - - buf.putLong(info.getTotalUnits()); - buf.putLong(userLimit); - buf.putLong(info.getFreeUnits()); - buf.putInt(info.getBlocksPerAllocationUnit()); - buf.putInt(info.getBlockSize()); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/Find.java b/source/java/org/alfresco/filesys/smb/server/Find.java deleted file mode 100644 index 8e3bf41925..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/Find.java +++ /dev/null @@ -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.smb.server; - -/** - * Find First Flags Class - */ -class Find -{ - // Find first flags - - protected static final int CloseSearch = 0x01; - protected static final int CloseSearchAtEnd = 0x02; - protected static final int ResumeKeysRequired = 0x04; - protected static final int ContinuePrevious = 0x08; - protected static final int BackupIntent = 0x10; -} diff --git a/source/java/org/alfresco/filesys/smb/server/FindInfoPacker.java b/source/java/org/alfresco/filesys/smb/server/FindInfoPacker.java deleted file mode 100644 index ee7fbd273b..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/FindInfoPacker.java +++ /dev/null @@ -1,953 +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.smb.server; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.util.DataBuffer; - -/** - * Find Information Packer Class - *

- * Pack file information for a find first/find next information level. - */ -class FindInfoPacker -{ - - // Enable 8.3 name generation (required for Mac OS9) - - private static final boolean Enable8Dot3Names = false; - - // Enable packing of file id - - private static final boolean EnableFileIdPacking = false; - - // File information levels - - public static final int InfoStandard = 1; - public static final int InfoQueryEASize = 2; - public static final int InfoQueryEAFromList = 3; - public static final int InfoDirectory = 0x101; - public static final int InfoFullDirectory = 0x102; - public static final int InfoNames = 0x103; - public static final int InfoDirectoryBoth = 0x104; - public static final int InfoMacHfsInfo = 0x302; - - // File information fixed lengths, includes nulls on strings. - - public static final int InfoStandardLen = 24; - public static final int InfoQueryEASizeLen = 28; - public static final int InfoDirectoryLen = 64; - public static final int InfoFullDirectoryLen = 68; - public static final int InfoNamesLen = 12; - public static final int InfoDirectoryBothLen = 94; - public static final int InfoMacHfsLen = 120; - - /** - * Pack a file information object into the specified buffer, using information level 1 format. - * - * @param info File information to be packed. - * @param buf Data buffer to pack the file information into - * @param infoLevel File information level. - * @param uni Pack Unicode strings if true, else pack ASCII strings - * @return Length of data packed - */ - public final static int packInfo(FileInfo info, DataBuffer buf, int infoLevel, boolean uni) - throws UnsupportedInfoLevelException - { - - // Determine the information level - - int curPos = buf.getPosition(); - - switch (infoLevel) - { - - // Standard information - - case InfoStandard: - packInfoStandard(info, buf, false, uni); - break; - - // Standard information + EA list size - - case InfoQueryEASize: - packInfoStandard(info, buf, true, uni); - break; - - // File name information - - case InfoNames: - packInfoFileName(info, buf, uni); - break; - - // File/directory information - - case InfoDirectory: - packInfoDirectory(info, buf, uni); - break; - - // Full file/directory information - - case InfoFullDirectory: - packInfoDirectoryFull(info, buf, uni); - break; - - // Full file/directory information with short name - - case InfoDirectoryBoth: - packInfoDirectoryBoth(info, buf, uni); - break; - - // Pack Macintosh format file information - - case InfoMacHfsInfo: - packInfoMacHfs(info, buf, uni); - break; - } - - // Check if we packed any data - - if (curPos == buf.getPosition()) - throw new UnsupportedInfoLevelException(); - - // Return the length of the packed data - - return buf.getPosition() - curPos; - } - - /** - * Calculate the file name offset for the specified information level. - * - * @param infoLev int - * @param offset int - * @return int - */ - public final static int calcFileNameOffset(int infoLev, int offset) - { - - // Determine the information level - - int pos = offset; - - switch (infoLev) - { - - // Standard information level - - case InfoStandard: - pos += InfoStandard; - break; - - // Standard + EA size - - case InfoQueryEASize: - pos += InfoQueryEASizeLen; - break; - - // File name information - - case InfoNames: - pos += InfoNamesLen; - break; - - // File/directory information - - case InfoDirectory: - pos += InfoDirectoryLen; - break; - - // File/directory information full - - case InfoFullDirectory: - pos += InfoFullDirectoryLen; - break; - - // Full file/directory information full plus short name - - case InfoDirectoryBoth: - pos += InfoDirectoryBothLen; - break; - } - - // Return the file name offset - - return pos; - } - - /** - * Calculate the required buffer space for the file information at the specified file - * information level. - * - * @param info File information - * @param infoLev File information level requested. - * @param resKey true if resume keys are being returned, else false. - * @param uni true if Unicode strings are being used, or false for ASCII strings - * @return int Buffer space required, or -1 if unknown information level. - */ - public final static int calcInfoSize(FileInfo info, int infoLev, boolean resKey, boolean uni) - { - - // Determine the information level requested - - int len = -1; - int nameLen = info.getFileName().length() + 1; - if (uni) - nameLen *= 2; - - switch (infoLev) - { - - // Standard information level - - case InfoStandard: - len = InfoStandardLen + nameLen; - break; - - // Standard + EA size - - case InfoQueryEASize: - len = InfoQueryEASizeLen + nameLen; - break; - - // File name information - - case InfoNames: - len += InfoNamesLen + nameLen; - break; - - // File/directory information - - case InfoDirectory: - len = InfoDirectoryLen + nameLen; - break; - - // File/directory information full - - case InfoFullDirectory: - len += InfoFullDirectoryLen + nameLen; - break; - - // Full file/directory information plus short name - - case InfoDirectoryBoth: - len = InfoDirectoryBothLen + nameLen; - break; - - // Maacintosh information level - - case InfoMacHfsInfo: - len = InfoMacHfsLen + nameLen; - break; - } - - // Add extra space for the resume key, if enabled - - if (resKey) - len += 4; - - // Return the buffer length required. - - return len; - } - - /** - * Clear the next structure offset - * - * @param dataBuf DataBuffer - * @param level int - * @param offset int - */ - public static final void clearNextOffset(DataBuffer buf, int level, int offset) - { - - // Standard information level does not have a next entry offset - - if (level == InfoStandard) - return; - - // Clear the next entry offset - - int curPos = buf.getPosition(); - buf.setPosition(offset); - buf.putInt(0); - buf.setPosition(curPos); - } - - /** - * Pack a file information object into the specified buffer. Use the standard information level - * if the EA size flag is false, else add the EA size field. - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param EAflag Add EA size field if true. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoStandard(FileInfo info, DataBuffer buf, boolean EAflag, boolean uni) - { - - // Information format :- - // SMB_DATE CreationDate - // SMB_TIME CreationTime - // SMB_DATE LastAccessDate - // SMB_TIME LastAccessTime - // SMB_DATE LastWriteDate - // SMB_TIME LastWriteTime - // ULONG File size - // ULONG Allocation size - // USHORT File attributes - // [ ULONG EA size ] - // UCHAR File name length - // STRING File name, null terminated - - // Pack the creation date/time - - SMBDate date = new SMBDate(0); - - if (info.hasCreationDateTime()) - { - date.setTime(info.getCreationDateTime()); - buf.putShort(date.asSMBDate()); - buf.putShort(date.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - date.setTime(info.getAccessDateTime()); - buf.putShort(date.asSMBDate()); - buf.putShort(date.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the last write date/time - - if (info.hasModifyDateTime()) - { - date.setTime(info.getModifyDateTime()); - buf.putShort(date.asSMBDate()); - buf.putShort(date.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the file size and allocation size - - buf.putInt(info.getSizeInt()); - - if (info.getAllocationSize() < info.getSize()) - buf.putInt(info.getSizeInt()); - else - buf.putInt(info.getAllocationSizeInt()); - - // Pack the file attributes - - buf.putShort(info.getFileAttributes()); - - // Pack the EA size, always zero - - if (EAflag) - buf.putInt(0); - - // Pack the file name - - if (uni == true) - { - - // Pack the number of bytes followed by the Unicode name word aligned - - buf.putByte(info.getFileName().length() * 2); - buf.wordAlign(); - buf.putString(info.getFileName(), uni, true); - } - else - { - - // Pack the number of bytes followed by the ASCII name - - buf.putByte(info.getFileName().length()); - buf.putString(info.getFileName(), uni, true); - } - } - - /** - * Pack the file name information - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoFileName(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG NextEntryOffset - // ULONG FileIndex - // ULONG FileNameLength - // STRING FileName - - // Pack the file id - - int startPos = buf.getPosition(); - buf.putZeros(4); - buf.putInt(EnableFileIdPacking ? info.getFileId() : 0); - - // Pack the file name length - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - - // Pack the long file name string - - buf.putString(info.getFileName(), uni, false); - - // Align the buffer pointer and set the offset to the next file information entry - - buf.wordAlign(); - - int curPos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(curPos - startPos); - buf.setPosition(curPos); - } - - /** - * Pack the file/directory information - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoDirectory(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG NextEntryOffset - // ULONG FileIndex - // LARGE_INTEGER CreationTime - // LARGE_INTEGER LastAccessTime - // LARGE_INTEGER LastWriteTime - // LARGE_INTEGER ChangeTime - // LARGE_INTEGER EndOfFile - // LARGE_INTEGER AllocationSize - // ULONG FileAttributes - // ULONG FileNameLength - // STRING FileName - - // Pack the file id - - int startPos = buf.getPosition(); - buf.putZeros(4); - buf.putInt(EnableFileIdPacking ? info.getFileId() : 0); - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write date/time and change time - - if (info.hasModifyDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - } - else - buf.putZeros(16); - - // Pack the file size and allocation size - - buf.putLong(info.getSize()); - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack the file name length - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - - // Pack the long file name string - - buf.putString(info.getFileName(), uni, false); - - // Align the buffer pointer and set the offset to the next file information entry - - buf.wordAlign(); - - int curPos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(curPos - startPos); - buf.setPosition(curPos); - } - - /** - * Pack the full file/directory information - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoDirectoryFull(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG NextEntryOffset - // ULONG FileIndex - // LARGE_INTEGER CreationTime - // LARGE_INTEGER LastAccessTime - // LARGE_INTEGER LastWriteTime - // LARGE_INTEGER ChangeTime - // LARGE_INTEGER EndOfFile - // LARGE_INTEGER AllocationSize - // ULONG FileAttributes - // ULONG FileNameLength - // ULONG EaSize - // STRING FileName - - // Pack the file id - - int startPos = buf.getPosition(); - buf.putZeros(4); - buf.putInt(EnableFileIdPacking ? info.getFileId() : 0); - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write date/time - - if (info.hasModifyDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - } - else - buf.putZeros(16); - - // Pack the file size and allocation size - - buf.putLong(info.getSize()); - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack the file name length - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - - // Pack the EA size - - buf.putZeros(4); - - // Pack the long file name string - - buf.putString(info.getFileName(), uni, false); - - // Align the buffer pointer and set the offset to the next file information entry - - buf.wordAlign(); - - int curPos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(curPos - startPos); - buf.setPosition(curPos); - } - - /** - * Pack the full file/directory information - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoDirectoryBoth(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG NextEntryOffset - // ULONG FileIndex - // LARGE_INTEGER CreationTime - // LARGE_INTEGER LastAccessTime - // LARGE_INTEGER LastWriteTime - // LARGE_INTEGER ChangeTime - // LARGE_INTEGER EndOfFile - // LARGE_INTEGER AllocationSize - // ULONG FileAttributes - // ULONG FileNameLength - // ULONG EaSize - // UCHAR ShortNameLength - // WCHAR ShortName[12] - // STRING FileName - - // Pack the file id - - int startPos = buf.getPosition(); - buf.putZeros(4); - buf.putInt(EnableFileIdPacking ? info.getFileId() : 0); - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write date/time and change time - - if (info.hasModifyDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - } - else - buf.putZeros(16); - - // Pack the file size and allocation size - - buf.putLong(info.getSize()); - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack the file name length - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - - // Pack the EA size - - buf.putZeros(4); - - // Pack the short file name length (8.3 name) - - pack8Dot3Name(buf, info.getFileName(), uni); - - // Pack the long file name string - - buf.putString(info.getFileName(), uni, false); - - // Align the buffer pointer and set the offset to the next file information entry - - buf.wordAlign(); - - int curPos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(curPos - startPos); - buf.setPosition(curPos); - } - - /** - * Pack the Macintosh format file/directory information - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param uni Pack Unicode strings if true, else pack ASCII strings - */ - protected final static void packInfoMacHfs(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG NextEntryOffset - // ULONG FileIndex - // LARGE_INTEGER CreationTime - // LARGE_INTEGER LastWriteTime - // LARGE_INTEGER ChangeTime - // LARGE_INTEGER Data stream length - // LARGE_INTEGER Resource stream length - // LARGE_INTEGER Data stream allocation size - // LARGE_INTEGER Resource stream allocation size - // ULONG ExtFileAttributes - // UCHAR FLAttrib Macintosh SetFLock, 1 = file locked - // UCHAR Pad - // UWORD DrNmFls Number of items in a directory, zero for files - // ULONG AccessControl - // UCHAR FinderInfo[32] - // ULONG FileNameLength - // UCHAR ShortNameLength - // UCHAR Pad - // WCHAR ShortName[12] - // STRING FileName - // LONG UniqueId - - // Pack the file id - - int startPos = buf.getPosition(); - buf.putZeros(4); - buf.putInt(EnableFileIdPacking ? info.getFileId() : 0); - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write date/time and change time - - if (info.hasModifyDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - buf.putLong(NTTime.toNTTime(info.getModifyDateTime())); - } - else - buf.putZeros(16); - - // Pack the data stream size and resource stream size (always zero) - - buf.putLong(info.getSize()); - buf.putZeros(8); - - // Pack the data stream allocation size and resource stream allocation size (always zero) - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - buf.putZeros(8); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack the file lock and padding byte - - buf.putZeros(2); - - // Pack the number of items in a directory, always zero for now - - buf.putShort(0); - - // Pack the access control - - buf.putInt(0); - - // Pack the finder information - - buf.putZeros(32); - - // Pack the file name length - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - - // Pack the short file name length (8.3 name) and name - - pack8Dot3Name(buf, info.getFileName(), uni); - - // Pack the long file name string - - buf.putString(info.getFileName(), uni, false); - - // Pack the unique id - - buf.putInt(0); - - // Align the buffer pointer and set the offset to the next file information entry - - buf.wordAlign(); - - int curPos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(curPos - startPos); - buf.setPosition(curPos); - } - - /** - * Pack a file name as a short 8.3 DOS style name. Packs the short name length byte, reserved - * byte and 8.3 file name string. - * - * @param buf DataBuffer - * @param fileName String - * @param uni boolean - */ - private static final void pack8Dot3Name(DataBuffer buf, String fileName, boolean uni) - { - - if (Enable8Dot3Names == false) - { - - // Pack an emty 8.3 name structure - - buf.putZeros(26); - } - else - { - - // Split the file name string into name and extension - - int pos = fileName.lastIndexOf('.'); - - String namePart = null; - String extPart = null; - - if (pos != -1) - { - - // Split the file name string - - namePart = fileName.substring(0, pos); - extPart = fileName.substring(pos + 1); - } - else - namePart = fileName; - - // If the name already fits into an 8.3 name we do not need to pack the short name - - if (namePart.length() <= 8 && (extPart == null || extPart.length() <= 3)) - { - - // Pack an emty 8.3 name structure - - buf.putZeros(26); - return; - } - - // Truncate the name and extension parts down to 8.3 sizes - - if (namePart.length() > 8) - namePart = namePart.substring(0, 6) + "~1"; - - if (extPart != null && extPart.length() > 3) - extPart = extPart.substring(0, 3); - - // Build the 8.3 format string - - StringBuffer str = new StringBuffer(16); - - str.append(namePart); - while (str.length() < 8) - str.append(" "); - - if (extPart != null) - { - str.append("."); - str.append(extPart); - } - else - str.append(" "); - - // Space pad the string to 12 characters - - while (str.length() < 12) - str.append(" "); - - // Calculate the used length - - int len = namePart.length(); - if (extPart != null) - len = extPart.length() + 9; - - len *= 2; - - // Pack the 8.3 file name structure, always packed as Unicode - - buf.putByte(len); - buf.putByte(0); - - buf.putString(str.toString(), true, false); - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/IPCHandler.java b/source/java/org/alfresco/filesys/smb/server/IPCHandler.java deleted file mode 100644 index aa300b6de5..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/IPCHandler.java +++ /dev/null @@ -1,804 +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.smb.server; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.PathNotFoundException; -import org.alfresco.filesys.server.filesys.TooManyFilesException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.TransactionNames; -import org.alfresco.filesys.smb.dcerpc.DCEPipeType; -import org.alfresco.filesys.smb.dcerpc.server.DCEPipeFile; -import org.alfresco.filesys.smb.dcerpc.server.DCEPipeHandler; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - *

- * The IPCHandler class processes requests made on the IPC$ remote admin pipe. The code is shared - * amongst different SMB protocol handlers. - */ -class IPCHandler -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - /** - * Process a request made on the IPC$ remote admin named pipe. - * - * @param sess SMBSrvSession - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - public static void processIPCRequest(SMBSrvSession sess, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the received packet from the session and verify that the connection is valid - - SMBSrvPacket smbPkt = sess.getReceivePacket(); - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection(smbPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ Request [" + smbPkt.getTreeId() + "] - cmd = " + smbPkt.getPacketTypeString()); - - // Determine the SMB command - - switch (smbPkt.getCommand()) - { - - // Open file request - - case PacketType.OpenAndX: - case PacketType.OpenFile: - procIPCFileOpen(sess, smbPkt, outPkt); - break; - - // Read file request - - case PacketType.ReadFile: - procIPCFileRead(sess, smbPkt, outPkt); - break; - - // Read AndX file request - - case PacketType.ReadAndX: - procIPCFileReadAndX(sess, smbPkt, outPkt); - break; - - // Write file request - - case PacketType.WriteFile: - procIPCFileWrite(sess, smbPkt, outPkt); - break; - - // Write AndX file request - - case PacketType.WriteAndX: - procIPCFileWriteAndX(sess, smbPkt, outPkt); - break; - - // Close file request - - case PacketType.CloseFile: - procIPCFileClose(sess, smbPkt, outPkt); - break; - - // NT create andX request - - case PacketType.NTCreateAndX: - procNTCreateAndX(sess, smbPkt, outPkt); - break; - - // Default, respond with an unsupported function error. - - default: - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - break; - } - } - - /** - * Process an IPC$ transaction request. - * - * @param vc VirtualCircuit - * @param tbuf SrvTransactBuffer - * @param sess SMBSrvSession - * @param outPkt SMBSrvPacket - */ - protected static void procTransaction(VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ Transaction pipe=" + tbuf.getName() + ", subCmd=" - + NamedPipeTransaction.getSubCommand(tbuf.getFunction())); - - // Call the required transaction handler - - if (tbuf.getName().compareTo(TransactionNames.PipeLanman) == 0) - { - - // Call the \PIPE\LANMAN transaction handler to process the request - - if (PipeLanmanHandler.processRequest(tbuf, sess, outPkt)) - return; - } - - // Process the pipe command - - switch (tbuf.getFunction()) - { - - // Set named pipe handle state - - case NamedPipeTransaction.SetNmPHandState: - procSetNamedPipeHandleState(sess, vc, tbuf, outPkt); - break; - - // Named pipe transation request, pass the request to the DCE/RPC handler - - case NamedPipeTransaction.TransactNmPipe: - DCERPCHandler.processDCERPCRequest(sess, vc, tbuf, outPkt); - break; - - // Query file information via handle - - case PacketType.Trans2QueryFile: - procTrans2QueryFile(sess, vc, tbuf, outPkt); - break; - - // Unknown command - - default: - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - break; - } - } - - /** - * Process a special IPC$ file open request. - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileOpen(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the data bytes position and length - - int dataPos = rxPkt.getByteOffset(); - int dataLen = rxPkt.getByteCount(); - byte[] buf = rxPkt.getBuffer(); - - // Extract the filename string - - String fileName = DataPacker.getString(buf, dataPos, dataLen); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ Open file = " + fileName); - - // Check if the requested IPC$ file is valid - - int pipeType = DCEPipeType.getNameAsType(fileName); - if (pipeType == -1) - { - sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = sess.findTreeConnection(rxPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Create a network file for the special pipe - - DCEPipeFile pipeFile = new DCEPipeFile(pipeType); - pipeFile.setGrantedAccess(NetworkFile.READWRITE); - - // Add the file to the list of open files for this tree connection - - int fid = -1; - - try - { - fid = conn.addFile(pipeFile, sess); - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - - // Build the open file response - - outPkt.setParameterCount(15); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); // AndX offset - - outPkt.setParameter(2, fid); - outPkt.setParameter(3, 0); // file attributes - outPkt.setParameter(4, 0); // last write time - outPkt.setParameter(5, 0); // last write date - outPkt.setParameterLong(6, 0); // file size - outPkt.setParameter(8, 0); - outPkt.setParameter(9, 0); - outPkt.setParameter(10, 0); // named pipe state - outPkt.setParameter(11, 0); - outPkt.setParameter(12, 0); // server FID (long) - outPkt.setParameter(13, 0); - outPkt.setParameter(14, 0); - - outPkt.setByteCount(0); - - // Send the response packet - - sess.sendResponseSMB(outPkt); - } - - /** - * Process an IPC pipe file read request - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileRead(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check if the received packet is a valid read file request - - if (rxPkt.checkPacketIsValid(5, 0) == false) - { - - // Invalid request - - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File Read"); - - // Pass the read request the DCE/RPC handler - - DCERPCHandler.processDCERPCRead(sess, rxPkt, outPkt); - } - - /** - * Process an IPC pipe file read andX request - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileReadAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check if the received packet is a valid read andX file request - - if (rxPkt.checkPacketIsValid(10, 0) == false) - { - - // Invalid request - - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File Read AndX"); - - // Pass the read request the DCE/RPC handler - - DCERPCHandler.processDCERPCRead(sess, rxPkt, outPkt); - } - - /** - * Process an IPC pipe file write request - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileWrite(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check if the received packet is a valid write file request - - if (rxPkt.checkPacketIsValid(5, 0) == false) - { - - // Invalid request - - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File Write"); - - // Pass the write request the DCE/RPC handler - - DCERPCHandler.processDCERPCRequest(sess, rxPkt, outPkt); - } - - /** - * Process an IPC pipe file write andX request - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileWriteAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check if the received packet is a valid write andX request - - if (rxPkt.checkPacketIsValid(12, 0) == false) - { - - // Invalid request - - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File Write AndX"); - - // Pass the write request the DCE/RPC handler - - DCERPCHandler.processDCERPCRequest(sess, rxPkt, outPkt); - } - - /** - * Process a special IPC$ file close request. - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procIPCFileClose(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file close request - - if (rxPkt.checkPacketIsValid(3, 0) == false) - { - sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection(rxPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the file id from the request - - int fid = rxPkt.getParameter(0); - DCEPipeFile netFile = (DCEPipeFile) conn.findFile(fid); - - if (netFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ File close [" + rxPkt.getTreeId() + "] fid=" + fid); - - // Remove the file from the connections list of open files - - conn.removeFile(fid, sess); - - // Build the close file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - sess.sendResponseSMB(outPkt); - } - - /** - * Process a set named pipe handle state request - * - * @param sess SMBSrvSession - * @param vc VirtualCircuit - * @param tbuf SrvTransactBuffer - * @param outPkt SMBSrvPacket - */ - protected static void procSetNamedPipeHandleState(SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the request parameters - - DataBuffer setupBuf = tbuf.getSetupBuffer(); - setupBuf.skipBytes(2); - int fid = setupBuf.getShort(); - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - int state = paramBuf.getShort(); - - // Get the connection for the request - - TreeConnection conn = vc.findConnection(tbuf.getTreeId()); - - // Get the IPC pipe file for the specified file id - - DCEPipeFile netFile = (DCEPipeFile) conn.findFile(fid); - if (netFile == null) - { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug(" SetNmPHandState pipe=" + netFile.getName() + ", fid=" + fid + ", state=0x" - + Integer.toHexString(state)); - - // Store the named pipe state - - netFile.setPipeState(state); - - // Setup the response packet - - SMBSrvTransPacket.initTransactReply(outPkt, 0, 0, 0, 0); - - // Send the response packet - - sess.sendResponseSMB(outPkt); - } - - /** - * Process an NT create andX request - * - * @param sess SMBSrvSession - * @param rxPkt SMBSrvPacket - * @param outPkt SMBSrvPacket - */ - protected static void procNTCreateAndX(SMBSrvSession sess, SMBSrvPacket rxPkt, SMBSrvPacket outPkt) - throws IOException, SMBSrvException - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = sess.findTreeConnection(rxPkt); - - if (conn == null) - { - sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Extract the NT create andX parameters - - NTParameterPacker prms = new NTParameterPacker(rxPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 5); - - int nameLen = prms.unpackWord(); - int flags = prms.unpackInt(); - int rootFID = prms.unpackInt(); - int accessMask = prms.unpackInt(); - long allocSize = prms.unpackLong(); - int attrib = prms.unpackInt(); - int shrAccess = prms.unpackInt(); - int createDisp = prms.unpackInt(); - int createOptn = prms.unpackInt(); - int impersonLev = prms.unpackInt(); - int secFlags = prms.unpackByte(); - - // Extract the filename string - - int pos = DataPacker.wordAlign(rxPkt.getByteOffset()); - String fileName = DataPacker.getUnicodeString(rxPkt.getBuffer(), pos, nameLen); - if (fileName == null) - { - sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NT Create AndX [" + rxPkt.getTreeId() + "] name=" + fileName + ", flags=0x" - + Integer.toHexString(flags) + ", attr=0x" + Integer.toHexString(attrib) + ", allocSize=" - + allocSize); - - // Check if the pipe name is a short or long name - - if (fileName.startsWith("\\PIPE") == false) - fileName = "\\PIPE" + fileName; - - // Check if the requested IPC$ file is valid - - int pipeType = DCEPipeType.getNameAsType(fileName); - if (pipeType == -1) - { - sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.NTErr); - return; - } - - // Check if there is a handler for the pipe file - - if (DCEPipeHandler.getHandlerForType(pipeType) == null) - { - sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.NTErr); - return; - } - - // Create a network file for the special pipe - - DCEPipeFile pipeFile = new DCEPipeFile(pipeType); - pipeFile.setGrantedAccess(NetworkFile.READWRITE); - - // Add the file to the list of open files for this tree connection - - int fid = -1; - - try - { - fid = conn.addFile(pipeFile, sess); - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - sess.sendErrorResponseSMB(SMBStatus.Win32InvalidHandle, SMBStatus.NTErr); - return; - } - - // Build the NT create andX response - - outPkt.setParameterCount(34); - - prms.reset(outPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 4); - - prms.packByte(0); - prms.packWord(fid); - prms.packInt(0x0001); // File existed and was opened - - prms.packLong(0); // Creation time - prms.packLong(0); // Last access time - prms.packLong(0); // Last write time - prms.packLong(0); // Change time - - prms.packInt(0x0080); // File attributes - prms.packLong(4096); // Allocation size - prms.packLong(0); // End of file - prms.packWord(2); // File type - named pipe, message mode - prms.packByte(0xFF); // Pipe instancing count - prms.packByte(0x05); // IPC state bits - - prms.packByte(0); // directory flag - - outPkt.setByteCount(0); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, outPkt.getLength()); // AndX offset - - // Send the response packet - - sess.sendResponseSMB(outPkt); - } - - /** - * Process a transact2 query file information (via handle) request. - * - * @param sess SMBSrvSession - * @param vc VirtualCircuit - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException The exception description. - * @exception org.alfresco.aifs.smb.SMBSrvException SMB protocol exception - */ - protected static final void procTrans2QueryFile(SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket outPkt) - throws java.io.IOException, SMBSrvException { - - // Get the tree connection details - - int treeId = tbuf.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) { - sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) { - - // User does not have the required access rights - - sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id and query path information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int fid = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - - // Get the file details via the file id - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) { - sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("IPC$ Query File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", name=" + netFile.getFullName()); - - // Access the shared device disk interface - - try { - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the file information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos + 4; - - // Pack the return parametes, EA error offset - - outPkt.setPosition(prmPos); - outPkt.packWord(0); - - // Create a data buffer using the SMB packet. The response should always fit into a single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Build the file information from the network file details - - FileInfo fileInfo = new FileInfo(netFile.getName(), netFile.getFileSize(), netFile.getFileAttributes()); - - fileInfo.setAccessDateTime(netFile.getAccessDate()); - fileInfo.setCreationDateTime(netFile.getCreationDate()); - fileInfo.setModifyDateTime(netFile.getModifyDate()); - fileInfo.setChangeDateTime(netFile.getModifyDate()); - - fileInfo.setFileId(netFile.getFileId()); - - // Pack the file information into the return data packet - - int dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); - - // Check if any data was packed, if not then the information level is not supported - - if (dataLen == 0) { - sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos); - outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); - - // Send the transact reply - - sess.sendResponseSMB(outPkt); - } - catch (FileNotFoundException ex) { - - // Requested file does not exist - - sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (PathNotFoundException ex) { - - // Requested path does not exist - - sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (UnsupportedInfoLevelException ex) { - - // Requested information level is not supported - - sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java deleted file mode 100644 index 723b3ab9c8..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/LanManProtocolHandler.java +++ /dev/null @@ -1,3004 +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.smb.server; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.auth.InvalidUserException; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.ShareType; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.filesys.AccessDeniedException; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.FileAccess; -import org.alfresco.filesys.server.filesys.FileAction; -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.FileOfflineException; -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.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.TooManyFilesException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; -import org.alfresco.filesys.server.filesys.VolumeInfo; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.FindFirstNext; -import org.alfresco.filesys.smb.InvalidUNCPathException; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * LanMan SMB Protocol Handler Class. - *

- * The LanMan protocol handler processes the additional SMBs that were added to the protocol in the - * LanMan1 and LanMan2 SMB dialects. - */ -class LanManProtocolHandler extends CoreProtocolHandler -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Locking type flags - - protected static final int LockShared = 0x01; - protected static final int LockOplockRelease = 0x02; - protected static final int LockChangeType = 0x04; - protected static final int LockCancel = 0x08; - protected static final int LockLargeFiles = 0x10; - - /** - * LanManProtocolHandler constructor. - */ - protected LanManProtocolHandler() - { - super(); - } - - /** - * LanManProtocolHandler constructor. - * - * @param sess org.alfresco.filesys.smbsrv.SMBSrvSession - */ - protected LanManProtocolHandler(SMBSrvSession sess) - { - super(sess); - } - - /** - * Return the protocol name - * - * @return String - */ - public String getName() - { - return "LanMan"; - } - - /** - * Process the chained SMB commands (AndX). - * - * @return New offset to the end of the reply packet - * @param outPkt Reply packet. - */ - protected final int procAndXCommands(SMBSrvPacket outPkt) - { - - // Get the chained command and command block offset - - int andxCmd = m_smbPkt.getAndXCommand(); - int andxOff = m_smbPkt.getParameter(1) + RFCNetBIOSProtocol.HEADER_LEN; - - // Set the initial chained command and offset - - outPkt.setAndXCommand(andxCmd); - outPkt.setParameter(1, andxOff - RFCNetBIOSProtocol.HEADER_LEN); - - // Pointer to the last parameter block, starts with the main command parameter block - - int paramBlk = SMBSrvPacket.WORDCNT; - - // Get the current end of the reply packet offset - - int endOfPkt = outPkt.getByteOffset() + outPkt.getByteCount(); - boolean andxErr = false; - - while (andxCmd != SMBSrvPacket.NO_ANDX_CMD && andxErr == false) - { - - // Determine the chained command type - - int prevEndOfPkt = endOfPkt; - - switch (andxCmd) - { - - // Tree connect - - case PacketType.TreeConnectAndX: - endOfPkt = procChainedTreeConnectAndX(andxOff, outPkt, endOfPkt); - break; - } - - // Advance to the next chained command block - - andxCmd = m_smbPkt.getAndXParameter(andxOff, 0) & 0x00FF; - andxOff = m_smbPkt.getAndXParameter(andxOff, 1); - - // Set the next chained command details in the current parameter block - - outPkt.setAndXCommand(prevEndOfPkt, andxCmd); - outPkt.setAndXParameter(paramBlk, 1, prevEndOfPkt - RFCNetBIOSProtocol.HEADER_LEN); - - // Advance the current parameter block - - paramBlk = prevEndOfPkt; - - // Check if the chained command has generated an error status - - if (outPkt.getErrorCode() != SMBStatus.Success) - andxErr = true; - } - - // Return the offset to the end of the reply packet - - return endOfPkt; - } - - /** - * Process a chained tree connect request. - * - * @return New end of reply offset. - * @param cmdOff int Offset to the chained command within the request packet. - * @param outPkt SMBSrvPacket Reply packet. - * @param endOff int Offset to the current end of the reply packet. - */ - protected final int procChainedTreeConnectAndX(int cmdOff, SMBSrvPacket outPkt, int endOff) - { - - // Extract the parameters - - int flags = m_smbPkt.getAndXParameter(cmdOff, 2); - int pwdLen = m_smbPkt.getAndXParameter(cmdOff, 3); - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( outPkt.getUserId()); - - if (vc == null) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return endOff; - } - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getAndXByteOffset(cmdOff); - int dataLen = m_smbPkt.getAndXByteCount(cmdOff); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the password string - - String pwd = null; - - if (pwdLen > 0) - { - pwd = new String(buf, dataPos, pwdLen); - dataPos += pwdLen; - dataLen -= pwdLen; - } - - // Extract the requested share name, as a UNC path - - String uncPath = DataPacker.getString(buf, dataPos, dataLen); - if (uncPath == null) - { - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - - // Extract the service type string - - dataPos += uncPath.length() + 1; // null terminated - dataLen -= uncPath.length() + 1; // null terminated - - String service = DataPacker.getString(buf, dataPos, dataLen); - if (service == null) - { - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - - // Convert the service type to a shared device type, client may specify '?????' in which - // case we ignore the error. - - int servType = ShareType.ServiceAsType(service); - if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) - { - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("ANDX Tree Connect AndX - " + uncPath + ", " + service); - - // Parse the requested share name - - PCShare share = null; - - try - { - share = new PCShare(uncPath); - } - catch (org.alfresco.filesys.smb.InvalidUNCPathException ex) - { - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - - // Map the IPC$ share to the admin pipe type - - if (servType == ShareType.NAMEDPIPE && share.getShareName().compareTo("IPC$") == 0) - servType = ShareType.ADMINPIPE; - - // Find the requested shared device - - SharedDevice shareDev = null; - - try - { - - // Get/create the shared device - - shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType, - getSession(), true); - } - catch (InvalidUserException ex) - { - - // Return a logon failure status - - outPkt.setError(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return endOff; - } - catch (Exception ex) - { - - // Return a general status, bad network name - - outPkt.setError(SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); - return endOff; - } - - // Check if the share is valid - - if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) - { - outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return endOff; - } - - // Authenticate the share connect, if the server is using share mode security - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - int filePerm = FileAccess.Writeable; - - if (auth != null) - { - - // Validate the share connection - - filePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); - if (filePerm < 0) - { - - // Invalid share connection request - - outPkt.setError(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return endOff; - } - } - - // Allocate a tree id for the new connection - - try - { - - // Allocate the tree id for this connection - - int treeId = vc.addConnection(shareDev); - outPkt.setTreeId(treeId); - - // Set the file permission that this user has been granted for this share - - TreeConnection tree = vc.findConnection(treeId); - tree.setPermission(filePerm); - - // Inform the driver that a connection has been opened - - if (tree.getInterface() != null) - tree.getInterface().treeOpened(m_sess, tree); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("ANDX Tree Connect AndX - Allocated Tree Id = " + treeId); - } - catch (TooManyConnectionsException ex) - { - - // Too many connections open at the moment - - outPkt.setError(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); - return endOff; - } - - // Build the tree connect response - - outPkt.setAndXParameterCount(endOff, 2); - outPkt.setAndXParameter(endOff, 0, SMBSrvPacket.NO_ANDX_CMD); - outPkt.setAndXParameter(endOff, 1, 0); - - // Pack the service type - - int pos = outPkt.getAndXByteOffset(endOff); - byte[] outBuf = outPkt.getBuffer(); - pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), outBuf, pos, true); - int bytLen = pos - outPkt.getAndXByteOffset(endOff); - outPkt.setAndXByteCount(endOff, bytLen); - - // Return the new end of packet offset - - return pos; - } - - /** - * Close a search started via the transact2 find first/next command. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procFindClose(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid find close request - - if (m_smbPkt.checkPacketIsValid(1, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the search id - - int searchId = m_smbPkt.getParameter(0); - - // Get the search context - - SearchContext ctx = vc.getSearchContext(searchId); - - if (ctx == null) - { - - // Invalid search handle - - m_sess.sendSuccessResponseSMB(); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Close trans search [" + searchId + "]"); - - // Deallocate the search slot, close the search. - - vc.deallocateSearchSlot(searchId); - - // Return a success status SMB - - m_sess.sendSuccessResponseSMB(); - } - - /** - * Process the file lock/unlock request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procLockingAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid locking andX request - - if (m_smbPkt.checkPacketIsValid(8, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Extract the file lock/unlock parameters - - int fid = m_smbPkt.getParameter(2); - int lockType = m_smbPkt.getParameter(3); - long lockTmo = m_smbPkt.getParameterLong(4); - int lockCnt = m_smbPkt.getParameter(6); - int unlockCnt = m_smbPkt.getParameter(7); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) - logger.debug("File Lock [" + netFile.getFileId() + "] : type=0x" + Integer.toHexString(lockType) + ", tmo=" - + lockTmo + ", locks=" + lockCnt + ", unlocks=" + unlockCnt); - - // Return a success status for now - - outPkt.setParameterCount(2); - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); - outPkt.setByteCount(0); - - // Send the lock request response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the logoff request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procLogoffAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - // Check that the received packet looks like a valid logoff andX request - - if (m_smbPkt.checkPacketIsValid(2, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - int uid = m_smbPkt.getUserId(); - VirtualCircuit vc = m_sess.findVirtualCircuit( uid); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // DEBUG - - if ( logger.isDebugEnabled() && m_sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Logoff vc=" + vc); - - // Close the virtual circuit - - m_sess.removeVirtualCircuit( uid); - - // Return a success status SMB - - m_sess.sendSuccessResponseSMB(); - } - - /** - * Process the file open request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procOpenAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid open andX request - - if (m_smbPkt.checkPacketIsValid(15, 1) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. If the device is - // not a disk type device then return an error. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - else if (conn.getSharedDevice().getType() != ShareType.DISK) - { - - // Return an access denied error - - // m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - // m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Extract the open file parameters - - int flags = m_smbPkt.getParameter(2); - int access = m_smbPkt.getParameter(3); - int srchAttr = m_smbPkt.getParameter(4); - int fileAttr = m_smbPkt.getParameter(5); - int crTime = m_smbPkt.getParameter(6); - int crDate = m_smbPkt.getParameter(7); - int openFunc = m_smbPkt.getParameter(8); - int allocSiz = m_smbPkt.getParameterLong(9); - - // Extract the filename string - - String fileName = m_smbPkt.unpackString(m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Create the file open parameters - - SMBDate crDateTime = null; - if (crTime > 0 && crDate > 0) - crDateTime = new SMBDate(crDate, crTime); - - FileOpenParams params = new FileOpenParams(fileName, openFunc, access, srchAttr, fileAttr, allocSiz, crDateTime - .getTime()); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Open AndX [" + m_smbPkt.getTreeId() + "] params=" + params); - - // Access the disk interface and open the requested file - - int fid; - NetworkFile netFile = null; - int respAction = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check if the requested file already exists - - int fileSts = disk.fileExists(m_sess, conn, fileName); - - if (fileSts == FileStatus.NotExist) - { - - // Check if the file should be created if it does not exist - - if (FileAction.createNotExists(openFunc)) - { - - // Check if the session has write access to the filesystem - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Create a new file - - netFile = disk.createFile(m_sess, conn, params); - - // Indicate that the file did not exist and was created - - respAction = FileAction.FileCreated; - } - else - { - - // Check if the path is a directory - - if (fileSts == FileStatus.DirectoryExists) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - } - else - { - - // Return a file not found error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - } - return; - } - } - else - { - - // Open the requested file - - netFile = disk.openFile(m_sess, conn, params); - - // Set the file action response - - if (FileAction.truncateExistingFile(openFunc)) - respAction = FileAction.FileTruncated; - else - respAction = FileAction.FileExisted; - } - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileSharingConflict, SMBStatus.ErrDos); - return; - } - catch (FileOfflineException ex) - { - - // File data is unavailable - - m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the open file response - - outPkt.setParameterCount(15); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); // AndX offset - - outPkt.setParameter(2, fid); - outPkt.setParameter(3, netFile.getFileAttributes()); // file attributes - - SMBDate modDate = null; - - if (netFile.hasModifyDate()) - modDate = new SMBDate(netFile.getModifyDate()); - - outPkt.setParameter(4, modDate != null ? modDate.asSMBTime() : 0); // last write time - outPkt.setParameter(5, modDate != null ? modDate.asSMBDate() : 0); // last write date - outPkt.setParameterLong(6, netFile.getFileSizeInt()); // file size - outPkt.setParameter(8, netFile.getGrantedAccess()); - outPkt.setParameter(9, OpenAndX.FileTypeDisk); - outPkt.setParameter(10, 0); // named pipe state - outPkt.setParameter(11, respAction); - outPkt.setParameter(12, 0); // server FID (long) - outPkt.setParameter(13, 0); - outPkt.setParameter(14, 0); - - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the file read request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procReadAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid read andX request - - if (m_smbPkt.checkPacketIsValid(10, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Extract the read file parameters - - int fid = m_smbPkt.getParameter(2); - int offset = m_smbPkt.getParameterLong(3); - int maxCount = m_smbPkt.getParameter(5); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read AndX [" + netFile.getFileId() + "] : Size=" + maxCount + " ,Pos=" + offset); - - // Read data from the file - - byte[] buf = outPkt.getBuffer(); - int dataPos = 0; - int rdlen = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the returned parameter count so that the byte offset can be calculated - - outPkt.setParameterCount(12); - dataPos = outPkt.getByteOffset(); - // dataPos = ( dataPos + 3) & 0xFFFFFFFC; // longword align the data - - // Check if the requested data length will fit into the buffer - - int dataLen = buf.length - dataPos; - if (dataLen < maxCount) - maxCount = dataLen; - - // Read from the file - - rdlen = disk.readFile(m_sess, conn, netFile, buf, dataPos, maxCount, offset); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // No access to file, or file is a directory - // - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - logger.error("File Read Error [" + netFile.getFileId() + "] : ", ex); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd); - return; - } - - // Return the data block - - outPkt.setAndXCommand(0xFF); // no chained command - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); // bytes remaining, for pipes only - outPkt.setParameter(3, 0); // data compaction mode - outPkt.setParameter(4, 0); // reserved - outPkt.setParameter(5, rdlen); // data length - outPkt.setParameter(6, dataPos - RFCNetBIOSProtocol.HEADER_LEN); - // offset to data - - // Clear the reserved parameters - - for (int i = 7; i < 12; i++) - outPkt.setParameter(i, 0); - - // Set the byte count - - outPkt.setByteCount((dataPos + rdlen) - outPkt.getByteOffset()); - - // Send the read andX response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Rename a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procRenameFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid rename file request - - if (m_smbPkt.checkPacketIsValid(1, 4) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the Unicode flag - - boolean isUni = m_smbPkt.isUnicode(); - - // Read the data block - - m_smbPkt.resetBytePointer(); - - // Extract the old file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String oldName = m_smbPkt.unpackString(isUni); - if (oldName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Extract the new file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String newName = m_smbPkt.unpackString(isUni); - if (oldName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Rename [" + m_smbPkt.getTreeId() + "] old name=" + oldName + ", new name=" + newName); - - // Access the disk interface and rename the requested file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Rename the requested file - - disk.renameFile(m_sess, conn, oldName, newName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the rename file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the SMB session setup request. - * - * @param outPkt Response SMB packet. - */ - protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException, - TooManyConnectionsException - { - - // Extract the client details from the session setup request - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the session details - - int maxBufSize = m_smbPkt.getParameter(2); - int maxMpx = m_smbPkt.getParameter(3); - int vcNum = m_smbPkt.getParameter(4); - - // Extract the password string - - byte[] pwd = null; - int pwdLen = m_smbPkt.getParameter(7); - - if (pwdLen > 0) - { - pwd = new byte[pwdLen]; - for (int i = 0; i < pwdLen; i++) - pwd[i] = buf[dataPos + i]; - dataPos += pwdLen; - dataLen -= pwdLen; - } - - // Extract the user name string - - String user = DataPacker.getString(buf, dataPos, dataLen); - if (user == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - else - { - - // Update the buffer pointers - - dataLen -= user.length() + 1; - dataPos += user.length() + 1; - } - - // Extract the clients primary domain name string - - String domain = ""; - - if (dataLen > 0) - { - - // Extract the callers domain name - - domain = DataPacker.getString(buf, dataPos, dataLen); - if (domain == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - else - { - - // Update the buffer pointers - - dataLen -= domain.length() + 1; - dataPos += domain.length() + 1; - } - } - - // Extract the clients native operating system - - String clientOS = ""; - - if (dataLen > 0) - { - - // Extract the callers operating system name - - clientOS = DataPacker.getString(buf, dataPos, dataLen); - if (clientOS == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - } - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Session setup from user=" + user + ", password=" + pwd + ", domain=" + domain + ", os=" - + clientOS + ", VC=" + vcNum + ", maxBuf=" + maxBufSize + ", maxMpx=" + maxMpx); - - // Store the client maximum buffer size and maximum multiplexed requests count - - m_sess.setClientMaximumBufferSize(maxBufSize); - m_sess.setClientMaximumMultiplex(maxMpx); - - // Create the client information and store in the session - - ClientInfo client = new ClientInfo(user, pwd); - client.setDomain(domain); - client.setOperatingSystem(clientOS); - if (m_sess.hasRemoteAddress()) - client.setClientAddress(m_sess.getRemoteAddress().getHostAddress()); - - if (m_sess.getClientInformation() == null) - { - - // Set the session client details - - m_sess.setClientInformation(client); - } - else - { - - // Get the current client details from the session - - ClientInfo curClient = m_sess.getClientInformation(); - - if (curClient.getUserName() == null || curClient.getUserName().length() == 0) - { - - // Update the client information - - m_sess.setClientInformation(client); - } - else - { - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Session already has client information set"); - } - } - - // Authenticate the user, if the server is using user mode security - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - boolean isGuest = false; - - if (auth != null) - { - - // Validate the user - - int sts = auth.authenticateUser(client, m_sess, CifsAuthenticator.LANMAN); - if (sts > 0 && (sts & CifsAuthenticator.AUTH_GUEST) != 0) - isGuest = true; - else if (sts != CifsAuthenticator.AUTH_ALLOW) - { - - // Invalid user, reject the session setup request - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - } - - // Set the guest flag for the client and logged on status - - client.setGuest(isGuest); - getSession().setLoggedOn(true); - - // Build the session setup response SMB - - outPkt.setParameterCount(3); - outPkt.setParameter(0, 0); // No chained response - outPkt.setParameter(1, 0); // Offset to chained response - outPkt.setParameter(2, isGuest ? 1 : 0); - outPkt.setByteCount(0); - - outPkt.setTreeId(0); - outPkt.setUserId(0); - - // Set the various flags - - // outPkt.setFlags( SMBSrvPacket.FLG_CASELESS); - int flags = outPkt.getFlags(); - flags &= ~SMBSrvPacket.FLG_CASELESS; - outPkt.setFlags(flags); - outPkt.setFlags2(SMBSrvPacket.FLG2_LONGFILENAMES); - - // Pack the OS, dialect and domain name strings. - - int pos = outPkt.getByteOffset(); - buf = outPkt.getBuffer(); - - pos = DataPacker.putString("Java", buf, pos, true); - pos = DataPacker.putString("JLAN Server " + m_sess.getServer().isVersion(), buf, pos, true); - pos = DataPacker.putString(m_sess.getServer().getConfiguration().getDomainName(), buf, pos, true); - - outPkt.setByteCount(pos - outPkt.getByteOffset()); - - // Check if there is a chained command, or commands - - if (m_smbPkt.hasAndXCommand() && dataPos < m_smbPkt.getReceivedLength()) - { - - // Process any chained commands, AndX - - pos = procAndXCommands(outPkt); - } - else - { - - // Indicate that there are no chained replies - - outPkt.setAndXCommand(SMBSrvPacket.NO_ANDX_CMD); - } - - // Send the negotiate response - - m_sess.sendResponseSMB(outPkt, pos); - - // Update the session state - - m_sess.setState(SMBSrvSessionState.SMBSESSION); - - // Notify listeners that a user has logged onto the session - - m_sess.getSMBServer().sessionLoggedOn(m_sess); - } - - /** - * Process a transact2 request. The transact2 can contain many different sub-requests. - * - * @param outPkt SMBSrvPacket - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procTransact2(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(15, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Create a transact packet using the received SMB packet - - SMBSrvTransPacket tranPkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); - - // Create a transact buffer to hold the transaction setup, parameter and data blocks - - SrvTransactBuffer transBuf = null; - int subCmd = tranPkt.getSubFunction(); - - if (tranPkt.getTotalParameterCount() == tranPkt.getParameterBlockCount() - && tranPkt.getTotalDataCount() == tranPkt.getDataBlockCount()) - { - - // Create a transact buffer using the packet buffer, the entire request is contained in - // a single - // packet - - transBuf = new SrvTransactBuffer(tranPkt); - } - else - { - - // Create a transact buffer to hold the multiple transact request parameter/data blocks - - transBuf = new SrvTransactBuffer(tranPkt.getSetupCount(), tranPkt.getTotalParameterCount(), tranPkt - .getTotalDataCount()); - transBuf.setType(tranPkt.getCommand()); - transBuf.setFunction(subCmd); - - // Append the setup, parameter and data blocks to the transaction data - - byte[] buf = tranPkt.getBuffer(); - - transBuf.appendSetup(buf, tranPkt.getSetupOffset(), tranPkt.getSetupCount() * 2); - transBuf.appendParameter(buf, tranPkt.getParameterBlockOffset(), tranPkt.getParameterBlockCount()); - transBuf.appendData(buf, tranPkt.getDataBlockOffset(), tranPkt.getDataBlockCount()); - } - - // Set the return data limits for the transaction - - transBuf.setReturnLimits(tranPkt.getMaximumReturnSetupCount(), tranPkt.getMaximumReturnParameterCount(), - tranPkt.getMaximumReturnDataCount()); - - // Check for a multi-packet transaction, for a multi-packet transaction we just acknowledge - // the receive with - // an empty response SMB - - if (transBuf.isMultiPacket()) - { - - // Save the partial transaction data - - vc.setTransaction(transBuf); - - // Send an intermediate acknowedgement response - - m_sess.sendSuccessResponseSMB(); - return; - } - - // Check if the transaction is on the IPC$ named pipe, the request requires special - // processing - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); - return; - } - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); - - // Process the transaction buffer - - processTransactionBuffer(transBuf, outPkt); - } - - /** - * Process a transact2 secondary request. - * - * @param outPkt SMBSrvPacket - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procTransact2Secondary(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(8, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Check if there is an active transaction, and it is an NT transaction - - if (vc.hasTransaction() == false - || (vc.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) - || (vc.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) - { - - // No transaction to continue, or packet does not match the existing transaction, return - // an error - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Create an NT transaction using the received packet - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); - byte[] buf = tpkt.getBuffer(); - SrvTransactBuffer transBuf = vc.getTransaction(); - - // Append the parameter data to the transaction buffer, if any - - int plen = tpkt.getSecondaryParameterBlockCount(); - if (plen > 0) - { - - // Append the data to the parameter buffer - - DataBuffer paramBuf = transBuf.getParameterBuffer(); - paramBuf.appendData(buf, tpkt.getSecondaryParameterBlockOffset(), plen); - } - - // Append the data block to the transaction buffer, if any - - int dlen = tpkt.getSecondaryDataBlockCount(); - if (dlen > 0) - { - - // Append the data to the data buffer - - DataBuffer dataBuf = transBuf.getDataBuffer(); - dataBuf.appendData(buf, tpkt.getSecondaryDataBlockOffset(), dlen); - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction Secondary [" + treeId + "] paramLen=" + plen + ", dataLen=" + dlen); - - // Check if the transaction has been received or there are more sections to be received - - int totParam = tpkt.getTotalParameterCount(); - int totData = tpkt.getTotalDataCount(); - - int paramDisp = tpkt.getParameterBlockDisplacement(); - int dataDisp = tpkt.getDataBlockDisplacement(); - - if ((paramDisp + plen) == totParam && (dataDisp + dlen) == totData) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction complete, processing ..."); - - // Clear the in progress transaction - - vc.setTransaction(null); - - // Check if the transaction is on the IPC$ named pipe, the request requires special - // processing - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); - return; - } - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction second [" + treeId + "] tbuf=" + transBuf); - - // Process the transaction - - processTransactionBuffer(transBuf, outPkt); - } - else - { - - // There are more transaction parameter/data sections to be received, return an - // intermediate response - - m_sess.sendSuccessResponseSMB(); - } - } - - /** - * Process a transaction buffer - * - * @param tbuf TransactBuffer - * @param outPkt SMBSrvPacket - * @exception IOException If a network error occurs - * @exception SMBSrvException If an SMB error occurs - */ - private final void processTransactionBuffer(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws IOException, - SMBSrvException - { - - // Get the transaction sub-command code and validate - - switch (tbuf.getFunction()) - { - - // Start a file search - - case PacketType.Trans2FindFirst: - procTrans2FindFirst(tbuf, outPkt); - break; - - // Continue a file search - - case PacketType.Trans2FindNext: - procTrans2FindNext(tbuf, outPkt); - break; - - // Query file system information - - case PacketType.Trans2QueryFileSys: - procTrans2QueryFileSys(tbuf, outPkt); - break; - - // Query path - - case PacketType.Trans2QueryPath: - procTrans2QueryPath(tbuf, outPkt); - break; - - // Unknown transact2 command - - default: - - // Return an unrecognized command error - - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - break; - } - } - - /** - * Process a transact2 file search request. - * - * @param tbuf Transaction request details - * @param outPkt Packet to use for the reply. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2FindFirst(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the search parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int srchAttr = paramBuf.getShort(); - int maxFiles = paramBuf.getShort(); - int srchFlag = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - paramBuf.skipBytes(4); - - String srchPath = paramBuf.getString(tbuf.isUnicode()); - - // Check if the search path is valid - - if (srchPath == null || srchPath.length() == 0) - { - - // Invalid search request - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the shared device disk interface - - SearchContext ctx = null; - DiskInterface disk = null; - int searchId = -1; - - try - { - - // Access the disk interface - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Allocate a search slot for the new search - - searchId = vc.allocateSearchSlot(); - if (searchId == -1) - { - - // Failed to allocate a slot for the new search - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Start trans search [" + searchId + "] - " + srchPath + ", attr=0x" - + Integer.toHexString(srchAttr) + ", maxFiles=" + maxFiles + ", infoLevel=" + infoLevl - + ", flags=0x" + Integer.toHexString(srchFlag)); - - // Start a new search - - ctx = disk.startSearch(m_sess, conn, srchPath, srchAttr); - if (ctx != null) - { - - // Store details of the search in the context - - ctx.setTreeId(treeId); - ctx.setMaximumFiles(maxFiles); - } - else - { - - // Failed to start the search, return a no more files error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Save the search context - - vc.setSearchContext(searchId, ctx); - - // Create the reply transact buffer - - SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); - DataBuffer dataBuf = replyBuf.getDataBuffer(); - - // Determine the maximum return data length - - int maxLen = replyBuf.getReturnDataLimit(); - - // Check if resume keys are required - - boolean resumeReq = (srchFlag & FindFirstNext.ReturnResumeKey) != 0 ? true : false; - - // Loop until we have filled the return buffer or there are no more files to return - - int fileCnt = 0; - int packLen = 0; - int lastNameOff = 0; - - boolean pktDone = false; - boolean searchDone = false; - - FileInfo info = new FileInfo(); - - while (pktDone == false && fileCnt < maxFiles) - { - - // Get file information from the search - - if (ctx.nextFileInfo(info) == false) - { - - // No more files - - pktDone = true; - searchDone = true; - } - - // Check if the file information will fit into the return buffer - - else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) - { - - // Pack a dummy resume key, if required - - if (resumeReq) - { - dataBuf.putZeros(4); - maxLen -= 4; - } - - // Save the offset to the last file information structure - - lastNameOff = dataBuf.getPosition(); - - // Pack the file information - - packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet - - fileCnt++; - - // Recalculate the remaining buffer space - - maxLen -= packLen; - } - else - { - - // Set the search restart point - - ctx.restartAt(info); - - // No more buffer space - - pktDone = true; - } - } - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(searchId); - paramBuf.putShort(fileCnt); - paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); - paramBuf.putShort(0); - paramBuf.putShort(lastNameOff); - - // Send the transaction response - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); - tpkt.doTransactionResponse(m_sess, replyBuf); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, moreFiles=" - + ctx.hasMoreFiles()); - - // Check if the search is complete - - if (searchDone == true) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Search complete)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - } - catch (FileNotFoundException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Search path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - } - catch (UnsupportedInfoLevelException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - } - - /** - * Process a transact2 file search continue request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2FindNext(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the search parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int searchId = paramBuf.getShort(); - int maxFiles = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - int reskey = paramBuf.getInt(); - int srchFlag = paramBuf.getShort(); - - String resumeName = paramBuf.getString(tbuf.isUnicode()); - - // Access the shared device disk interface - - SearchContext ctx = null; - DiskInterface disk = null; - - try - { - - // Access the disk interface - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Retrieve the search context - - ctx = vc.getSearchContext(searchId); - if (ctx == null) - { - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search context null - [" + searchId + "]"); - - // Invalid search handle - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Continue search [" + searchId + "] - " + resumeName + ", maxFiles=" + maxFiles - + ", infoLevel=" + infoLevl + ", flags=0x" + Integer.toHexString(srchFlag)); - - // Create the reply transaction buffer - - SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); - DataBuffer dataBuf = replyBuf.getDataBuffer(); - - // Determine the maximum return data length - - int maxLen = replyBuf.getReturnDataLimit(); - - // Check if resume keys are required - - boolean resumeReq = (srchFlag & FindFirstNext.ReturnResumeKey) != 0 ? true : false; - - // Loop until we have filled the return buffer or there are no more files to return - - int fileCnt = 0; - int packLen = 0; - int lastNameOff = 0; - - boolean pktDone = false; - boolean searchDone = false; - - FileInfo info = new FileInfo(); - - while (pktDone == false && fileCnt < maxFiles) - { - - // Get file information from the search - - if (ctx.nextFileInfo(info) == false) - { - - // No more files - - pktDone = true; - searchDone = true; - } - - // Check if the file information will fit into the return buffer - - else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) - { - - // Pack a dummy resume key, if required - - if (resumeReq) - dataBuf.putZeros(4); - - // Save the offset to the last file information structure - - lastNameOff = dataBuf.getPosition(); - - // Pack the file information - - packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet - - fileCnt++; - - // Recalculate the remaining buffer space - - maxLen -= packLen; - } - else - { - - // Set the search restart point - - ctx.restartAt(info); - - // No more buffer space - - pktDone = true; - } - } - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(fileCnt); - paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); - paramBuf.putShort(0); - paramBuf.putShort(lastNameOff); - - // Send the transaction response - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); - tpkt.doTransactionResponse(m_sess, replyBuf); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, moreFiles=" - + ctx.hasMoreFiles()); - - // Check if the search is complete - - if (searchDone == true) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Search complete)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - } - catch (FileNotFoundException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Search path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - } - catch (UnsupportedInfoLevelException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - } - - /** - * Process a transact2 file system query request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2QueryFileSys(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) - throws java.io.IOException, SMBSrvException - { - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the query file system required information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevl = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Query File System Info - level = 0x" + Integer.toHexString(infoLevl)); - - // Access the shared device disk interface - - try - { - - // Access the disk interface and context - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the disk information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos; // no parameters returned - - // Create a data buffer using the SMB packet. The response should always fit into a - // single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Determine the information level requested - - SrvDiskInfo diskInfo = null; - VolumeInfo volInfo = null; - - switch (infoLevl) - { - - // Standard disk information - - case DiskInfoPacker.InfoStandard: - - // Get the disk information - - diskInfo = getDiskInformation(disk, diskCtx); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packStandardInfo(diskInfo, replyBuf); - break; - - // Volume label information - - case DiskInfoPacker.InfoVolume: - - // Get the volume label information - - volInfo = getVolumeInformation(disk, diskCtx); - - // Pack the volume label information - - DiskInfoPacker.packVolumeInfo(volInfo, replyBuf, tbuf.isUnicode()); - break; - - // Full volume information - - case DiskInfoPacker.InfoFsVolume: - - // Get the volume information - - volInfo = getVolumeInformation(disk, diskCtx); - - // Pack the volume information - - DiskInfoPacker.packFsVolumeInformation(volInfo, replyBuf, tbuf.isUnicode()); - break; - - // Filesystem size information - - case DiskInfoPacker.InfoFsSize: - - // Get the disk information - - diskInfo = getDiskInformation(disk, diskCtx); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packFsSizeInformation(diskInfo, replyBuf); - break; - - // Filesystem device information - - case DiskInfoPacker.InfoFsDevice: - DiskInfoPacker.packFsDevice(0, 0, replyBuf); - break; - - // Filesystem attribute information - - case DiskInfoPacker.InfoFsAttribute: - DiskInfoPacker.packFsAttribute(0, 255, "JLAN", tbuf.isUnicode(), replyBuf); - break; - } - - // Check if any data was packed, if not then the information level is not supported - - if (replyBuf.getPosition() == dataPos) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - int dataLen = replyBuf.getLength(); - SMBSrvTransPacket.initTransactReply(outPkt, 0, prmPos, dataLen, dataPos); - outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - } - - /** - * Process a transact2 query path information request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2QueryPath(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the query path information level and file/directory name - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevl = paramBuf.getShort(); - paramBuf.skipBytes(4); - - String path = paramBuf.getString(tbuf.isUnicode()); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Query Path - level = 0x" + Integer.toHexString(infoLevl) + ", path = " + path); - - // Access the shared device disk interface - - try - { - - // Access the disk interface - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the file information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos; // no parameters returned - - // Create a data buffer using the SMB packet. The response should always fit into a - // single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Get the file information - - FileInfo fileInfo = disk.getFileInformation(m_sess, conn, path); - - if (fileInfo == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.NTErr); - return; - } - - // Pack the file information into the return data packet - - int dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); - - // Check if any data was packed, if not then the information level is not supported - - if (dataLen == 0) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - - SMBSrvTransPacket.initTransactReply(outPkt, 0, prmPos, dataLen, dataPos); - outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - } - catch (FileNotFoundException ex) - { - - // Requested file does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.NTErr); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - catch (UnsupportedInfoLevelException ex) - { - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.NTErr); - return; - } - } - - /** - * Process the SMB tree connect request. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - * @exception TooManyConnectionsException Too many concurrent connections on this session. - */ - - protected void procTreeConnectAndX(SMBSrvPacket outPkt) throws SMBSrvException, TooManyConnectionsException, - java.io.IOException - { - - // Check that the received packet looks like a valid tree connect request - - if (m_smbPkt.checkPacketIsValid(4, 3) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Extract the parameters - - int flags = m_smbPkt.getParameter(2); - int pwdLen = m_smbPkt.getParameter(3); - - // Get the data bytes position and length - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - byte[] buf = m_smbPkt.getBuffer(); - - // Extract the password string - - String pwd = null; - - if (pwdLen > 0) - { - pwd = new String(buf, dataPos, pwdLen); - dataPos += pwdLen; - dataLen -= pwdLen; - } - - // Extract the requested share name, as a UNC path - - String uncPath = DataPacker.getString(buf, dataPos, dataLen); - if (uncPath == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Extract the service type string - - dataPos += uncPath.length() + 1; // null terminated - dataLen -= uncPath.length() + 1; // null terminated - - String service = DataPacker.getString(buf, dataPos, dataLen); - if (service == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Convert the service type to a shared device type, client may specify '?????' in which - // case we ignore the error. - - int servType = ShareType.ServiceAsType(service); - if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree Connect AndX - " + uncPath + ", " + service); - - // Parse the requested share name - - PCShare share = null; - - try - { - share = new PCShare(uncPath); - } - catch (InvalidUNCPathException ex) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Map the IPC$ share to the admin pipe type - - if (servType == ShareType.NAMEDPIPE && share.getShareName().compareTo("IPC$") == 0) - servType = ShareType.ADMINPIPE; - - // Find the requested shared device - - SharedDevice shareDev = null; - - try - { - - // Get/create the shared device - - shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType, - getSession(), true); - } - catch (InvalidUserException ex) - { - - // Return a logon failure status - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (Exception ex) - { - - // Return a general status, bad network name - - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); - return; - } - - // Check if the share is valid - - if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Authenticate the share connection depending upon the security mode the server is running - // under - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - int filePerm = FileAccess.Writeable; - - if (auth != null) - { - - // Validate the share connection - - filePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); - if (filePerm < 0) - { - - // Invalid share connection request - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - } - - // Allocate a tree id for the new connection - - int treeId = vc.addConnection(shareDev); - outPkt.setTreeId(treeId); - - // Set the file permission that this user has been granted for this share - - TreeConnection tree = vc.findConnection(treeId); - tree.setPermission(filePerm); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree Connect AndX - Allocated Tree Id = " + treeId + ", Permission = " - + FileAccess.asString(filePerm)); - - // Build the tree connect response - - outPkt.setParameterCount(3); - outPkt.setAndXCommand(0xFF); // no chained reply - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); - - // Pack the service type - - int pos = outPkt.getByteOffset(); - pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), buf, pos, true); - outPkt.setByteCount(pos - outPkt.getByteOffset()); - - // Send the response - - m_sess.sendResponseSMB(outPkt); - - // Inform the driver that a connection has been opened - - if (tree.getInterface() != null) - tree.getInterface().treeOpened(m_sess, tree); - } - - /** - * Process the file write request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procWriteAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid write andX request - - if (m_smbPkt.checkPacketIsValid(12, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Extract the write file parameters - - int fid = m_smbPkt.getParameter(2); - int offset = m_smbPkt.getParameterLong(3); - int dataLen = m_smbPkt.getParameter(10); - int dataPos = m_smbPkt.getParameter(11) + RFCNetBIOSProtocol.HEADER_LEN; - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write AndX [" + netFile.getFileId() + "] : Size=" + dataLen + " ,Pos=" + offset); - - // Write data to the file - - byte[] buf = m_smbPkt.getBuffer(); - int wrtlen = 0; - - // Access the disk interface and write to the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Write to the file - - wrtlen = disk.writeFile(m_sess, conn, netFile, buf, dataPos, dataLen, offset); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - logger.error("File Write Error [" + netFile.getFileId() + "] : ", ex); - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - - // Return the count of bytes actually written - - outPkt.setParameterCount(6); - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); - outPkt.setParameter(2, wrtlen); - outPkt.setParameter(3, 0); // remaining byte count for pipes only - outPkt.setParameter(4, 0); // reserved - outPkt.setParameter(5, 0); // " - outPkt.setByteCount(0); - - // Send the write response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * runProtocol method comment. - */ - public boolean runProtocol() throws java.io.IOException, SMBSrvException, TooManyConnectionsException - { - - // Check if the SMB packet is initialized - - if (m_smbPkt == null) - m_smbPkt = m_sess.getReceivePacket(); - - // Check if the received packet has a valid SMB signature - - if (m_smbPkt.checkPacketSignature() == false) - throw new IOException("Invalid SMB signature"); - - // Determine if the request has a chained command, if so then we will copy the incoming - // request so that - // a chained reply can be built. - - SMBSrvPacket outPkt = m_smbPkt; - boolean chainedCmd = hasChainedCommand(m_smbPkt); - - if (chainedCmd) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STATE)) - logger.debug("AndX Command = 0x" + Integer.toHexString(m_smbPkt.getAndXCommand())); - - // Copy the request packet into a new packet for the reply - - outPkt = new SMBSrvPacket(m_smbPkt); - } - - // Reset the byte unpack offset - - m_smbPkt.resetBytePointer(); - - // Determine the SMB command type - - boolean handledOK = true; - - switch (m_smbPkt.getCommand()) - { - - // Session setup - - case PacketType.SessionSetupAndX: - procSessionSetup(outPkt); - break; - - // Tree connect - - case PacketType.TreeConnectAndX: - procTreeConnectAndX(outPkt); - break; - - // Transaction2 - - case PacketType.Transaction2: - case PacketType.Transaction: - procTransact2(outPkt); - break; - - // Transaction/transaction2 secondary - - case PacketType.TransactionSecond: - case PacketType.Transaction2Second: - procTransact2Secondary(outPkt); - break; - - // Close a search started via the FindFirst transaction2 command - - case PacketType.FindClose2: - procFindClose(outPkt); - break; - - // Open a file - - case PacketType.OpenAndX: - procOpenAndX(outPkt); - break; - - // Read a file - - case PacketType.ReadAndX: - procReadAndX(outPkt); - break; - - // Write to a file - - case PacketType.WriteAndX: - procWriteAndX(outPkt); - break; - - // Tree disconnect - - case PacketType.TreeDisconnect: - procTreeDisconnect(outPkt); - break; - - // Lock/unlock regions of a file - - case PacketType.LockingAndX: - procLockingAndX(outPkt); - break; - - // Logoff a user - - case PacketType.LogoffAndX: - procLogoffAndX(outPkt); - break; - - // Tree connection (without AndX batching) - - case PacketType.TreeConnect: - super.runProtocol(); - break; - - // Rename file - - case PacketType.RenameFile: - procRenameFile(outPkt); - break; - - // Echo request - - case PacketType.Echo: - super.procEcho(outPkt); - break; - - // Default - - default: - - // Get the tree connection details, if it is a disk or printer type connection then pass - // the request to the - // core protocol handler - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = null; - if (treeId != -1) - conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn != null) - { - - // Check if this is a disk or print connection, if so then send the request to the - // core protocol handler - - if (conn.getSharedDevice().getType() == ShareType.DISK - || conn.getSharedDevice().getType() == ShareType.PRINTER) - { - - // Chain to the core protocol handler - - handledOK = super.runProtocol(); - } - else if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Send the request to IPC$ remote admin handler - - IPCHandler.processIPCRequest(m_sess, outPkt); - handledOK = true; - } - } - break; - } - - // Return the handled status - - return handledOK; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/NTParameterPacker.java b/source/java/org/alfresco/filesys/smb/server/NTParameterPacker.java deleted file mode 100644 index c9cc2cb223..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NTParameterPacker.java +++ /dev/null @@ -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.smb.server; - -import org.alfresco.filesys.util.DataPacker; - -/** - * NT Dialect Parameter Packer Class - *

- * The NT SMB dialect uses parameters that are not always word/longword aligned. - */ -public class NTParameterPacker -{ - - // Buffer and current offset - - private byte[] m_buf; - private int m_pos; - - /** - * Class constructor - * - * @param buf byte[] - */ - public NTParameterPacker(byte[] buf) - { - m_buf = buf; - m_pos = SMBSrvPacket.PARAMWORDS; - } - - /** - * Class constructor - * - * @param buf byte[] - * @param pos int - */ - public NTParameterPacker(byte[] buf, int pos) - { - m_buf = buf; - m_pos = pos; - } - - /** - * Pack a byte (8 bit) value - * - * @param val byte - */ - public final void packByte(byte val) - { - m_buf[m_pos++] = val; - } - - /** - * Pack a byte (8 bit) value - * - * @param val int - */ - public final void packByte(int val) - { - m_buf[m_pos++] = (byte) val; - } - - /** - * Pack a word (16 bit) value - * - * @param val int - */ - public final void packWord(int val) - { - DataPacker.putIntelShort(val, m_buf, m_pos); - m_pos += 2; - } - - /** - * Pack an integer (32 bit) value - * - * @param val int - */ - public final void packInt(int val) - { - DataPacker.putIntelInt(val, m_buf, m_pos); - m_pos += 4; - } - - /** - * Pack a long (64 bit) value - * - * @param val long - */ - public final void packLong(long val) - { - DataPacker.putIntelLong(val, m_buf, m_pos); - m_pos += 8; - } - - /** - * Return the current buffer position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Return the buffer - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_buf; - } - - /** - * Unpack a byte value - * - * @return int - */ - public final int unpackByte() - { - return (int) m_buf[m_pos++]; - } - - /** - * Unpack a word (16 bit) value - * - * @return int - */ - public final int unpackWord() - { - int val = DataPacker.getIntelShort(m_buf, m_pos); - m_pos += 2; - return val; - } - - /** - * Unpack an integer (32 bit) value - * - * @return int - */ - public final int unpackInt() - { - int val = DataPacker.getIntelInt(m_buf, m_pos); - m_pos += 4; - return val; - } - - /** - * Unpack a long (64 bit) value - * - * @return int - */ - public final long unpackLong() - { - long val = DataPacker.getIntelLong(m_buf, m_pos); - m_pos += 8; - return val; - } - - /** - * Reset the parameter packer/reader to use the new buffer/offset - * - * @param buf byte[] - * @param off int - */ - public final void reset(byte[] buf, int pos) - { - m_buf = buf; - m_pos = pos; - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java deleted file mode 100644 index 83ab646f82..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java +++ /dev/null @@ -1,7129 +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.smb.server; - -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.locking.LockConflictException; -import org.alfresco.filesys.locking.NotLockedException; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.auth.InvalidUserException; -import org.alfresco.filesys.server.auth.acl.AccessControl; -import org.alfresco.filesys.server.auth.acl.AccessControlManager; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.ShareType; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.filesys.AccessDeniedException; -import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskFullException; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.FileAccess; -import org.alfresco.filesys.server.filesys.FileAction; -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.FileOfflineException; -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.FileSystem; -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.NotifyChange; -import org.alfresco.filesys.server.filesys.PathNotFoundException; -import org.alfresco.filesys.server.filesys.SearchContext; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.TooManyFilesException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; -import org.alfresco.filesys.server.filesys.VolumeInfo; -import org.alfresco.filesys.server.locking.FileLockingInterface; -import org.alfresco.filesys.server.locking.LockManager; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.FileInfoLevel; -import org.alfresco.filesys.smb.FindFirstNext; -import org.alfresco.filesys.smb.InvalidUNCPathException; -import org.alfresco.filesys.smb.LockingAndX; -import org.alfresco.filesys.smb.NTIOCtl; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.PCShare; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.WinNT; -import org.alfresco.filesys.smb.server.notify.NotifyChangeEventList; -import org.alfresco.filesys.smb.server.notify.NotifyChangeHandler; -import org.alfresco.filesys.smb.server.notify.NotifyRequest; -import org.alfresco.filesys.smb.server.ntfs.NTFSStreamsInterface; -import org.alfresco.filesys.smb.server.ntfs.StreamInfoList; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.WildCard; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NT SMB Protocol Handler Class - *

- * The NT protocol handler processes the additional SMBs that were added to the protocol in the NT - * SMB dialect. - */ -public class NTProtocolHandler extends CoreProtocolHandler -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Constants - // - // Flag to enable returning of '.' and '..' directory information in FindFirst request - - public static final boolean ReturnDotFiles = true; - - // Flag to enable faking of oplock requests when opening files - - public static final boolean FakeOpLocks = false; - - // Number of write requests per file to report file size change notifications - - public static final int FileSizeChangeRate = 10; - - // Security descriptor to allow Everyone access, returned by the QuerySecurityDescrptor NT - // transaction when NTFS streams are enabled for a virtual filesystem. - - private static byte[] _sdEveryOne = { 0x01, 0x00, 0x04, (byte) 0x80, 0x14, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1c, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, - (byte) 0xff, 0x01, 0x1f, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - - /** - * Class constructor. - */ - protected NTProtocolHandler() - { - super(); - } - - /** - * Class constructor - * - * @param sess SMBSrvSession - */ - protected NTProtocolHandler(SMBSrvSession sess) - { - super(sess); - } - - /** - * Return the protocol name - * - * @return String - */ - public String getName() - { - return "NT"; - } - - /** - * Run the NT SMB protocol handler to process the received SMB packet - * - * @exception IOException - * @exception SMBSrvException - * @exception TooManyConnectionsException - */ - public boolean runProtocol() throws java.io.IOException, SMBSrvException, TooManyConnectionsException - { - - // Check if the SMB packet is initialized - - if (m_smbPkt == null) - m_smbPkt = m_sess.getReceivePacket(); - - // Check if the received packet has a valid SMB signature - - if (m_smbPkt.checkPacketSignature() == false) - throw new IOException("Invalid SMB signature"); - - // Determine if the request has a chained command, if so then we will copy the incoming - // request so that - // a chained reply can be built. - - SMBSrvPacket outPkt = m_smbPkt; - boolean chainedCmd = hasChainedCommand(m_smbPkt); - - if (chainedCmd) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STATE)) - logger.debug("AndX Command = 0x" + Integer.toHexString(m_smbPkt.getAndXCommand())); - - // Copy the request packet into a new packet for the reply - - outPkt = new SMBSrvPacket(m_smbPkt, m_smbPkt.getPacketLength()); - } - - // Reset the byte unpack offset - - m_smbPkt.resetBytePointer(); - - // Set the process id from the received packet, this can change for the same session and - // needs to be set - // for lock ownership checking - - m_sess.setProcessId(m_smbPkt.getProcessId()); - - // Determine the SMB command type - - boolean handledOK = true; - - switch (m_smbPkt.getCommand()) - { - - // NT Session setup - - case PacketType.SessionSetupAndX: - procSessionSetup(outPkt); - break; - - // Tree connect - - case PacketType.TreeConnectAndX: - procTreeConnectAndX(outPkt); - break; - - // Transaction/transaction2 - - case PacketType.Transaction: - case PacketType.Transaction2: - procTransact2(outPkt); - break; - - // Transaction/transaction2 secondary - - case PacketType.TransactionSecond: - case PacketType.Transaction2Second: - procTransact2Secondary(outPkt); - break; - - // Close a search started via the FindFirst transaction2 command - - case PacketType.FindClose2: - procFindClose(outPkt); - break; - - // Open a file - - case PacketType.OpenAndX: - procOpenAndX(outPkt); - break; - - // Close a file - - case PacketType.CloseFile: - procCloseFile(outPkt); - break; - - // Read a file - - case PacketType.ReadAndX: - procReadAndX(outPkt); - break; - - // Write to a file - - case PacketType.WriteAndX: - procWriteAndX(outPkt); - break; - - // Rename file - - case PacketType.RenameFile: - procRenameFile(outPkt); - break; - - // Delete file - - case PacketType.DeleteFile: - procDeleteFile(outPkt); - break; - - // Delete directory - - case PacketType.DeleteDirectory: - procDeleteDirectory(outPkt); - break; - - // Tree disconnect - - case PacketType.TreeDisconnect: - procTreeDisconnect(outPkt); - break; - - // Lock/unlock regions of a file - - case PacketType.LockingAndX: - procLockingAndX(outPkt); - break; - - // Logoff a user - - case PacketType.LogoffAndX: - procLogoffAndX(outPkt); - break; - - // NT Create/open file - - case PacketType.NTCreateAndX: - procNTCreateAndX(outPkt); - break; - - // Tree connection (without AndX batching) - - case PacketType.TreeConnect: - super.runProtocol(); - break; - - // NT cancel - - case PacketType.NTCancel: - procNTCancel(outPkt); - break; - - // NT transaction - - case PacketType.NTTransact: - procNTTransaction(outPkt); - break; - - // NT transaction secondary - - case PacketType.NTTransactSecond: - procNTTransactionSecondary(outPkt); - break; - - // Echo request - - case PacketType.Echo: - super.procEcho(outPkt); - break; - - // Default - - default: - - // Get the tree connection details, if it is a disk or printer type connection then pass - // the request to the - // core protocol handler - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = null; - if (treeId != -1) - conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn != null) - { - - // Check if this is a disk or print connection, if so then send the request to the - // core protocol handler - - if (conn.getSharedDevice().getType() == ShareType.DISK - || conn.getSharedDevice().getType() == ShareType.PRINTER) - { - - // Chain to the core protocol handler - - handledOK = super.runProtocol(); - } - else if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Send the request to IPC$ remote admin handler - - IPCHandler.processIPCRequest(m_sess, outPkt); - handledOK = true; - } - } - break; - } - - // Return the handled status - - return handledOK; - } - - /** - * Process the NT SMB session setup request. - * - * @param outPkt Response SMB packet. - */ - protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException, - TooManyConnectionsException - { - - // Call the authenticator to process the session setup - - CifsAuthenticator cifsAuthenticator = m_sess.getServer().getAuthenticator(); - - try - { - // Process the session setup request, build the response - - cifsAuthenticator.processSessionSetup( m_sess, m_smbPkt, outPkt); - } - catch (SMBSrvException ex) - { - // Return an error response to the client - - m_sess.sendErrorResponseSMB( ex.getNTErrorCode(), ex.getErrorCode(), ex.getErrorClass()); - return; - } - - // Check if there is a chained command, or commands - - int pos = outPkt.getLength(); - - if (m_smbPkt.hasAndXCommand() && m_smbPkt.getPosition() < m_smbPkt.getReceivedLength()) - { - - // Process any chained commands, AndX - - pos = procAndXCommands(outPkt); - pos -= RFCNetBIOSProtocol.HEADER_LEN; - } - else - { - // Indicate that there are no chained replies - - outPkt.setAndXCommand(SMBSrvPacket.NO_ANDX_CMD); - } - - // Send the session setup response - - m_sess.sendResponseSMB(outPkt, pos); - - // Update the session state if the response indicates a success status. A multi stage session setup - // response returns a warning status. - - if ( outPkt.getLongErrorCode() == SMBStatus.NTSuccess) - { - // Update the session state - - m_sess.setState(SMBSrvSessionState.SMBSESSION); - - // Notify listeners that a user has logged onto the session - - m_sess.getSMBServer().sessionLoggedOn(m_sess); - } - } - - /** - * Process the chained SMB commands (AndX). - * - * @param outPkt Reply packet. - * @return New offset to the end of the reply packet - */ - protected final int procAndXCommands(SMBSrvPacket outPkt) - { - - // Use the byte offset plus length to calculate the current output packet end position - - return procAndXCommands(outPkt, outPkt.getByteOffset() + outPkt.getByteCount(), null); - } - - /** - * Process the chained SMB commands (AndX). - * - * @param outPkt Reply packet. - * @param endPos Current end of packet position - * @param file Current file , or null if no file context in chain - * @return New offset to the end of the reply packet - */ - protected final int procAndXCommands(SMBSrvPacket outPkt, int endPos, NetworkFile file) - { - - // Get the chained command and command block offset - - int andxCmd = m_smbPkt.getAndXCommand(); - int andxOff = m_smbPkt.getParameter(1) + RFCNetBIOSProtocol.HEADER_LEN; - - // Set the initial chained command and offset - - outPkt.setAndXCommand(andxCmd); - outPkt.setParameter(1, andxOff - RFCNetBIOSProtocol.HEADER_LEN); - - // Pointer to the last parameter block, starts with the main command parameter block - - int paramBlk = SMBSrvPacket.WORDCNT; - - // Get the current end of the reply packet offset - - int endOfPkt = endPos; - boolean andxErr = false; - - while (andxCmd != SMBSrvPacket.NO_ANDX_CMD && andxErr == false) - { - - // Determine the chained command type - - int prevEndOfPkt = endOfPkt; - boolean endOfChain = false; - - switch (andxCmd) - { - - // Tree connect - - case PacketType.TreeConnectAndX: - endOfPkt = procChainedTreeConnectAndX(andxOff, outPkt, endOfPkt); - break; - - // Close file - - case PacketType.CloseFile: - endOfPkt = procChainedClose(andxOff, outPkt, endOfPkt); - endOfChain = true; - break; - - // Read file - - case PacketType.ReadAndX: - endOfPkt = procChainedReadAndX(andxOff, outPkt, endOfPkt, file); - break; - - // Chained command was not handled - - default: - break; - } - - // Set the next chained command details in the current parameter block - - outPkt.setAndXCommand(paramBlk, andxCmd); - outPkt.setAndXParameter(paramBlk, 1, prevEndOfPkt - RFCNetBIOSProtocol.HEADER_LEN); - - // Check if the end of chain has been reached, if not then look for the next - // chained command in the request. End of chain might be set if the current command - // is not an AndX SMB command. - - if (endOfChain == false) - { - - // Advance to the next chained command block - - andxCmd = m_smbPkt.getAndXParameter(andxOff, 0) & 0x00FF; - andxOff = m_smbPkt.getAndXParameter(andxOff, 1); - - // Advance the current parameter block - - paramBlk = prevEndOfPkt; - } - else - { - - // Indicate that the end of the command chain has been reached - - andxCmd = SMBSrvPacket.NO_ANDX_CMD; - } - - // Check if the chained command has generated an error status - - if (outPkt.getErrorCode() != SMBStatus.Success) - andxErr = true; - } - - // Return the offset to the end of the reply packet - - return endOfPkt; - } - - /** - * Process a chained tree connect request. - * - * @return New end of reply offset. - * @param cmdOff int Offset to the chained command within the request packet. - * @param outPkt SMBSrvPacket Reply packet. - * @param endOff int Offset to the current end of the reply packet. - */ - protected final int procChainedTreeConnectAndX(int cmdOff, SMBSrvPacket outPkt, int endOff) - { - - // Extract the parameters - - int pwdLen = m_smbPkt.getAndXParameter(cmdOff, 3); - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( outPkt.getUserId()); - - if (vc == null) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return endOff; - } - - // Reset the byte pointer for data unpacking - - m_smbPkt.setBytePointer(m_smbPkt.getAndXByteOffset(cmdOff), m_smbPkt.getAndXByteCount(cmdOff)); - - // Extract the password string - - String pwd = null; - - if (pwdLen > 0) - { - byte[] pwdByt = m_smbPkt.unpackBytes(pwdLen); - pwd = new String(pwdByt); - } - - // Extract the requested share name, as a UNC path - - boolean unicode = m_smbPkt.isUnicode(); - - String uncPath = m_smbPkt.unpackString(unicode); - if (uncPath == null) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return endOff; - } - - // Extract the service type string - - String service = m_smbPkt.unpackString(false); - if (service == null) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return endOff; - } - - // Convert the service type to a shared device type, client may specify '?????' in which - // case we ignore the error. - - int servType = ShareType.ServiceAsType(service); - if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return endOff; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("NT ANDX Tree Connect AndX - " + uncPath + ", " + service); - - // Parse the requested share name - - PCShare share = null; - - try - { - share = new PCShare(uncPath); - } - catch (InvalidUNCPathException ex) - { - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return endOff; - } - - // Map the IPC$ share to the admin pipe type - - if (share.getShareName().compareTo("IPC$") == 0) - servType = ShareType.ADMINPIPE; - - // Check if the session is a null session, only allow access to the IPC$ named pipe share - - if (m_sess.hasClientInformation() && m_sess.getClientInformation().isNullSession() - && servType != ShareType.ADMINPIPE) - { - - // Return an error status - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, - SMBStatus.ErrDos); - return endOff; - } - - // Find the requested shared device - - SharedDevice shareDev = null; - - try - { - - // Get/create the shared device - - shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType, m_sess, - true); - } - catch (InvalidUserException ex) - { - - // Return a logon failure status - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, - SMBStatus.ErrDos); - return endOff; - } - catch (Exception ex) - { - - // Log the generic error - - logger.error("Exception in TreeConnectAndX", ex); - - // Return a general status, bad network name - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, - SMBStatus.ErrSrv); - return endOff; - } - - // Check if the share is valid - - if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) - { - - // Set the error status - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, - SMBStatus.ErrSrv); - return endOff; - } - - // Authenticate the share connect, if the server is using share mode security - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - int sharePerm = FileAccess.Writeable; - - if (auth != null) - { - - // Validate the share connection - - sharePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); - if (sharePerm < 0) - { - - // Invalid share connection request - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, - SMBStatus.ErrDos); - return endOff; - } - } - - // Check if there is an access control manager, if so then run any access controls to - // determine the - // sessions access to the share. - - if (getSession().getServer().hasAccessControlManager() && shareDev.hasAccessControls()) - { - - // Get the access control manager - - AccessControlManager aclMgr = getSession().getServer().getAccessControlManager(); - - // Update the access permission for this session by processing the access control list - // for the - // shared device - - int aclPerm = aclMgr.checkAccessControl(getSession(), shareDev); - - if (aclPerm == FileAccess.NoAccess) - { - - // Invalid share connection request - - outPkt.setError(m_smbPkt.isLongErrorCode(), SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, - SMBStatus.ErrDos); - return endOff; - } - - // If the access controls returned a new access type update the main permission - - if (aclPerm != AccessControl.Default) - sharePerm = aclPerm; - } - - // Allocate a tree id for the new connection - - TreeConnection tree = null; - - try - { - - // Allocate the tree id for this connection - - int treeId = vc.addConnection(shareDev); - outPkt.setTreeId(treeId); - - // Set the file permission that this user has been granted for this share - - tree = vc.findConnection(treeId); - tree.setPermission(sharePerm); - - // Inform the driver that a connection has been opened - - if (tree.getInterface() != null) - tree.getInterface().treeOpened(m_sess, tree); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("ANDX Tree Connect AndX - Allocated Tree Id = " + treeId); - } - catch (TooManyConnectionsException ex) - { - - // Too many connections open at the moment - - outPkt.setError(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); - return endOff; - } - - // Build the tree connect response - - outPkt.setAndXParameterCount(endOff, 2); - outPkt.setAndXParameter(endOff, 0, SMBSrvPacket.NO_ANDX_CMD); - outPkt.setAndXParameter(endOff, 1, 0); - - // Pack the service type - - int pos = outPkt.getAndXByteOffset(endOff); - byte[] outBuf = outPkt.getBuffer(); - pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), outBuf, pos, true); - - // Determine the filesystem type, for disk shares - - String devType = ""; - - try - { - // Check if this is a disk shared device - - if ( shareDev.getType() == ShareType.DISK) - { - // Check if the filesystem driver implements the NTFS streams interface, and streams are - // enabled - - if (shareDev.getInterface() instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) shareDev.getInterface(); - if (ntfsStreams.hasStreamsEnabled(m_sess, tree)) - devType = FileSystem.TypeNTFS; - } - else - { - // Get the filesystem type from the context - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - devType = diskCtx.getFilesystemType(); - } - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Log the error - - logger.error("TreeConnectAndX error", ex); - } - - // Pack the filesystem type - - pos = DataPacker.putString(devType, outBuf, pos, true, outPkt.isUnicode()); - - int bytLen = pos - outPkt.getAndXByteOffset(endOff); - outPkt.setAndXByteCount(endOff, bytLen); - - // Return the new end of packet offset - - return pos; - } - - /** - * Process a chained read file request - * - * @param cmdOff Offset to the chained command within the request packet. - * @param outPkt Reply packet. - * @param endOff Offset to the current end of the reply packet. - * @param netFile File to be read, passed down the chained requests - * @return New end of reply offset. - */ - protected final int procChainedReadAndX(int cmdOff, SMBSrvPacket outPkt, int endOff, NetworkFile netFile) - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return endOff; - } - - // Extract the read file parameters - - long offset = (long) m_smbPkt.getAndXParameterLong(cmdOff, 3); // bottom 32bits of read - // offset - offset &= 0xFFFFFFFFL; - int maxCount = m_smbPkt.getAndXParameter(cmdOff, 5); - - // Check for the NT format request that has the top 32bits of the file offset - - if (m_smbPkt.getAndXParameterCount(cmdOff) == 12) - { - long topOff = (long) m_smbPkt.getAndXParameterLong(cmdOff, 10); - offset += topOff << 32; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Chained File Read AndX : Size=" + maxCount + " ,Pos=" + offset); - - // Read data from the file - - byte[] buf = outPkt.getBuffer(); - int dataPos = 0; - int rdlen = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the returned parameter count so that the byte offset can be calculated - - outPkt.setAndXParameterCount(endOff, 12); - dataPos = outPkt.getAndXByteOffset(endOff); - dataPos = DataPacker.wordAlign(dataPos); // align the data buffer - - // Check if the requested data length will fit into the buffer - - int dataLen = buf.length - dataPos; - if (dataLen < maxCount) - maxCount = dataLen; - - // Read from the file - - rdlen = disk.readFile(m_sess, conn, netFile, buf, dataPos, maxCount, offset); - - // Return the data block - - outPkt.setAndXParameter(endOff, 0, SMBSrvPacket.NO_ANDX_CMD); - outPkt.setAndXParameter(endOff, 1, 0); - - outPkt.setAndXParameter(endOff, 2, 0); // bytes remaining, for pipes only - outPkt.setAndXParameter(endOff, 3, 0); // data compaction mode - outPkt.setAndXParameter(endOff, 4, 0); // reserved - outPkt.setAndXParameter(endOff, 5, rdlen); // data length - outPkt.setAndXParameter(endOff, 6, dataPos - RFCNetBIOSProtocol.HEADER_LEN); // offset - // to - // data - - // Clear the reserved parameters - - for (int i = 7; i < 12; i++) - outPkt.setAndXParameter(endOff, i, 0); - - // Set the byte count - - outPkt.setAndXByteCount(endOff, (dataPos + rdlen) - outPkt.getAndXByteOffset(endOff)); - - // Update the end offset for the new end of packet - - endOff = dataPos + rdlen; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - catch (java.io.IOException ex) - { - } - - // Return the new end of packet offset - - return endOff; - } - - /** - * Process a chained close file request - * - * @param cmdOff int Offset to the chained command within the request packet. - * @param outPkt SMBSrvPacket Reply packet. - * @param endOff int Offset to the current end of the reply packet. - * @return New end of reply offset. - */ - protected final int procChainedClose(int cmdOff, SMBSrvPacket outPkt, int endOff) - { - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return endOff; - } - - // Get the file id from the request - - int fid = m_smbPkt.getAndXParameter(cmdOff, 0); - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - outPkt.setError(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return endOff; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Chained File Close [" + m_smbPkt.getTreeId() + "] fid=" + fid); - - // Close the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Close the file - // - // The disk interface may be null if the file is a named pipe file - - if (disk != null) - disk.closeFile(m_sess, conn, netFile); - - // Indicate that the file has been closed - - netFile.setClosed(true); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - outPkt.setError(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return endOff; - } - catch (java.io.IOException ex) - { - } - - // Clear the returned parameter count and byte count - - outPkt.setAndXParameterCount(endOff, 0); - outPkt.setAndXByteCount(endOff, 0); - - endOff = outPkt.getAndXByteOffset(endOff) - RFCNetBIOSProtocol.HEADER_LEN; - - // Remove the file from the connections list of open files - - conn.removeFile(fid, getSession()); - - // Return the new end of packet offset - - return endOff; - } - - /** - * Process the SMB tree connect request. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - * @exception TooManyConnectionsException Too many concurrent connections on this session. - */ - - protected void procTreeConnectAndX(SMBSrvPacket outPkt) throws SMBSrvException, TooManyConnectionsException, - java.io.IOException - { - - // Check that the received packet looks like a valid tree connect request - - if (m_smbPkt.checkPacketIsValid(4, 3) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - if ( vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Extract the parameters - - int pwdLen = m_smbPkt.getParameter(3); - - // Initialize the byte area pointer - - m_smbPkt.resetBytePointer(); - - // Determine if ASCII or unicode strings are being used - - boolean unicode = m_smbPkt.isUnicode(); - - // Extract the password string - - String pwd = null; - - if (pwdLen > 0) - { - byte[] pwdByts = m_smbPkt.unpackBytes(pwdLen); - pwd = new String(pwdByts); - } - - // Extract the requested share name, as a UNC path - - String uncPath = m_smbPkt.unpackString(unicode); - if (uncPath == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Extract the service type string, always seems to be ASCII - - String service = m_smbPkt.unpackString(false); - if (service == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Convert the service type to a shared device type, client may specify '?????' in which - // case we ignore the error. - - int servType = ShareType.ServiceAsType(service); - if (servType == ShareType.UNKNOWN && service.compareTo("?????") != 0) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("NT Tree Connect AndX - " + uncPath + ", " + service); - - // Parse the requested share name - - String shareName = null; - String hostName = null; - - if (uncPath.startsWith("\\")) - { - - try - { - PCShare share = new PCShare(uncPath); - shareName = share.getShareName(); - hostName = share.getNodeName(); - } - catch (InvalidUNCPathException ex) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - } - else - shareName = uncPath; - - // Map the IPC$ share to the admin pipe type - - if (shareName.compareTo("IPC$") == 0) - servType = ShareType.ADMINPIPE; - - // Check if the session is a null session, only allow access to the IPC$ named pipe share - - if (m_sess.hasClientInformation() && m_sess.getClientInformation().isNullSession() - && servType != ShareType.ADMINPIPE) - { - - // Return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Find the requested shared device - - SharedDevice shareDev = null; - - try - { - - // Get/create the shared device - - shareDev = m_sess.getSMBServer().findShare(hostName, shareName, servType, m_sess, true); - } - catch (InvalidUserException ex) - { - - // Return a logon failure status - - m_sess.sendErrorResponseSMB(SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (Exception ex) - { - - // Log the generic error - - logger.error("TreeConnectAndX error", ex); - - // Return a general status, bad network name - - m_sess.sendErrorResponseSMB(SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); - return; - } - - // Check if the share is valid - - if (shareDev == null || (servType != ShareType.UNKNOWN && shareDev.getType() != servType)) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTBadNetName, SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv); - return; - } - - // Authenticate the share connection depending upon the security mode the server is running - // under - - CifsAuthenticator auth = getSession().getSMBServer().getAuthenticator(); - int sharePerm = FileAccess.Writeable; - - if (auth != null) - { - - // Validate the share connection - - sharePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess); - if (sharePerm < 0) - { - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree connect to " + shareName + ", access denied"); - - // Invalid share connection request - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - } - - // Check if there is an access control manager, if so then run any access controls to - // determine the - // sessions access to the share. - - if (getSession().getServer().hasAccessControlManager() && shareDev.hasAccessControls()) - { - - // Get the access control manager - - AccessControlManager aclMgr = getSession().getServer().getAccessControlManager(); - - // Update the access permission for this session by processing the access control list - // for the - // shared device - - int aclPerm = aclMgr.checkAccessControl(getSession(), shareDev); - - if (aclPerm == FileAccess.NoAccess) - { - - // Invalid share connection request - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the access controls returned a new access type update the main permission - - if (aclPerm != AccessControl.Default) - sharePerm = aclPerm; - } - - // Allocate a tree id for the new connection - - int treeId = vc.addConnection(shareDev); - outPkt.setTreeId(treeId); - - // Set the file permission that this user has been granted for this share - - TreeConnection tree = vc.findConnection(treeId); - tree.setPermission(sharePerm); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE)) - logger.debug("Tree Connect AndX - Allocated Tree Id = " + treeId + ", Permission = " - + FileAccess.asString(sharePerm)); - - // Build the tree connect response - - outPkt.setParameterCount(3); - outPkt.setAndXCommand(0xFF); // no chained reply - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); - - // Pack the service type - - int pos = outPkt.getByteOffset(); - pos = DataPacker.putString(ShareType.TypeAsService(shareDev.getType()), m_smbPkt.getBuffer(), pos, true); - - // Determine the filesystem type, for disk shares - - String devType = ""; - - try - { - // Check if this is a disk shared device - - if ( shareDev.getType() == ShareType.DISK) - { - // Check if the filesystem driver implements the NTFS streams interface, and streams are - // enabled - - if (shareDev.getInterface() instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) shareDev.getInterface(); - if (ntfsStreams.hasStreamsEnabled(m_sess, tree)) - devType = FileSystem.TypeNTFS; - } - else - { - // Get the filesystem type from the context - - DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); - devType = diskCtx.getFilesystemType(); - } - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Log the error - - logger.error("TreeConnectAndX error", ex); - } - - // Pack the filesystem type - - pos = DataPacker.putString(devType, m_smbPkt.getBuffer(), pos, true, outPkt.isUnicode()); - outPkt.setByteCount(pos - outPkt.getByteOffset()); - - // Send the response - - m_sess.sendResponseSMB(outPkt); - - // Inform the driver that a connection has been opened - - if (tree.getInterface() != null) - tree.getInterface().treeOpened(m_sess, tree); - } - - /** - * Close a file that has been opened on the server. - * - * @param outPkt Response SMB packet. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procCloseFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file close request - - if (m_smbPkt.checkPacketIsValid(3, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Get the file id from the request - - int fid = m_smbPkt.getParameter(0); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File close [" + m_smbPkt.getTreeId() + "] fid=" + fid); - - // Close the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Close the file - // - // The disk interface may be null if the file is a named pipe file - - if (disk != null) - disk.closeFile(m_sess, conn, netFile); - - // Indicate that the file has been closed - - netFile.setClosed(true); - } - catch (AccessDeniedException ex) - { - // Not allowed to delete the file, when delete on close flag is set - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (DiskFullException ex) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("IOException ignore: "+ex); - } - - // Remove the file from the connections list of open files - - conn.removeFile(fid, getSession()); - - // Build the close file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (netFile.getWriteCount() > 0 && diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileSizeChanged(netFile.getFullName()); - - if (netFile.hasDeleteOnClose() && diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, netFile.getFullName()); - } - - /** - * Process a transact2 request. The transact2 can contain many different sub-requests. - * - * @param outPkt SMBSrvPacket - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procTransact2(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(14, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Create a transact packet using the received SMB packet - - SMBSrvTransPacket tranPkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); - - // Create a transact buffer to hold the transaction setup, parameter and data blocks - - SrvTransactBuffer transBuf = null; - int subCmd = tranPkt.getSubFunction(); - - if (tranPkt.getTotalParameterCount() == tranPkt.getRxParameterBlockLength() - && tranPkt.getTotalDataCount() == tranPkt.getRxDataBlockLength()) - { - - // Create a transact buffer using the packet buffer, the entire request is contained in - // a single - // packet - - transBuf = new SrvTransactBuffer(tranPkt); - } - else - { - - // Create a transact buffer to hold the multiple transact request parameter/data blocks - - transBuf = new SrvTransactBuffer(tranPkt.getSetupCount(), tranPkt.getTotalParameterCount(), tranPkt - .getTotalDataCount()); - transBuf.setType(tranPkt.getCommand()); - transBuf.setFunction(subCmd); - - // Append the setup, parameter and data blocks to the transaction data - - byte[] buf = tranPkt.getBuffer(); - - transBuf.appendSetup(buf, tranPkt.getSetupOffset(), tranPkt.getSetupCount() * 2); - transBuf.appendParameter(buf, tranPkt.getRxParameterBlock(), tranPkt.getRxParameterBlockLength()); - transBuf.appendData(buf, tranPkt.getRxDataBlock(), tranPkt.getRxDataBlockLength()); - } - - // Set the return data limits for the transaction - - transBuf.setReturnLimits(tranPkt.getMaximumReturnSetupCount(), tranPkt.getMaximumReturnParameterCount(), - tranPkt.getMaximumReturnDataCount()); - - // Check for a multi-packet transaction, for a multi-packet transaction we just acknowledge - // the receive with - // an empty response SMB - - if (transBuf.isMultiPacket()) - { - - // Save the partial transaction data - - vc.setTransaction(transBuf); - - // Send an intermediate acknowedgement response - - m_sess.sendSuccessResponseSMB(); - return; - } - - // Check if the transaction is on the IPC$ named pipe, the request requires special - // processing - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); - return; - } - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); - - // Process the transaction buffer - - processTransactionBuffer(transBuf, outPkt); - } - - /** - * Process a transact2 secondary request. - * - * @param outPkt SMBSrvPacket - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procTransact2Secondary(SMBSrvPacket outPkt) throws IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(8, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Check if there is an active transaction, and it is an NT transaction - - if (vc.hasTransaction() == false - || (vc.getTransaction().isType() == PacketType.Transaction && m_smbPkt.getCommand() != PacketType.TransactionSecond) - || (vc.getTransaction().isType() == PacketType.Transaction2 && m_smbPkt.getCommand() != PacketType.Transaction2Second)) - { - - // No transaction to continue, or packet does not match the existing transaction, return - // an error - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Create an NT transaction using the received packet - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(m_smbPkt.getBuffer()); - byte[] buf = tpkt.getBuffer(); - SrvTransactBuffer transBuf = vc.getTransaction(); - - // Append the parameter data to the transaction buffer, if any - - int plen = tpkt.getSecondaryParameterBlockCount(); - if (plen > 0) - { - - // Append the data to the parameter buffer - - DataBuffer paramBuf = transBuf.getParameterBuffer(); - paramBuf.appendData(buf, tpkt.getSecondaryParameterBlockOffset(), plen); - } - - // Append the data block to the transaction buffer, if any - - int dlen = tpkt.getSecondaryDataBlockCount(); - if (dlen > 0) - { - - // Append the data to the data buffer - - DataBuffer dataBuf = transBuf.getDataBuffer(); - dataBuf.appendData(buf, tpkt.getSecondaryDataBlockOffset(), dlen); - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction Secondary [" + m_smbPkt.getTreeId() + "] paramLen=" + plen + ", dataLen=" + dlen); - - // Check if the transaction has been received or there are more sections to be received - - int totParam = tpkt.getTotalParameterCount(); - int totData = tpkt.getTotalDataCount(); - - int paramDisp = tpkt.getParameterBlockDisplacement(); - int dataDisp = tpkt.getDataBlockDisplacement(); - - if ((paramDisp + plen) == totParam && (dataDisp + dlen) == totData) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction complete, processing ..."); - - // Clear the in progress transaction - - vc.setTransaction(null); - - // Check if the transaction is on the IPC$ named pipe, the request requires special - // processing - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.procTransaction(vc, transBuf, m_sess, outPkt); - return; - } - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("Transaction second [" + m_smbPkt.getTreeId() + "] tbuf=" + transBuf); - - // Process the transaction - - processTransactionBuffer(transBuf, outPkt); - } - else - { - - // There are more transaction parameter/data sections to be received, return an - // intermediate response - - m_sess.sendSuccessResponseSMB(); - } - } - - /** - * Process a transaction buffer - * - * @param tbuf TransactBuffer - * @param outPkt SMBSrvPacket - * @exception IOException If a network error occurs - * @exception SMBSrvException If an SMB error occurs - */ - private final void processTransactionBuffer(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws IOException, - SMBSrvException - { - - // Get the transact2 sub-command code and process the request - - switch (tbuf.getFunction()) - { - - // Start a file search - - case PacketType.Trans2FindFirst: - procTrans2FindFirst(tbuf, outPkt); - break; - - // Continue a file search - - case PacketType.Trans2FindNext: - procTrans2FindNext(tbuf, outPkt); - break; - - // Query file system information - - case PacketType.Trans2QueryFileSys: - procTrans2QueryFileSys(tbuf, outPkt); - break; - - // Query path - - case PacketType.Trans2QueryPath: - procTrans2QueryPath(tbuf, outPkt); - break; - - // Query file information via handle - - case PacketType.Trans2QueryFile: - procTrans2QueryFile(tbuf, outPkt); - break; - - // Set file information via handle - - case PacketType.Trans2SetFile: - procTrans2SetFile(tbuf, outPkt); - break; - - // Set file information via path - - case PacketType.Trans2SetPath: - procTrans2SetPath(tbuf, outPkt); - break; - - // Unknown transact2 command - - default: - - // Return an unrecognized command error - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - break; - } - } - - /** - * Close a search started via the transact2 find first/next command. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procFindClose(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid find close request - - if (m_smbPkt.checkPacketIsValid(1, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Get the search id - - int searchId = m_smbPkt.getParameter(0); - - // Get the search context - - SearchContext ctx = vc.getSearchContext(searchId); - - if (ctx == null) - { - - // Invalid search handle - - m_sess.sendSuccessResponseSMB(); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Close trans search [" + searchId + "]"); - - // Deallocate the search slot, close the search. - - vc.deallocateSearchSlot(searchId); - - // Return a success status SMB - - m_sess.sendSuccessResponseSMB(); - } - - /** - * Process the file lock/unlock request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procLockingAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid locking andX request - - if (m_smbPkt.checkPacketIsValid(8, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Extract the file lock/unlock parameters - - int fid = m_smbPkt.getParameter(2); - int lockType = m_smbPkt.getParameter(3); - long lockTmo = m_smbPkt.getParameterLong(4); - int unlockCnt = m_smbPkt.getParameter(6); - int lockCnt = m_smbPkt.getParameter(7); - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.Win32InvalidHandle, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) - logger.debug("File Lock [" + netFile.getFileId() + "] : type=0x" + Integer.toHexString(lockType) + ", tmo=" - + lockTmo + ", locks=" + lockCnt + ", unlocks=" + unlockCnt); - - DiskInterface disk = null; - try - { - - // Get the disk interface for the share - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the virtual filesystem supports file locking - - if (disk instanceof FileLockingInterface) - { - - // Get the lock manager - - FileLockingInterface lockInterface = (FileLockingInterface) disk; - LockManager lockMgr = lockInterface.getLockManager(m_sess, conn); - - // Unpack the lock/unlock structures - - m_smbPkt.resetBytePointer(); - boolean largeFileLock = LockingAndX.hasLargeFiles(lockType); - - // Optimize for a single lock/unlock structure - - if ((unlockCnt + lockCnt) == 1) - { - - // Get the unlock/lock structure - - int pid = m_smbPkt.unpackWord(); - long offset = -1; - long length = -1; - - if (largeFileLock == false) - { - - // Get the lock offset and length, short format - - offset = m_smbPkt.unpackInt(); - length = m_smbPkt.unpackInt(); - } - else - { - - // Get the lock offset and length, large format - - m_smbPkt.skipBytes(2); - - offset = ((long) m_smbPkt.unpackInt()) << 32; - offset += (long) m_smbPkt.unpackInt(); - - length = ((long) m_smbPkt.unpackInt()) << 32; - length += (long) m_smbPkt.unpackInt(); - } - - // Create the lock/unlock details - - FileLock fLock = lockMgr.createLockObject(m_sess, conn, netFile, offset, length, pid); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) - logger.debug(" Single " + (lockCnt == 1 ? "Lock" : "UnLock") + " lock=" + fLock.toString()); - - // Perform the lock/unlock request - - try - { - - // Check if the request is an unlock - - if (unlockCnt > 0) - { - - // Unlock the file - - lockMgr.unlockFile(m_sess, conn, netFile, fLock); - } - else - { - - // Lock the file - - lockMgr.lockFile(m_sess, conn, netFile, fLock); - } - } - catch (NotLockedException ex) - { - - // Return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTRangeNotLocked, SMBStatus.DOSNotLocked, SMBStatus.ErrDos); - return; - } - catch (LockConflictException ex) - { - - // Return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTLockNotGranted, SMBStatus.DOSLockConflict, SMBStatus.ErrDos); - return; - } - catch (IOException ex) - { - - // Return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - return; - } - } - else - { - - // Unpack the lock/unlock structures - - } - } - else - { - - // Return a 'not locked' status if there are unlocks in the request else return a - // success status - - if (unlockCnt > 0) - { - - // Return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTRangeNotLocked, SMBStatus.DOSNotLocked, SMBStatus.ErrDos); - return; - } - } - - // Return a success response - - outPkt.setParameterCount(2); - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); - outPkt.setByteCount(0); - - // Send the lock request response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the logoff request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procLogoffAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - // Check that the received packet looks like a valid logoff andX request - - if (m_smbPkt.checkPacketIsValid(2, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - int uid = m_smbPkt.getUserId(); - VirtualCircuit vc = m_sess.findVirtualCircuit( uid); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // DEBUG - - if ( logger.isDebugEnabled() && m_sess.hasDebug( SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Logoff vc=" + vc); - - // Close the virtual circuit - - m_sess.removeVirtualCircuit( uid); - - // Return a success status SMB - - m_sess.sendSuccessResponseSMB(); - } - - /** - * Process the file open request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procOpenAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid open andX request - - if (m_smbPkt.checkPacketIsValid(15, 1) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. If the device is - // not a disk type device then return an error. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - else if (conn.getSharedDevice().getType() != ShareType.DISK) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Extract the open file parameters - - int access = m_smbPkt.getParameter(3); - int srchAttr = m_smbPkt.getParameter(4); - int fileAttr = m_smbPkt.getParameter(5); - int crTime = m_smbPkt.getParameter(6); - int crDate = m_smbPkt.getParameter(7); - int openFunc = m_smbPkt.getParameter(8); - int allocSiz = m_smbPkt.getParameterLong(9); - - // Extract the filename string - - String fileName = m_smbPkt.unpackString(m_smbPkt.isUnicode()); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Create the file open parameters - - long crDateTime = 0L; - if (crTime > 0 && crDate > 0) - crDateTime = new SMBDate(crDate, crTime).getTime(); - - FileOpenParams params = new FileOpenParams(fileName, openFunc, access, srchAttr, fileAttr, allocSiz, crDateTime); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Open AndX [" + m_smbPkt.getTreeId() + "] params=" + params); - - // Check if the file name is valid - - if ( isValidPath( params.getPath()) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the disk interface and open the requested file - - int fid; - NetworkFile netFile = null; - int respAction = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Check if the requested file already exists - - int fileSts = disk.fileExists(m_sess, conn, fileName); - - if (fileSts == FileStatus.NotExist) - { - - // Check if the file should be created if it does not exist - - if (FileAction.createNotExists(openFunc)) - { - - // Create a new file - - netFile = disk.createFile(m_sess, conn, params); - - // Indicate that the file did not exist and was created - - respAction = FileAction.FileCreated; - } - else - { - - // Check if the path is a directory - - if (fileSts == FileStatus.DirectoryExists) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - } - else - { - - // Return a file not found error - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - } - return; - } - } - else - { - - // Open the requested file - - netFile = disk.openFile(m_sess, conn, params); - - // Set the file action response - - if (FileAction.truncateExistingFile(openFunc)) - respAction = FileAction.FileTruncated; - else - respAction = FileAction.FileExisted; - } - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, - SMBStatus.ErrDos); - return; - } - catch (FileOfflineException ex) - { - - // File data is unavailable - - m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the open file response - - outPkt.setParameterCount(15); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); // AndX offset - - outPkt.setParameter(2, fid); - outPkt.setParameter(3, netFile.getFileAttributes()); // file attributes - - SMBDate modDate = null; - - if (netFile.hasModifyDate()) - modDate = new SMBDate(netFile.getModifyDate()); - - outPkt.setParameter(4, modDate != null ? modDate.asSMBTime() : 0); // last write time - outPkt.setParameter(5, modDate != null ? modDate.asSMBDate() : 0); // last write date - outPkt.setParameterLong(6, netFile.getFileSizeInt()); // file size - outPkt.setParameter(8, netFile.getGrantedAccess()); - outPkt.setParameter(9, OpenAndX.FileTypeDisk); - outPkt.setParameter(10, 0); // named pipe state - outPkt.setParameter(11, respAction); - outPkt.setParameter(12, 0); // server FID (long) - outPkt.setParameter(13, 0); - outPkt.setParameter(14, 0); - - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process the file read request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procReadAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid read andX request - - if (m_smbPkt.checkPacketIsValid(10, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Extract the read file parameters - - int fid = m_smbPkt.getParameter(2); - long offset = (long) m_smbPkt.getParameterLong(3); // bottom 32bits of read offset - offset &= 0xFFFFFFFFL; - int maxCount = m_smbPkt.getParameter(5); - - // Check for the NT format request that has the top 32bits of the file offset - - if (m_smbPkt.getParameterCount() == 12) - { - long topOff = (long) m_smbPkt.getParameterLong(10); - offset += topOff << 32; - } - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Read AndX [" + netFile.getFileId() + "] : Size=" + maxCount + " ,Pos=" + offset); - - // Read data from the file - - byte[] buf = outPkt.getBuffer(); - int dataPos = 0; - int rdlen = 0; - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the returned parameter count so that the byte offset can be calculated - - outPkt.setParameterCount(12); - dataPos = outPkt.getByteOffset(); - dataPos = DataPacker.wordAlign(dataPos); // align the data buffer - - // Check if the requested data length will fit into the buffer - - int dataLen = buf.length - dataPos; - if (dataLen < maxCount) - maxCount = dataLen; - - // Read from the file - - rdlen = disk.readFile(m_sess, conn, netFile, buf, dataPos, maxCount, offset); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (FileOfflineException ex) - { - - // File data is unavailable - - m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDReadFault, SMBStatus.ErrHrd); - return; - } - catch (LockConflictException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) - logger.debug("Read Lock Error [" + netFile.getFileId() + "] : Size=" + maxCount + " ,Pos=" + offset); - - // File is locked - - m_sess.sendErrorResponseSMB(SMBStatus.NTLockConflict, SMBStatus.DOSLockConflict, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // User does not have the required access rights or file is not accessible - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to read the file - - m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd); - return; - } - - // Return the data block - - outPkt.setAndXCommand(0xFF); // no chained command - outPkt.setParameter(1, 0); - outPkt.setParameter(2, 0); // bytes remaining, for pipes only - outPkt.setParameter(3, 0); // data compaction mode - outPkt.setParameter(4, 0); // reserved - outPkt.setParameter(5, rdlen); // data length - outPkt.setParameter(6, dataPos - RFCNetBIOSProtocol.HEADER_LEN); // offset to data - - // Clear the reserved parameters - - for (int i = 7; i < 12; i++) - outPkt.setParameter(i, 0); - - // Set the byte count - - outPkt.setByteCount((dataPos + rdlen) - outPkt.getByteOffset()); - - // Check if there is a chained command, or commands - - if (m_smbPkt.hasAndXCommand()) - { - - // Process any chained commands, AndX - - int pos = procAndXCommands(outPkt, outPkt.getPacketLength(), netFile); - - // Send the read andX response - - m_sess.sendResponseSMB(outPkt, pos); - } - else - { - - // Send the normal read andX response - - m_sess.sendResponseSMB(outPkt); - } - } - - /** - * Rename a file. - * - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected void procRenameFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid rename file request - - if (m_smbPkt.checkPacketIsValid(1, 4) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the Unicode flag - - boolean isUni = m_smbPkt.isUnicode(); - - // Read the data block - - m_smbPkt.resetBytePointer(); - - // Extract the old file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String oldName = m_smbPkt.unpackString(isUni); - if (oldName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Extract the new file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String newName = m_smbPkt.unpackString(isUni); - if (newName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Rename [" + m_smbPkt.getTreeId() + "] old name=" + oldName + ", new name=" + newName); - - // Check if the from/to paths are - - if ( isValidPath( oldName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - if ( isValidPath( newName) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the disk interface and rename the requested file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Rename the requested file - - disk.renameFile(m_sess, conn, oldName, newName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (FileNotFoundException ex) - { - - // Source file/directory does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (FileExistsException ex) - { - - // Destination file/directory already exists - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to rename the file/directory - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, - SMBStatus.ErrDos); - return; - } - - // Build the rename file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyRename(oldName, newName); - } - - /** - * Delete a file. - * - * @param outPkt SMBSrvPacket - * @exception IOException If an network error occurs - * @exception SMBSrvException If an SMB error occurs - */ - protected void procDeleteFile(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid file delete request - - if (m_smbPkt.checkPacketIsValid(1, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the Unicode flag - - boolean isUni = m_smbPkt.isUnicode(); - - // Read the data block - - m_smbPkt.resetBytePointer(); - - // Extract the old file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String fileName = m_smbPkt.unpackString(isUni); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("File Delete [" + m_smbPkt.getTreeId() + "] name=" + fileName); - - // Access the disk interface and delete the file(s) - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Delete file(s) - - disk.deleteFile(m_sess, conn, fileName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to delete the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the delete file response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, fileName); - } - - /** - * Delete a directory. - * - * @param outPkt SMBSrvPacket - * @exception IOException If a network error occurs - * @exception SMBSrvException If an SMB error occurs - */ - protected void procDeleteDirectory(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid delete directory request - - if (m_smbPkt.checkPacketIsValid(0, 2) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the Unicode flag - - boolean isUni = m_smbPkt.isUnicode(); - - // Read the data block - - m_smbPkt.resetBytePointer(); - - // Extract the old file name - - if (m_smbPkt.unpackByte() != DataType.ASCII) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - String dirName = m_smbPkt.unpackString(isUni); - if (dirName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("Directory Delete [" + m_smbPkt.getTreeId() + "] name=" + dirName); - - // Access the disk interface and delete the directory - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Delete the directory - - disk.deleteDirectory(m_sess, conn, dirName); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to delete the directory - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (DirectoryNotEmptyException ex) - { - - // Directory not empty - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryNotEmpty, SMBStatus.ErrDos); - return; - } - catch (java.io.IOException ex) - { - - // Failed to delete the directory - - m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos); - return; - } - - // Build the delete directory response - - outPkt.setParameterCount(0); - outPkt.setByteCount(0); - - // Send the response packet - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler()) - diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionRemoved, dirName); - } - - /** - * Process a transact2 file search request. - * - * @param tbuf Transaction request details - * @param outPkt Packet to use for the reply. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2FindFirst(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(tbuf.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv); - return; - } - - // Get the search parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int srchAttr = paramBuf.getShort(); - int maxFiles = paramBuf.getShort(); - int srchFlag = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - paramBuf.skipBytes(4); - - String srchPath = paramBuf.getString(tbuf.isUnicode()); - - // Check if the search path is valid - - if (srchPath == null || srchPath.length() == 0) - { - - // Invalid search request - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - else if (srchPath.endsWith("\\")) - { - - // Make the search a wildcard search - - srchPath = srchPath + "*.*"; - } - - // Check for the Macintosh information level, if the Macintosh extensions are not enabled - // return an error - - if (infoLevl == FindInfoPacker.InfoMacHfsInfo && getSession().hasMacintoshExtensions() == false) - { - - // Return an error status, Macintosh extensions are not enabled - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Check if the search path is valid - - if ( isValidSearchPath( srchPath) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the search is for an NTFS stream - - if ( FileName.containsStreamName( srchPath)) - { - // NTFS streams not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - // Access the shared device disk interface - - SearchContext ctx = null; - DiskInterface disk = null; - int searchId = -1; - boolean wildcardSearch = false; - - try - { - - // Access the disk interface - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Allocate a search slot for the new search - - searchId = vc.allocateSearchSlot(); - if (searchId == -1) - { - - // Failed to allocate a slot for the new search - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv); - return; - } - - // Check if this is a wildcard search or single file search - - if (WildCard.containsWildcards(srchPath) || WildCard.containsUnicodeWildcard(srchPath)) - wildcardSearch = true; - - // Check if the search contains Unicode wildcards - - if (tbuf.isUnicode() && WildCard.containsUnicodeWildcard(srchPath)) - { - - // Translate the Unicode wildcards to standard DOS wildcards - - srchPath = WildCard.convertUnicodeWildcardToDOS(srchPath); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Converted Unicode wildcards to:" + srchPath); - } - - // Start a new search - - ctx = disk.startSearch(m_sess, conn, srchPath, srchAttr); - if (ctx != null) - { - - // Store details of the search in the context - - ctx.setTreeId(m_smbPkt.getTreeId()); - ctx.setMaximumFiles(maxFiles); - } - else - { - - // Failed to start the search, return a no more files error - - m_sess.sendErrorResponseSMB(SMBStatus.NTNoSuchFile, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Save the search context - - vc.setSearchContext(searchId, ctx); - - // Create the reply transact buffer - - SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); - DataBuffer dataBuf = replyBuf.getDataBuffer(); - - // Determine the maximum return data length - - int maxLen = replyBuf.getReturnDataLimit(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Start trans search [" + searchId + "] - " + srchPath + ", attr=0x" - + Integer.toHexString(srchAttr) + ", maxFiles=" + maxFiles + ", maxLen=" + maxLen - + ", infoLevel=" + infoLevl + ", flags=0x" + Integer.toHexString(srchFlag)); - - // Loop until we have filled the return buffer or there are no more files to return - - int fileCnt = 0; - int packLen = 0; - int lastNameOff = 0; - - // Flag to indicate if resume ids should be returned - - boolean resumeIds = false; - if (infoLevl == FindInfoPacker.InfoStandard && (srchFlag & FindFirstNext.ReturnResumeKey) != 0) - { - - // Windows servers only seem to return resume keys for the standard information - // level - - resumeIds = true; - } - - // If this is a wildcard search then add the '.' and '..' entries - - if (wildcardSearch == true && ReturnDotFiles == true) - { - - // Pack the '.' file information - - if (resumeIds == true) - { - dataBuf.putInt(-1); - maxLen -= 4; - } - - lastNameOff = dataBuf.getPosition(); - FileInfo dotInfo = new FileInfo(".", 0, FileAttribute.Directory); - dotInfo.setFileId(dotInfo.getFileName().hashCode()); - - packLen = FindInfoPacker.packInfo(dotInfo, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet, update the remaining buffer length - - fileCnt++; - maxLen -= packLen; - - // Pack the '..' file information - - if (resumeIds == true) - { - dataBuf.putInt(-2); - maxLen -= 4; - } - - lastNameOff = dataBuf.getPosition(); - dotInfo.setFileName(".."); - dotInfo.setFileId(dotInfo.getFileName().hashCode()); - - packLen = FindInfoPacker.packInfo(dotInfo, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet, update the remaining buffer length - - fileCnt++; - maxLen -= packLen; - } - - boolean pktDone = false; - boolean searchDone = false; - - FileInfo info = new FileInfo(); - - while (pktDone == false && fileCnt < maxFiles) - { - - // Get file information from the search - - if (ctx.nextFileInfo(info) == false) - { - - // No more files - - pktDone = true; - searchDone = true; - } - - // Check if the file information will fit into the return buffer - - else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) - { - - // Pack the resume id, if required - - if (resumeIds == true) - { - dataBuf.putInt(ctx.getResumeId()); - maxLen -= 4; - } - - // Save the offset to the last file information structure - - lastNameOff = dataBuf.getPosition(); - - // Pack the file information - - packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet - - fileCnt++; - - // Recalculate the remaining buffer space - - maxLen -= packLen; - } - else - { - - // Set the search restart point - - ctx.restartAt(info); - - // No more buffer space - - pktDone = true; - } - } - - // Check for a single file search and the file was not found, in this case return an - // error status - - if (wildcardSearch == false && fileCnt == 0) - throw new FileNotFoundException(srchPath); - - // Check for a search where the maximum files is set to one, close the search - // immediately. - - if (maxFiles == 1 && fileCnt == 1) - searchDone = true; - - // Clear the next structure offset, if applicable - - FindInfoPacker.clearNextOffset(dataBuf, infoLevl, lastNameOff); - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(searchId); - paramBuf.putShort(fileCnt); - paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); - paramBuf.putShort(0); - paramBuf.putShort(lastNameOff); - - // Send the transaction response - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); - tpkt.doTransactionResponse(m_sess, replyBuf); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, dataLen=" + dataBuf.getLength() - + ", moreFiles=" + ctx.hasMoreFiles()); - - // Check if the search is complete - - if (searchDone == true || ctx.hasMoreFiles() == false) - { - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Search complete)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - else if (( srchFlag & FindFirstNext.CloseSearch) != 0) - { - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Close)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - } - catch (FileNotFoundException ex) - { - - // Search path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTNoSuchFile, SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - } - catch (PathNotFoundException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Requested path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - } - catch (UnsupportedInfoLevelException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidLevel, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - } - - /** - * Process a transact2 file search continue request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2FindNext(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(tbuf.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the search parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int searchId = paramBuf.getShort(); - int maxFiles = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - paramBuf.getInt(); - int srchFlag = paramBuf.getShort(); - - String resumeName = paramBuf.getString(tbuf.isUnicode()); - - // Access the shared device disk interface - - SearchContext ctx = null; - - try - { - // Retrieve the search context - - ctx = vc.getSearchContext(searchId); - if (ctx == null) - { - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search context null - [" + searchId + "]"); - - // Invalid search handle - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - return; - } - - // Create the reply transaction buffer - - SrvTransactBuffer replyBuf = new SrvTransactBuffer(tbuf); - DataBuffer dataBuf = replyBuf.getDataBuffer(); - - // Determine the maximum return data length - - int maxLen = replyBuf.getReturnDataLimit(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Continue search [" + searchId + "] - " + resumeName + ", maxFiles=" + maxFiles - + ", maxLen=" + maxLen + ", infoLevel=" + infoLevl + ", flags=0x" - + Integer.toHexString(srchFlag)); - - // Loop until we have filled the return buffer or there are no more files to return - - int fileCnt = 0; - int packLen = 0; - int lastNameOff = 0; - - // Flag to indicate if resume ids should be returned - - boolean resumeIds = false; - if (infoLevl == FindInfoPacker.InfoStandard && (srchFlag & FindFirstNext.ReturnResumeKey) != 0) - { - - // Windows servers only seem to return resume keys for the standard information - // level - - resumeIds = true; - } - - // Flags to indicate packet full or search complete - - boolean pktDone = false; - boolean searchDone = false; - - FileInfo info = new FileInfo(); - - while (pktDone == false && fileCnt < maxFiles) - { - - // Get file information from the search - - if (ctx.nextFileInfo(info) == false) - { - - // No more files - - pktDone = true; - searchDone = true; - } - - // Check if the file information will fit into the return buffer - - else if (FindInfoPacker.calcInfoSize(info, infoLevl, false, true) <= maxLen) - { - - // Pack the resume id, if required - - if (resumeIds == true) - { - dataBuf.putInt(ctx.getResumeId()); - maxLen -= 4; - } - - // Save the offset to the last file information structure - - lastNameOff = dataBuf.getPosition(); - - // Pack the file information - - packLen = FindInfoPacker.packInfo(info, dataBuf, infoLevl, tbuf.isUnicode()); - - // Update the file count for this packet - - fileCnt++; - - // Recalculate the remaining buffer space - - maxLen -= packLen; - } - else - { - - // Set the search restart point - - ctx.restartAt(info); - - // No more buffer space - - pktDone = true; - } - } - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(fileCnt); - paramBuf.putShort(ctx.hasMoreFiles() ? 0 : 1); - paramBuf.putShort(0); - paramBuf.putShort(lastNameOff); - - // Send the transaction response - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(outPkt.getBuffer()); - tpkt.doTransactionResponse(m_sess, replyBuf); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("Search [" + searchId + "] Returned " + fileCnt + " files, dataLen=" + dataBuf.getLength() - + ", moreFiles=" + ctx.hasMoreFiles()); - - // Check if the search is complete - - if (searchDone == true || ctx.hasMoreFiles() == false) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Search complete)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - else if (( srchFlag & FindFirstNext.CloseSearch) != 0) - { - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH)) - logger.debug("End start search [" + searchId + "] (Close)"); - - // Release the search context - - vc.deallocateSearchSlot(searchId); - } - } - catch (FileNotFoundException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Search path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos); - } - catch (UnsupportedInfoLevelException ex) - { - - // Deallocate the search - - if (searchId != -1) - vc.deallocateSearchSlot(searchId); - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidLevel, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - } - - /** - * Process a transact2 file system query request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2QueryFileSys(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) - throws java.io.IOException, SMBSrvException - { - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the query file system required information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevl = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Query File System Info - level = 0x" + Integer.toHexString(infoLevl)); - - // Access the shared device disk interface - - try - { - - // Access the disk interface and context - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the disk information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos; // no parameters returned - - // Create a data buffer using the SMB packet. The response should always fit into a - // single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Determine the information level requested - - SrvDiskInfo diskInfo = null; - VolumeInfo volInfo = null; - - switch (infoLevl) - { - - // Standard disk information - - case DiskInfoPacker.InfoStandard: - - // Get the disk information - - diskInfo = getDiskInformation(disk, diskCtx); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packStandardInfo(diskInfo, replyBuf); - break; - - // Volume label information - - case DiskInfoPacker.InfoVolume: - - // Get the volume label information - - volInfo = getVolumeInformation(disk, diskCtx); - - // Pack the volume label information - - DiskInfoPacker.packVolumeInfo(volInfo, replyBuf, tbuf.isUnicode()); - break; - - // Full volume information - - case DiskInfoPacker.InfoFsVolume: - - // Get the volume information - - volInfo = getVolumeInformation(disk, diskCtx); - - // Pack the volume information - - DiskInfoPacker.packFsVolumeInformation(volInfo, replyBuf, tbuf.isUnicode()); - break; - - // Filesystem size information - - case DiskInfoPacker.InfoFsSize: - - // Get the disk information - - diskInfo = getDiskInformation(disk, diskCtx); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packFsSizeInformation(diskInfo, replyBuf); - break; - - // Filesystem device information - - case DiskInfoPacker.InfoFsDevice: - DiskInfoPacker.packFsDevice(NTIOCtl.DeviceDisk, diskCtx.getDeviceAttributes(), replyBuf); - break; - - // Filesystem attribute information - - case DiskInfoPacker.InfoFsAttribute: - String fsType = diskCtx.getFilesystemType(); - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - if (ntfsStreams.hasStreamsEnabled(m_sess, conn)) - fsType = "NTFS"; - } - - // Pack the filesystem type - - DiskInfoPacker.packFsAttribute(diskCtx.getFilesystemAttributes(), 255, fsType, tbuf.isUnicode(), - replyBuf); - break; - - // Mac filesystem information - - case DiskInfoPacker.InfoMacFsInfo: - - // Check if the filesystem supports NTFS streams - // - // We should only return a valid response to the Macintosh information level if the - // filesystem - // does NOT support NTFS streams. By returning an error status the Thursby DAVE - // software will treat - // the filesystem as a WinXP/2K filesystem with full streams support. - - boolean ntfs = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - ntfs = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // If the filesystem does not support NTFS streams then send a valid response. - - if (ntfs == false) - { - - // Get the disk and volume information - - diskInfo = getDiskInformation(disk, diskCtx); - volInfo = getVolumeInformation(disk, diskCtx); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packMacFsInformation(diskInfo, volInfo, ntfs, replyBuf); - } - break; - - // Filesystem size information, including per user allocation limit - - case DiskInfoPacker.InfoFullFsSize: - - // Get the disk information - - diskInfo = getDiskInformation(disk, diskCtx); - long userLimit = diskInfo.getTotalUnits(); - - // Pack the disk information into the return data packet - - DiskInfoPacker.packFullFsSizeInformation(userLimit, diskInfo, replyBuf); - break; - } - - // Check if any data was packed, if not then the information level is not supported - - if (replyBuf.getPosition() == dataPos) - { - m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - int bytCnt = replyBuf.getPosition() - outPkt.getByteOffset(); - replyBuf.setEndOfBuffer(); - int dataLen = replyBuf.getLength(); - SMBSrvTransPacket.initTransactReply(outPkt, 0, prmPos, dataLen, dataPos); - outPkt.setByteCount(bytCnt); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - } - - /** - * Process a transact2 query path information request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - protected final void procTrans2QueryPath(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the query path information level and file/directory name - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevl = paramBuf.getShort(); - paramBuf.skipBytes(4); - - String path = paramBuf.getString(tbuf.isUnicode()); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Query Path - level = 0x" + Integer.toHexString(infoLevl) + ", path = " + path); - - // Check if the file name is valid - - if ( isValidPath( path) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the shared device disk interface - - try - { - - // Access the disk interface - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the file information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos + 4; - - // Pack the return parametes, EA error offset - - outPkt.setPosition(prmPos); - outPkt.packWord(0); - - // Create a data buffer using the SMB packet. The response should always fit into a - // single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Check if the virtual filesystem supports streams, and streams are enabled - - boolean streams = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // Check if the path is for an NTFS stream, return an error if streams are not supported or not enabled - - if ( streams == false && path.indexOf(FileOpenParams.StreamSeparator) != -1) - { - // NTFS streams not supported, return an error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Check for the file streams information level - - int dataLen = 0; - - if (streams == true - && (infoLevl == FileInfoLevel.PathFileStreamInfo || infoLevl == FileInfoLevel.NTFileStreamInfo)) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) - logger.debug("Get NTFS streams list path=" + path); - - // Get the list of streams from the share driver - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - StreamInfoList streamList = ntfsStreams.getStreamList(m_sess, conn, path); - - if (streamList == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - // Pack the file streams information into the return data packet - - dataLen = QueryInfoPacker.packStreamFileInfo(streamList, replyBuf, true); - } - else - { - - // Get the file information - - FileInfo fileInfo = disk.getFileInformation(m_sess, conn, path); - - if (fileInfo == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, - SMBStatus.ErrDos); - return; - } - - // Pack the file information into the return data packet - - dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); - } - - // Check if any data was packed, if not then the information level is not supported - - if (dataLen == 0) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos); - outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - } - catch (AccessDeniedException ex) - { - - // Not allowed to access the file/folder - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileNotFoundException ex) - { - - // Requested file does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (PathNotFoundException ex) - { - - // Requested path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - catch (UnsupportedInfoLevelException ex) - { - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidLevel, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - } - - /** - * Process a transact2 query file information (via handle) request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException SMB protocol exception - */ - protected final void procTrans2QueryFile(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id and query path information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int fid = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - - // Get the file details via the file id - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Query File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", stream=" - + netFile.getStreamId() + ", name=" + netFile.getFullName()); - - // Access the shared device disk interface - - try - { - - // Access the disk interface - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the file information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = DataPacker.longwordAlign(outPkt.getByteOffset()); - int dataPos = prmPos + 4; - - // Pack the return parametes, EA error offset - - outPkt.setPosition(prmPos); - outPkt.packWord(0); - - // Create a data buffer using the SMB packet. The response should always fit into a - // single - // reply packet. - - DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos); - - // Check if the virtual filesystem supports streams, and streams are enabled - - boolean streams = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // Check for the file streams information level - - int dataLen = 0; - - if (streams == true - && (infoLevl == FileInfoLevel.PathFileStreamInfo || infoLevl == FileInfoLevel.NTFileStreamInfo)) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) - logger.debug("Get NTFS streams list fid=" + fid + ", name=" + netFile.getFullName()); - - // Get the list of streams from the share driver - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - StreamInfoList streamList = ntfsStreams.getStreamList(m_sess, conn, netFile.getFullName()); - - if (streamList == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - // Pack the file streams information into the return data packet - - dataLen = QueryInfoPacker.packStreamFileInfo(streamList, replyBuf, true); - } - else - { - - // Get the file information - - FileInfo fileInfo = disk.getFileInformation(m_sess, conn, netFile.getFullNameStream()); - - if (fileInfo == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - // Get the current file size from the open file - - fileInfo.setFileSize( netFile.getFileSize()); - - // Pack the file information into the return data packet - - dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true); - } - - // Check if any data was packed, if not then the information level is not supported - - if (dataLen == 0) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, - SMBStatus.ErrSrv); - return; - } - - SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, dataLen, dataPos); - outPkt.setByteCount(replyBuf.getPosition() - outPkt.getByteOffset()); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - } - catch (AccessDeniedException ex) - { - - // Not allowed to access the file/folder - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileNotFoundException ex) - { - - // Requested file does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (PathNotFoundException ex) - { - - // Requested path does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - catch (UnsupportedInfoLevelException ex) - { - - // Requested information level is not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidLevel, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - } - - /** - * Process a transact2 set file information (via handle) request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException SMB protocol exception - */ - protected final void procTrans2SetFile(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file id and information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int fid = paramBuf.getShort(); - int infoLevl = paramBuf.getShort(); - - // Get the file details via the file id - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Set File - level=0x" + Integer.toHexString(infoLevl) + ", fid=" + fid + ", name=" - + netFile.getFullName()); - - // Access the shared device disk interface - - try - { - - // Access the disk interface - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Process the set file information request - - DataBuffer dataBuf = tbuf.getDataBuffer(); - FileInfo finfo = null; - - switch (infoLevl) - { - - // Set basic file information (dates/attributes) - - case FileInfoLevel.SetBasicInfo: - - // Create the file information template - - int setFlags = 0; - finfo = new FileInfo(netFile.getFullName(), 0, -1); - - // Set the creation date/time, if specified - - long timeNow = System.currentTimeMillis(); - - long nttim = dataBuf.getLong(); - boolean hasSetTime = false; - - if (nttim != 0L) - { - if (nttim != -1L) - { - finfo.setCreationDateTime(NTTime.toJavaDate(nttim)); - setFlags += FileInfo.SetCreationDate; - } - hasSetTime = true; - } - - // Set the last access date/time, if specified - - nttim = dataBuf.getLong(); - - if (nttim != 0L) - { - if (nttim != -1L) - { - finfo.setAccessDateTime(NTTime.toJavaDate(nttim)); - setFlags += FileInfo.SetAccessDate; - } - else - { - finfo.setAccessDateTime(timeNow); - setFlags += FileInfo.SetAccessDate; - } - hasSetTime = true; - } - - // Set the last write date/time, if specified - - nttim = dataBuf.getLong(); - - if (nttim > 0L) - { - if (nttim != -1L) - { - finfo.setModifyDateTime(NTTime.toJavaDate(nttim)); - setFlags += FileInfo.SetModifyDate; - } - else - { - finfo.setModifyDateTime(timeNow); - setFlags += FileInfo.SetModifyDate; - } - hasSetTime = true; - } - - // Set the modify date/time, if specified - - nttim = dataBuf.getLong(); - - if (nttim > 0L) - { - if (nttim != -1L) - { - finfo.setChangeDateTime(NTTime.toJavaDate(nttim)); - setFlags += FileInfo.SetChangeDate; - } - hasSetTime = true; - } - - // Set the attributes - - int attr = dataBuf.getInt(); - int unknown = dataBuf.getInt(); - - if (hasSetTime == false && unknown == 0) - { - finfo.setFileAttributes(attr); - setFlags += FileInfo.SetAttributes; - } - - // Set the file information for the specified file/directory - - finfo.setFileInformationFlags(setFlags); - disk.setFileInformation(m_sess, conn, netFile.getFullName(), finfo); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set Basic Info [" + treeId + "] name=" + netFile.getFullName() + ", attr=0x" - + Integer.toHexString(attr) + ", setTime=" + hasSetTime + ", setFlags=0x" - + Integer.toHexString(setFlags) + ", unknown=" + unknown); - break; - - // Set end of file position for a file - - case FileInfoLevel.SetEndOfFileInfo: - - // Get the new end of file position - - long eofPos = dataBuf.getLong(); - - // Set the new end of file position - - disk.truncateFile(m_sess, conn, netFile, eofPos); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set end of file position fid=" + fid + ", eof=" + eofPos); - break; - - // Set the allocation size for a file - - case FileInfoLevel.SetAllocationInfo: - - // Get the new end of file position - - long allocSize = dataBuf.getLong(); - - // Set the new end of file position - - disk.truncateFile(m_sess, conn, netFile, allocSize); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set allocation size fid=" + fid + ", allocSize=" + allocSize); - break; - - // Rename a stream - - case FileInfoLevel.NTFileRenameInfo: - - // Check if the virtual filesystem supports streams, and streams are enabled - - boolean streams = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if NTFS streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // If streams are not supported or are not enabled then return an error status - - if (streams == false) - { - - // Return a not supported error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotSupported, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Get the overwrite flag - - boolean overwrite = dataBuf.getByte() == 1 ? true : false; - dataBuf.skipBytes(3); - - int rootFid = dataBuf.getInt(); - int nameLen = dataBuf.getInt(); - String newName = dataBuf.getString(nameLen, true); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set rename fid=" + fid + ", newName=" + newName + ", overwrite=" + overwrite - + ", rootFID=" + rootFid); - - // Check if the new path contains a directory, only rename of a stream on the same - // file is supported - - if (newName.indexOf(FileName.DOS_SEPERATOR_STR) != -1) - { - - // Return a not supported error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotSupported, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_STREAMS)) - logger.debug("Rename stream fid=" + fid + ", name=" + netFile.getFullNameStream() + ", newName=" - + newName + ", overwrite=" + overwrite); - - // Rename the stream - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - ntfsStreams.renameStream(m_sess, conn, netFile.getFullNameStream(), newName, overwrite); - break; - - // Mark or unmark a file/directory for delete - - case FileInfoLevel.SetDispositionInfo: - case FileInfoLevel.NTFileDispositionInfo: - - // Get the delete flag - - int flag = dataBuf.getByte(); - boolean delFlag = flag == 1 ? true : false; - - // Call the filesystem driver set file information to see if the file can be marked - // for - // delete. - - FileInfo delInfo = new FileInfo(); - delInfo.setDeleteOnClose(delFlag); - delInfo.setFileInformationFlags(FileInfo.SetDeleteOnClose); - - disk.setFileInformation(m_sess, conn, netFile.getFullName(), delInfo); - - // Mark/unmark the file/directory for deletion - - netFile.setDeleteOnClose(delFlag); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set file disposition fid=" + fid + ", name=" + netFile.getName() + ", delete=" - + delFlag); - break; - } - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the return information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = outPkt.getByteOffset(); - - // Longword align the parameters, return an unknown word parameter - // - // Note: Make sure the data offset is on a longword boundary, NT has problems if this is - // not done - - prmPos = DataPacker.longwordAlign(prmPos); - DataPacker.putIntelShort(0, buf, prmPos); - - SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, 0, prmPos + 4); - outPkt.setByteCount((prmPos - outPkt.getByteOffset()) + 4); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - if (diskCtx.hasChangeHandler() && netFile.getFullName() != null) - { - - // Get the change handler - - NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); - - // Check for file attributes and last write time changes - - if (finfo != null) - { - - // File attributes changed - - if (finfo.hasSetFlag(FileInfo.SetAttributes)) - changeHandler.notifyAttributesChanged(netFile.getFullName(), netFile.isDirectory()); - - // Last write time changed - - if (finfo.hasSetFlag(FileInfo.SetModifyDate)) - changeHandler.notifyLastWriteTimeChanged(netFile.getFullName(), netFile.isDirectory()); - } - else if (infoLevl == FileInfoLevel.SetAllocationInfo || infoLevl == FileInfoLevel.SetEndOfFileInfo) - { - - // File size changed - - changeHandler.notifyFileSizeChanged(netFile.getFullName()); - } - } - } - catch (FileNotFoundException ex) - { - - // Requested file does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to change file attributes/settings - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (DiskFullException ex) - { - - // Disk is full - - m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - } - - /** - * Process a transact2 set path information request. - * - * @param tbuf Transaction request details - * @param outPkt SMBSrvPacket - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException SMB protocol exception - */ - protected final void procTrans2SetPath(SrvTransactBuffer tbuf, SMBSrvPacket outPkt) throws java.io.IOException, - SMBSrvException - { - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = m_smbPkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the path and information level - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevl = paramBuf.getShort(); - paramBuf.skipBytes(4); - - String path = paramBuf.getString(tbuf.isUnicode()); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug("Set Path - path=" + path + ", level=0x" + Integer.toHexString(infoLevl)); - - // Check if the file name is valid - - if ( isValidPath( path) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the shared device disk interface - - try - { - - // Access the disk interface - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Process the set file information request - - DataBuffer dataBuf = tbuf.getDataBuffer(); - FileInfo finfo = null; - - switch (infoLevl) - { - - // Set standard file information (dates/attributes) - - case FileInfoLevel.SetStandard: - - // Create the file information template - - int setFlags = 0; - finfo = new FileInfo(path, 0, -1); - - // Set the creation date/time, if specified - - int smbDate = dataBuf.getShort(); - int smbTime = dataBuf.getShort(); - - boolean hasSetTime = false; - - if (smbDate != 0 && smbTime != 0) - { - finfo.setCreationDateTime(new SMBDate(smbDate, smbTime).getTime()); - setFlags += FileInfo.SetCreationDate; - hasSetTime = true; - } - - // Set the last access date/time, if specified - - smbDate = dataBuf.getShort(); - smbTime = dataBuf.getShort(); - - if (smbDate != 0 && smbTime != 0) - { - finfo.setAccessDateTime(new SMBDate(smbDate, smbTime).getTime()); - setFlags += FileInfo.SetAccessDate; - hasSetTime = true; - } - - // Set the last write date/time, if specified - - smbDate = dataBuf.getShort(); - smbTime = dataBuf.getShort(); - - if (smbDate != 0 && smbTime != 0) - { - finfo.setModifyDateTime(new SMBDate(smbDate, smbTime).getTime()); - setFlags += FileInfo.SetModifyDate; - hasSetTime = true; - } - - // Set the file size/allocation size - - int fileSize = dataBuf.getInt(); - if (fileSize != 0) - { - finfo.setFileSize(fileSize); - setFlags += FileInfo.SetFileSize; - } - - fileSize = dataBuf.getInt(); - if (fileSize != 0) - { - finfo.setAllocationSize(fileSize); - setFlags += FileInfo.SetAllocationSize; - } - - // Set the attributes - - int attr = dataBuf.getInt(); - int eaListLen = dataBuf.getInt(); - - if (hasSetTime == false && eaListLen == 0) - { - finfo.setFileAttributes(attr); - setFlags += FileInfo.SetAttributes; - } - - // Set the file information for the specified file/directory - - finfo.setFileInformationFlags(setFlags); - disk.setFileInformation(m_sess, conn, path, finfo); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO)) - logger.debug(" Set Standard Info [" + treeId + "] name=" + path + ", attr=0x" - + Integer.toHexString(attr) + ", setTime=" + hasSetTime + ", setFlags=0x" - + Integer.toHexString(setFlags) + ", eaListLen=" + eaListLen); - break; - } - - // Set the return parameter count, so that the data area position can be calculated. - - outPkt.setParameterCount(10); - - // Pack the return information into the data area of the transaction reply - - byte[] buf = outPkt.getBuffer(); - int prmPos = outPkt.getByteOffset(); - - // Longword align the parameters, return an unknown word parameter - // - // Note: Make sure the data offset is on a longword boundary, NT has problems if this is - // not done - - prmPos = DataPacker.longwordAlign(prmPos); - DataPacker.putIntelShort(0, buf, prmPos); - - SMBSrvTransPacket.initTransactReply(outPkt, 2, prmPos, 0, prmPos + 4); - outPkt.setByteCount((prmPos - outPkt.getByteOffset()) + 4); - - // Send the transact reply - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - if (diskCtx.hasChangeHandler() && path != null) - { - - // Get the change handler - - NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); - - // Check for file attributes and last write time changes - - if (finfo != null) - { - - // Check if the path refers to a file or directory - - int fileSts = disk.fileExists(m_sess, conn, path); - - // File attributes changed - - if (finfo.hasSetFlag(FileInfo.SetAttributes)) - changeHandler.notifyAttributesChanged(path, fileSts == FileStatus.DirectoryExists ? true - : false); - - // Last write time changed - - if (finfo.hasSetFlag(FileInfo.SetModifyDate)) - changeHandler.notifyLastWriteTimeChanged(path, fileSts == FileStatus.DirectoryExists ? true - : false); - } - } - } - catch (FileNotFoundException ex) - { - - // Requested file does not exist - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Not allowed to change file attributes/settings - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (DiskFullException ex) - { - - // Disk is full - - m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - } - - /** - * Process the file write request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procWriteAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid write andX request - - if (m_smbPkt.checkPacketIsValid(12, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Extract the write file parameters - - int fid = m_smbPkt.getParameter(2); - long offset = (long) (((long) m_smbPkt.getParameterLong(3)) & 0xFFFFFFFFL); // bottom 32bits - // of file - // offset - int dataPos = m_smbPkt.getParameter(11) + RFCNetBIOSProtocol.HEADER_LEN; - - int dataLen = m_smbPkt.getParameter(10); - int dataLenHigh = 0; - - if (m_smbPkt.getReceivedLength() > 0xFFFF) - dataLenHigh = m_smbPkt.getParameter(9) & 0x0001; - - if (dataLenHigh > 0) - dataLen += (dataLenHigh << 16); - - // Check for the NT format request that has the top 32bits of the file offset - - if (m_smbPkt.getParameterCount() == 14) - { - long topOff = (long) (((long) m_smbPkt.getParameterLong(12)) & 0xFFFFFFFFL); - offset += topOff << 32; - } - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write AndX [" + netFile.getFileId() + "] : Size=" + dataLen + " ,Pos=" + offset); - - // Write data to the file - - byte[] buf = m_smbPkt.getBuffer(); - int wrtlen = 0; - - // Access the disk interface and write to the file - - try - { - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface(); - - // Write to the file - - wrtlen = disk.writeFile(m_sess, conn, netFile, buf, dataPos, dataLen, offset); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Not allowed to write to the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (LockConflictException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_LOCK)) - logger.debug("Write Lock Error [" + netFile.getFileId() + "] : Size=" + dataLen + " ,Pos=" + offset); - - // File is locked - - m_sess.sendErrorResponseSMB(SMBStatus.NTLockConflict, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (DiskFullException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("Write Quota Error [" + netFile.getFileId() + "] Disk full : Size=" + dataLen + " ,Pos=" - + offset); - - // Disk is full - - m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO)) - logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString()); - - // Failed to write the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTDiskFull, SMBStatus.HRDWriteFault, SMBStatus.ErrHrd); - return; - } - - // Return the count of bytes actually written - - outPkt.setParameterCount(6); - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); // AndX offset - outPkt.setParameter(2, wrtlen); - outPkt.setParameter(3, 0xFFFF); - - if (dataLenHigh > 0) - { - outPkt.setParameter(4, dataLen >> 16); - outPkt.setParameter(5, 0); - } - else - { - outPkt.setParameterLong(4, 0); - } - - outPkt.setByteCount(0); - outPkt.setParameter(1, outPkt.getLength()); - - // Send the write response - - m_sess.sendResponseSMB(outPkt); - - // Report file size change notifications every so often - // - // We do not report every write due to the increased overhead of change notifications - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - - if (netFile.getWriteCount() % FileSizeChangeRate == 0 && diskCtx.hasChangeHandler() - && netFile.getFullName() != null) - { - - // Get the change handler - - NotifyChangeHandler changeHandler = diskCtx.getChangeHandler(); - - // File size changed - - changeHandler.notifyFileSizeChanged(netFile.getFullName()); - } - } - - /** - * Process the file create/open request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procNTCreateAndX(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid NT create andX request - - if (m_smbPkt.checkPacketIsValid(24, 1) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is to the IPC$ remote admin named pipe pass the request to the IPC - // handler. If the device is - // not a disk type device then return an error. - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - - // Use the IPC$ handler to process the request - - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - else if (conn.getSharedDevice().getType() != ShareType.DISK) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Extract the NT create andX parameters - - NTParameterPacker prms = new NTParameterPacker(m_smbPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 5); - - int nameLen = prms.unpackWord(); - int flags = prms.unpackInt(); - int rootFID = prms.unpackInt(); - int accessMask = prms.unpackInt(); - long allocSize = prms.unpackLong(); - int attrib = prms.unpackInt(); - int shrAccess = prms.unpackInt(); - int createDisp = prms.unpackInt(); - int createOptn = prms.unpackInt(); - int impersonLev = prms.unpackInt(); - int secFlags = prms.unpackByte(); - - // Extract the filename string - - String fileName = DataPacker.getUnicodeString(m_smbPkt.getBuffer(), DataPacker.wordAlign(m_smbPkt - .getByteOffset()), nameLen / 2); - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = null; - try - { - - // Get the disk interface for the share - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name contains a file stream name. If the disk interface does not - // implement the optional NTFS - // streams interface then return an error status, not supported. - - if ( FileName.containsStreamName(fileName)) - { - - // Check if the driver implements the NTFS streams interface and it is enabled - - boolean streams = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // Check if streams are enabled/available - - if (streams == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - } - - // Create the file open parameters to be passed to the disk interface - - FileOpenParams params = new FileOpenParams(fileName, createDisp, accessMask, attrib, shrAccess, allocSize, - createOptn, rootFID, impersonLev, secFlags); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("NT Create AndX [" + m_smbPkt.getTreeId() + "] params=" + params); - - // Check if the file name is valid - - if ( isValidPath( params.getPath()) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameInvalid, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Access the disk interface and open the requested file - - int fid; - NetworkFile netFile = null; - int respAction = 0; - - try - { - - // Check if the requested file already exists - - int fileSts = disk.fileExists(m_sess, conn, fileName); - - if (fileSts == FileStatus.NotExist) - { - - // Check if the file should be created if it does not exist - - if (createDisp == FileAction.NTCreate || createDisp == FileAction.NTOpenIf - || createDisp == FileAction.NTOverwriteIf || createDisp == FileAction.NTSupersede) - { - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, - SMBStatus.ErrDos); - return; - } - - // Check if a new file or directory should be created - - if ((createOptn & WinNT.CreateDirectory) == 0) - { - - // Create a new file - - netFile = disk.createFile(m_sess, conn, params); - } - else - { - - // Create a new directory and open it - - disk.createDirectory(m_sess, conn, params); - netFile = disk.openFile(m_sess, conn, params); - } - - // Check if the delete on close option is set - - if (netFile != null && (createOptn & WinNT.CreateDeleteOnClose) != 0) - netFile.setDeleteOnClose(true); - - // Indicate that the file did not exist and was created - - respAction = FileAction.FileCreated; - } - else - { - - // Check if the path is a directory - - if (fileSts == FileStatus.DirectoryExists) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - else - { - - // Return a file not found error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, - SMBStatus.ErrDos); - return; - } - } - } - else if (createDisp == FileAction.NTCreate) - { - - // Check for a file or directory - - if (fileSts == FileStatus.FileExists || fileSts == FileStatus.DirectoryExists) - { - - // Return a file exists error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - else - { - - // Return an access denied exception - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - } - else - { - - // Open the requested file/directory - - netFile = disk.openFile(m_sess, conn, params); - - // Check if the file should be truncated - - if (createDisp == FileAction.NTSupersede || createDisp == FileAction.NTOverwriteIf) - { - - // Truncate the file - - disk.truncateFile(m_sess, conn, netFile, 0L); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug(" [" + m_smbPkt.getTreeId() + "] name=" + fileName + " truncated"); - } - - // Set the file action response - - respAction = FileAction.FileExisted; - } - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.NTTooManyOpenFiles, SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileExistsException ex) - { - - // File/directory already exists - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, - SMBStatus.ErrDos); - return; - } - catch (FileOfflineException ex) - { - - // File data is unavailable - - m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the NT create andX response - - outPkt.setParameterCount( 34); - - outPkt.setAndXCommand(0xFF); - outPkt.setParameter(1, 0); // AndX offset - - prms.reset(outPkt.getBuffer(), SMBSrvPacket.PARAMWORDS + 4); - - // Fake the oplock for certain file types - - boolean fakeOpLocks = FakeOpLocks; - String fname = params.getPath().toUpperCase(); - - if ( fname.endsWith( ".URL")){ - - // Fake the oplock - - fakeOpLocks = true; - } - - // Check if oplocks should be faked - - if (fakeOpLocks == true) - { - - // If an oplock was requested indicate it was granted, for now - - if ((flags & WinNT.RequestBatchOplock) != 0) - { - - // Batch oplock granted - - prms.packByte(2); - } - else if ((flags & WinNT.RequestOplock) != 0) - { - - // Exclusive oplock granted - - prms.packByte(1); - } - else - { - - // No oplock granted - - prms.packByte(0); - } - } - else - prms.packByte(0); - - // Pack the file id - - prms.packWord(fid); - prms.packInt(respAction); - - // Pack the file/directory dates - - if (netFile.hasCreationDate()) - prms.packLong(NTTime.toNTTime(netFile.getCreationDate())); - else - prms.packLong(0); - - if ( netFile.hasAccessDate()) - prms.packLong(NTTime.toNTTime(netFile.getAccessDate())); - else - prms.packLong(0); - - if (netFile.hasModifyDate()) - { - long modDate = NTTime.toNTTime(netFile.getModifyDate()); - prms.packLong(modDate); - prms.packLong(modDate); - } - else - { - prms.packLong(0); // Last write time - prms.packLong(0); // Change time - } - - prms.packInt(netFile.getFileAttributes()); - - // Pack the file size/allocation size - - long fileSize = netFile.getFileSize(); - if (fileSize > 0L) - fileSize = (fileSize + 512L) & 0xFFFFFFFFFFFFFE00L; - - prms.packLong(fileSize); // Allocation size - prms.packLong(netFile.getFileSize()); // End of file - prms.packWord(0); // File type - disk file - prms.packWord((flags & WinNT.ExtendedResponse) != 0 ? 7 : 0); // Device state - prms.packByte(netFile.isDirectory() ? 1 : 0); - - prms.packWord(0); // byte count = 0 - - // Set the AndX offset - - int endPos = prms.getPosition(); - outPkt.setParameter(1, endPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Check if there is a chained request - - if (m_smbPkt.hasAndXCommand()) - { - - // Process the chained requests - - endPos = procAndXCommands(outPkt, endPos, netFile); - } - - // Send the response packet - - m_sess.sendResponseSMB(outPkt, endPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler() && respAction == FileAction.FileCreated) - { - - // Check if a file or directory has been created - - if (netFile.isDirectory()) - diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, fileName); - else - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName); - } - } - - /** - * Process the cancel request. - * - * @param outPkt SMBSrvPacket - */ - protected final void procNTCancel(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that the received packet looks like a valid NT cancel request - - if (m_smbPkt.checkPacketIsValid(0, 0) == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the tree connection details - - TreeConnection conn = m_sess.findTreeConnection(m_smbPkt); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Find the matching notify request and remove it - - NotifyRequest req = m_sess.findNotifyRequest(m_smbPkt.getMultiplexId(), m_smbPkt.getTreeId(), m_smbPkt - .getUserId(), m_smbPkt.getProcessId()); - if (req != null) - { - - // Remove the request - - m_sess.removeNotifyRequest(req); - - // Return a cancelled status - - m_smbPkt.setParameterCount(0); - m_smbPkt.setByteCount(0); - - // Enable the long error status flag - - if (m_smbPkt.isLongErrorCode() == false) - m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE); - - // Set the NT status code - - m_smbPkt.setLongErrorCode(SMBStatus.NTCancelled); - - // Set the Unicode strings flag - - if (m_smbPkt.isUnicode() == false) - m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_UNICODE); - - // Return the error response to the client - - m_sess.sendResponseSMB(m_smbPkt); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) - { - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - logger.debug("NT Cancel notify mid=" + req.getMultiplexId() + ", dir=" + req.getWatchPath() - + ", queue=" + diskCtx.getChangeHandler().getRequestQueueSize()); - } - } - else - { - - // Nothing to cancel - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - } - } - - /** - * Process an NT transaction - * - * @param outPkt SMBSrvPacket - */ - protected final void procNTTransaction(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(19, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Check if the transaction request is for the IPC$ pipe - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Create an NT transaction using the received packet - - NTTransPacket ntTrans = new NTTransPacket(m_smbPkt.getBuffer()); - int subCmd = ntTrans.getNTFunction(); - - // Check for a notfy change request, this needs special processing - - if (subCmd == PacketType.NTTransNotifyChange) - { - - // Handle the notify change setup request - - procNTTransactNotifyChange(ntTrans, outPkt); - return; - } - - // Create a transact buffer to hold the transaction parameter block and data block - - SrvTransactBuffer transBuf = null; - - if (ntTrans.getTotalParameterCount() == ntTrans.getParameterBlockCount() - && ntTrans.getTotalDataCount() == ntTrans.getDataBlockCount()) - { - - // Create a transact buffer using the packet buffer, the entire request is contained in - // a single - // packet - - transBuf = new SrvTransactBuffer(ntTrans); - } - else - { - - // Create a transact buffer to hold the multiple transact request parameter/data blocks - - transBuf = new SrvTransactBuffer(ntTrans.getSetupCount(), ntTrans.getTotalParameterCount(), ntTrans - .getTotalDataCount()); - transBuf.setType(ntTrans.getCommand()); - transBuf.setFunction(subCmd); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] transbuf=" + transBuf); - - // Append the setup, parameter and data blocks to the transaction data - - byte[] buf = ntTrans.getBuffer(); - int cnt = ntTrans.getSetupCount(); - - if (cnt > 0) - transBuf.appendSetup(buf, ntTrans.getSetupOffset(), cnt * 2); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] pcnt=" + ntTrans.getNTParameter(4) + ", offset=" - + ntTrans.getNTParameter(5)); - - cnt = ntTrans.getParameterBlockCount(); - - if (cnt > 0) - transBuf.appendParameter(buf, ntTrans.getParameterBlockOffset(), cnt); - - cnt = ntTrans.getDataBlockCount(); - if (cnt > 0) - transBuf.appendData(buf, ntTrans.getDataBlockOffset(), cnt); - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction [" + m_smbPkt.getTreeId() + "] cmd=0x" + Integer.toHexString(subCmd) + ", multiPkt=" - + transBuf.isMultiPacket()); - - // Check for a multi-packet transaction, for a multi-packet transaction we just acknowledge - // the receive with - // an empty response SMB - - if (transBuf.isMultiPacket()) - { - - // Save the partial transaction data - - vc.setTransaction(transBuf); - - // Send an intermediate acknowedgement response - - m_sess.sendSuccessResponseSMB(); - return; - } - - // Process the transaction buffer - - processNTTransactionBuffer(transBuf, ntTrans); - } - - /** - * Process an NT transaction secondary packet - * - * @param outPkt SMBSrvPacket - */ - protected final void procNTTransactionSecondary(SMBSrvPacket outPkt) throws java.io.IOException, SMBSrvException - { - - // Check that we received enough parameters for a transact2 request - - if (m_smbPkt.checkPacketIsValid(18, 0) == false) - { - - // Not enough parameters for a valid transact2 request - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree id from the received packet and validate that it is a valid - // connection id. - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Check if the transaction request is for the IPC$ pipe - - if (conn.getSharedDevice().getType() == ShareType.ADMINPIPE) - { - IPCHandler.processIPCRequest(m_sess, outPkt); - return; - } - - // Check if there is an active transaction, and it is an NT transaction - - if (vc.hasTransaction() == false || vc.getTransaction().isType() != PacketType.NTTransact) - { - - // No NT transaction to continue, return an error - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Create an NT transaction using the received packet - - NTTransPacket ntTrans = new NTTransPacket(m_smbPkt.getBuffer()); - byte[] buf = ntTrans.getBuffer(); - SrvTransactBuffer transBuf = vc.getTransaction(); - - // Append the parameter data to the transaction buffer, if any - - int plen = ntTrans.getParameterBlockCount(); - if (plen > 0) - { - - // Append the data to the parameter buffer - - DataBuffer paramBuf = transBuf.getParameterBuffer(); - paramBuf.appendData(buf, ntTrans.getParameterBlockOffset(), plen); - } - - // Append the data block to the transaction buffer, if any - - int dlen = ntTrans.getDataBlockCount(); - if (dlen > 0) - { - - // Append the data to the data buffer - - DataBuffer dataBuf = transBuf.getDataBuffer(); - dataBuf.appendData(buf, ntTrans.getDataBlockOffset(), dlen); - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction Secondary [" + m_smbPkt.getTreeId() + "] paramLen=" + plen + ", dataLen=" + dlen); - - // Check if the transaction has been received or there are more sections to be received - - int totParam = ntTrans.getTotalParameterCount(); - int totData = ntTrans.getTotalDataCount(); - - int paramDisp = ntTrans.getParameterBlockDisplacement(); - int dataDisp = ntTrans.getDataBlockDisplacement(); - - if ((paramDisp + plen) == totParam && (dataDisp + dlen) == totData) - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT Transaction complete, processing ..."); - - // Clear the in progress transaction - - vc.setTransaction(null); - - // Process the transaction - - processNTTransactionBuffer(transBuf, ntTrans); - } - - // No response is sent for a transaction secondary - } - - /** - * Process an NT transaction buffer - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException If a network error occurs - * @exception SMBSrvException If an SMB error occurs - */ - private final void processNTTransactionBuffer(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, - SMBSrvException - { - - // Process the NT transaction buffer - - switch (tbuf.getFunction()) - { - - // Create file/directory - - case PacketType.NTTransCreate: - procNTTransactCreate(tbuf, outPkt); - break; - - // I/O control - - case PacketType.NTTransIOCtl: - procNTTransactIOCtl(tbuf, outPkt); - break; - - // Query security descriptor - - case PacketType.NTTransQuerySecurityDesc: - procNTTransactQuerySecurityDesc(tbuf, outPkt); - break; - - // Set security descriptor - - case PacketType.NTTransSetSecurityDesc: - procNTTransactSetSecurityDesc(tbuf, outPkt); - break; - - // Rename file/directory via handle - - case PacketType.NTTransRename: - procNTTransactRename(tbuf, outPkt); - break; - - // Get user quota - - case PacketType.NTTransGetUserQuota: - - // Return a not implemented error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - break; - - // Set user quota - - case PacketType.NTTransSetUserQuota: - - // Return a not implemented error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - break; - - // Unknown NT transaction command - - default: - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - break; - } - } - - /** - * Process an NT create file/directory transaction - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactCreate(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, - SMBSrvException - { - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT TransactCreate"); - - // Check that the received packet looks like a valid NT create transaction - - if (tbuf.hasParameterBuffer() && tbuf.getParameterBuffer().getLength() < 52) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // If the connection is not a disk share then return an error. - - if (conn.getSharedDevice().getType() != ShareType.DISK) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Extract the file create parameters - - DataBuffer tparams = tbuf.getParameterBuffer(); - - int flags = tparams.getInt(); - int rootFID = tparams.getInt(); - int accessMask = tparams.getInt(); - long allocSize = tparams.getLong(); - int attrib = tparams.getInt(); - int shrAccess = tparams.getInt(); - int createDisp = tparams.getInt(); - int createOptn = tparams.getInt(); - int sdLen = tparams.getInt(); - int eaLen = tparams.getInt(); - int nameLen = tparams.getInt(); - int impersonLev = tparams.getInt(); - int secFlags = tparams.getByte(); - - // Extract the filename string - - tparams.wordAlign(); - String fileName = tparams.getString(nameLen, true); - - if (fileName == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = null; - try - { - - // Get the disk interface for the share - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - } - catch (InvalidDeviceInterfaceException ex) - { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the file name contains a file stream name. If the disk interface does not - // implement the optional NTFS - // streams interface then return an error status, not supported. - - if (fileName.indexOf(FileOpenParams.StreamSeparator) != -1) - { - - // Check if the driver implements the NTFS streams interface and it is enabled - - boolean streams = false; - - if (disk instanceof NTFSStreamsInterface) - { - - // Check if streams are enabled - - NTFSStreamsInterface ntfsStreams = (NTFSStreamsInterface) disk; - streams = ntfsStreams.hasStreamsEnabled(m_sess, conn); - } - - // Check if streams are enabled/available - - if (streams == false) - { - - // Return a file not found error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - } - - // Create the file open parameters to be passed to the disk interface - - FileOpenParams params = new FileOpenParams(fileName, createDisp, accessMask, attrib, shrAccess, allocSize, - createOptn, rootFID, impersonLev, secFlags); - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug("NT TransactCreate [" + m_smbPkt.getTreeId() + "] params=" + params + " secDescLen=" + sdLen - + ", extAttribLen=" + eaLen); - - // Access the disk interface and open/create the requested file - - int fid; - NetworkFile netFile = null; - int respAction = 0; - - try - { - - // Check if the requested file already exists - - int fileSts = disk.fileExists(m_sess, conn, fileName); - - if (fileSts == FileStatus.NotExist) - { - - // Check if the file should be created if it does not exist - - if (createDisp == FileAction.NTCreate || createDisp == FileAction.NTOpenIf - || createDisp == FileAction.NTOverwriteIf || createDisp == FileAction.NTSupersede) - { - - // Check if a new file or directory should be created - - if ((createOptn & WinNT.CreateDirectory) == 0) - { - - // Create a new file - - netFile = disk.createFile(m_sess, conn, params); - } - else - { - - // Create a new directory and open it - - disk.createDirectory(m_sess, conn, params); - netFile = disk.openFile(m_sess, conn, params); - } - - // Indicate that the file did not exist and was created - - respAction = FileAction.FileCreated; - } - else - { - - // Check if the path is a directory - - if (fileSts == FileStatus.DirectoryExists) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - else - { - - // Return a file not found error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, - SMBStatus.ErrDos); - return; - } - } - } - else if (createDisp == FileAction.NTCreate) - { - - // Check for a file or directory - - if (fileSts == FileStatus.FileExists || fileSts == FileStatus.DirectoryExists) - { - - // Return a file exists error - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - else - { - - // Return an access denied exception - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - } - else - { - - // Open the requested file/directory - - netFile = disk.openFile(m_sess, conn, params); - - // Check if the file should be truncated - - if (createDisp == FileAction.NTSupersede || createDisp == FileAction.NTOverwriteIf) - { - - // Truncate the file - - disk.truncateFile(m_sess, conn, netFile, 0L); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE)) - logger.debug(" [" + m_smbPkt.getTreeId() + "] name=" + fileName + " truncated"); - } - - // Set the file action response - - respAction = FileAction.FileExisted; - } - - // Add the file to the list of open files for this tree connection - - fid = conn.addFile(netFile, getSession()); - } - catch (TooManyFilesException ex) - { - - // Too many files are open on this connection, cannot open any more files. - - m_sess.sendErrorResponseSMB(SMBStatus.NTTooManyOpenFiles, SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos); - return; - } - catch (AccessDeniedException ex) - { - - // Return an access denied error - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - catch (FileExistsException ex) - { - - // File/directory already exists - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists, - SMBStatus.ErrDos); - return; - } - catch (FileSharingException ex) - { - - // Return a sharing violation error - - m_sess.sendErrorResponseSMB(SMBStatus.NTSharingViolation, SMBStatus.DOSFileSharingConflict, - SMBStatus.ErrDos); - return; - } - catch (FileOfflineException ex) - { - - // File data is unavailable - - m_sess.sendErrorResponseSMB(SMBStatus.NTFileOffline, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd); - return; - } - catch (java.io.IOException ex) - { - - // Failed to open the file - - m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos); - return; - } - - // Build the NT transaction create response - - DataBuffer prms = new DataBuffer(128); - - // If an oplock was requested indicate it was granted, for now - - if ((flags & WinNT.RequestBatchOplock) != 0) - { - - // Batch oplock granted - - prms.putByte(2); - } - else if ((flags & WinNT.RequestOplock) != 0) - { - - // Exclusive oplock granted - - prms.putByte(1); - } - else - { - - // No oplock granted - - prms.putByte(0); - } - prms.putByte(0); // alignment - - // Pack the file id - - prms.putShort(fid); - prms.putInt(respAction); - - // EA error offset - - prms.putInt(0); - - // Pack the file/directory dates - - if (netFile.hasCreationDate()) - prms.putLong(NTTime.toNTTime(netFile.getCreationDate())); - else - prms.putLong(0); - - if (netFile.hasModifyDate()) - { - long modDate = NTTime.toNTTime(netFile.getModifyDate()); - prms.putLong(modDate); - prms.putLong(modDate); - prms.putLong(modDate); - } - else - { - prms.putLong(0); // Last access time - prms.putLong(0); // Last write time - prms.putLong(0); // Change time - } - - prms.putInt(netFile.getFileAttributes()); - - // Pack the file size/allocation size - - prms.putLong(netFile.getFileSize()); // Allocation size - prms.putLong(netFile.getFileSize()); // End of file - prms.putShort(0); // File type - disk file - prms.putShort(0); // Device state - prms.putByte(netFile.isDirectory() ? 1 : 0); - - // Initialize the transaction response - - outPkt.initTransactReply(prms.getBuffer(), prms.getLength(), null, 0); - - // Send back the response - - m_sess.sendResponseSMB(outPkt); - - // Check if there are any file/directory change notify requests active - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler() && respAction == FileAction.FileCreated) - { - - // Check if a file or directory has been created - - if (netFile.isDirectory()) - diskCtx.getChangeHandler().notifyDirectoryChanged(NotifyChange.ActionAdded, fileName); - else - diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName); - } - } - - /** - * Process an NT I/O control transaction - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactIOCtl(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(m_smbPkt.getTreeId()); - - if (conn == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Unpack the request details - - DataBuffer setupBuf = tbuf.getSetupBuffer(); - - int ctrlCode = setupBuf.getInt(); - int fid = setupBuf.getShort(); - boolean fsctrl = setupBuf.getByte() == 1 ? true : false; - int filter = setupBuf.getByte(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT IOCtl code=" + NTIOCtl.asString(ctrlCode) + ", fid=" + fid + ", fsctrl=" + fsctrl + ", filter=" + filter); - - // Access the disk interface that is associated with the shared device - - DiskInterface disk = null; - try { - - // Get the disk interface for the share - - disk = (DiskInterface) conn.getSharedDevice().getInterface(); - } - catch (InvalidDeviceInterfaceException ex) { - - // Failed to get/initialize the disk interface - - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); - return; - } - - // Check if the disk interface implements the optional IO control interface - - if ( disk instanceof IOCtlInterface) { - - // Access the IO control interface - - IOCtlInterface ioControl = (IOCtlInterface) disk; - - try { - - // Pass the request to the IO control interface for processing - - DataBuffer response = ioControl.processIOControl(m_sess, conn, ctrlCode, fid, tbuf.getDataBuffer(), fsctrl, filter); - - // Pack the response - - if ( response != null) { - - // Pack the response data block - - outPkt.initTransactReply(null, 0, response.getBuffer(), response.getLength(), 1); - outPkt.setSetupParameter(0, response.getLength()); - } - else { - - // Pack an empty response data block - - outPkt.initTransactReply(null, 0, null, 0, 1); - outPkt.setSetupParameter(0, 0); - } - } - catch (IOControlNotImplementedException ex) { - - // Return a not implemented error status - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - return; - } - catch (SMBException ex) { - - // Return the specified SMB status, this should be an NT status code - - m_sess.sendErrorResponseSMB(ex.getErrorCode(), SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - return; - } - - // Send the IOCtl response - - m_sess.sendResponseSMB(outPkt); - } - else { - - // Send back an error, IOctl not supported - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - } - - /** - * Process an NT query security descriptor transaction - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactQuerySecurityDesc(SrvTransactBuffer tbuf, NTTransPacket outPkt) - throws IOException, SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(tbuf.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Unpack the request details - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int fid = paramBuf.getShort(); - int flags = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT QuerySecurityDesc fid=" + fid + ", flags=" + flags); - - // Get the file details - - NetworkFile netFile = conn.findFile(fid); - - if (netFile == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Return an empty security descriptor - - byte[] paramblk = new byte[4]; - DataPacker.putIntelInt(0, paramblk, 0); - - outPkt.initTransactReply(paramblk, paramblk.length, null, 0); - - // Send back the response - - m_sess.sendResponseSMB(outPkt); - } - - /** - * Process an NT set security descriptor transaction - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactSetSecurityDesc(SrvTransactBuffer tbuf, NTTransPacket outPkt) - throws IOException, SMBSrvException - { - - // Unpack the request details - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - TreeConnection conn = vc.findConnection(tbuf.getTreeId()); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Get the file details - - int fid = paramBuf.getShort(); - paramBuf.skipBytes(2); - int flags = paramBuf.getInt(); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT SetSecurityDesc fid=" + fid + ", flags=" + flags); - - // Send back an error, security descriptors not supported - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - } - - /** - * Process an NT change notification transaction - * - * @param ntpkt NTTransPacket - * @param outPkt SMBSrvPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactNotifyChange(NTTransPacket ntpkt, SMBSrvPacket outPkt) throws IOException, - SMBSrvException - { - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = ntpkt.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasReadAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Make sure the tree connection is for a disk device - - if (conn.getContext() == null || conn.getContext() instanceof DiskDeviceContext == false) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Check if the device has change notification enabled - - DiskDeviceContext diskCtx = (DiskDeviceContext) conn.getContext(); - if (diskCtx.hasChangeHandler() == false) - { - - // Return an error status, share does not have change notification enabled - - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Unpack the request details - - ntpkt.resetSetupPointer(); - - int filter = ntpkt.unpackInt(); - int fid = ntpkt.unpackWord(); - boolean watchTree = ntpkt.unpackByte() == 1 ? true : false; - int mid = ntpkt.getMultiplexId(); - - // Get the file details - - NetworkFile dir = conn.findFile(fid); - if (dir == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - return; - } - - // Get the maximum notifications to buffer whilst waiting for the request to be reset after - // a notification - // has been triggered - - int maxQueue = 0; - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) - logger.debug("NT NotifyChange fid=" + fid + ", mid=" + mid + ", filter=0x" + Integer.toHexString(filter) - + ", dir=" + dir.getFullName() + ", maxQueue=" + maxQueue); - - // Check if there is an existing request in the notify list that matches the new request and - // is in a completed - // state. If so then the client is resetting the notify request so reuse the existing - // request. - - NotifyRequest req = m_sess.findNotifyRequest(dir, filter, watchTree); - - if (req != null && req.isCompleted()) - { - - // Reset the existing request with the new multiplex id - - req.setMultiplexId(mid); - req.setCompleted(false); - - // Check if there are any buffered notifications for this session - - if (req.hasBufferedEvents() || req.hasNotifyEnum()) - { - - // Get the buffered events from the request, clear the list from the request - - NotifyChangeEventList bufList = req.getBufferedEventList(); - req.clearBufferedEvents(); - - // Send the buffered events - - diskCtx.getChangeHandler().sendBufferedNotifications(req, bufList); - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) - { - if (bufList == null) - logger.debug(" Sent buffered notifications, req=" + req.toString() + ", Enum"); - else - logger.debug(" Sent buffered notifications, req=" + req.toString() + ", count=" - + bufList.numberOfEvents()); - } - } - else - { - - // DEBUG - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) - logger.debug(" Reset notify request, " + req.toString()); - } - } - else - { - - // Create a change notification request - - req = new NotifyRequest(filter, watchTree, m_sess, dir, mid, ntpkt.getTreeId(), ntpkt.getProcessId(), ntpkt - .getUserId(), maxQueue); - - // Add the request to the pending notify change lists - - m_sess.addNotifyRequest(req, diskCtx); - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_NOTIFY)) - logger.debug(" Added new request, " + req.toString()); - } - - // NOTE: If the change notification request is accepted then no reply is sent to the client. - // A reply will be sent - // asynchronously if the change notification is triggered. - } - - /** - * Process an NT rename via handle transaction - * - * @param tbuf TransactBuffer - * @param outPkt NTTransPacket - * @exception IOException - * @exception SMBSrvException - */ - protected final void procNTTransactRename(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, - SMBSrvException - { - // Unpack the request details - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - // Get the virtual circuit for the request - - VirtualCircuit vc = m_sess.findVirtualCircuit( m_smbPkt.getUserId()); - - if (vc == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Get the tree connection details - - int treeId = tbuf.getTreeId(); - TreeConnection conn = vc.findConnection(treeId); - - if (conn == null) - { - m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); - return; - } - - // Check if the user has the required access permission - - if (conn.hasWriteAccess() == false) - { - - // User does not have the required access rights - - m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos); - return; - } - - // Debug - - if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) - logger.debug("NT TransactRename"); - - // Send back an error, NT rename not supported - - m_sess.sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/NTTransPacket.java b/source/java/org/alfresco/filesys/smb/server/NTTransPacket.java deleted file mode 100644 index 80d9330e5f..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NTTransPacket.java +++ /dev/null @@ -1,733 +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.smb.server; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.util.DataPacker; - -/** - * NT Transaction Packet Class - */ -public class NTTransPacket extends SMBSrvPacket -{ - - // Define the number of standard parameter words/bytes - - private static final int StandardParams = 19; - private static final int ParameterBytes = 36; // 8 x 32bit params + max setup count byte + - // setup count byte + reserved word - - // Standard reply word count - - private static final int ReplyParams = 18; - - // Offset to start of NT parameters from start of packet - - private static final int NTMaxSetupCount = SMBPacket.PARAMWORDS; - private static final int NTParams = SMBPacket.PARAMWORDS + 3; - private static final int NTSetupCount = NTParams + 32; - private static final int NTFunction = NTSetupCount + 1; - - // Default return parameter/data byte counts - - private static final int DefaultReturnParams = 4; - private static final int DefaultReturnData = 1024; - - /** - * Default constructor - */ - public NTTransPacket() - { - super(); - } - - /** - * Class constructor - * - * @param buf byte[] - */ - public NTTransPacket(byte[] buf) - { - super(buf); - } - - /** - * Copy constructor - * - * @param pkt NTTransPacket - */ - public NTTransPacket(NTTransPacket pkt) - { - super(pkt); - } - - /** - * Return the data block size - * - * @return Data block size in bytes - */ - public final int getDataLength() - { - return getNTParameter(6); - } - - /** - * Return the data block offset - * - * @return Data block offset within the SMB packet. - */ - public final int getDataOffset() - { - return getNTParameter(7) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Unpack the parameter block - * - * @return int[] - */ - public final int[] getParameterBlock() - { - - // Get the parameter count and allocate the parameter buffer - - int prmcnt = getParameterBlockCount() / 4; // convert to number of ints - if (prmcnt <= 0) - return null; - int[] prmblk = new int[prmcnt]; - - // Get the offset to the parameter words, add the NetBIOS header length - // to the offset. - - int pos = getParameterBlockOffset(); - - // Unpack the parameter ints - - setBytePointer(pos, getByteCount()); - - for (int idx = 0; idx < prmcnt; idx++) - { - - // Unpack the current parameter value - - prmblk[idx] = unpackInt(); - } - - // Return the parameter block - - return prmblk; - } - - /** - * Return the total parameter count - * - * @return int - */ - public final int getTotalParameterCount() - { - return getNTParameter(0); - } - - /** - * Return the total data count - * - * @return int - */ - public final int getTotalDataCount() - { - return getNTParameter(1); - } - - /** - * Return the maximum parameter block length to be returned - * - * @return int - */ - public final int getMaximumParameterReturn() - { - return getNTParameter(2); - } - - /** - * Return the maximum data block length to be returned - * - * @return int - */ - public final int getMaximumDataReturn() - { - return getNTParameter(3); - } - - /** - * Return the parameter block count - * - * @return int - */ - public final int getParameterBlockCount() - { - return getNTParameter(getCommand() == PacketType.NTTransact ? 4 : 2); - } - - /** - * Return the parameter block offset - * - * @return int - */ - public final int getParameterBlockOffset() - { - return getNTParameter(getCommand() == PacketType.NTTransact ? 5 : 3) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the paramater block displacement - * - * @return int - */ - public final int getParameterBlockDisplacement() - { - return getNTParameter(4); - } - - /** - * Return the data block count - * - * @return int - */ - public final int getDataBlockCount() - { - return getNTParameter(getCommand() == PacketType.NTTransact ? 6 : 5); - } - - /** - * Return the data block offset - * - * @return int - */ - public final int getDataBlockOffset() - { - return getNTParameter(getCommand() == PacketType.NTTransact ? 7 : 6) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the data block displacment - * - * @return int - */ - public final int getDataBlockDisplacement() - { - return getNTParameter(7); - } - - /** - * Get an NT parameter (32bit) - * - * @param idx int - * @return int - */ - protected final int getNTParameter(int idx) - { - int pos = NTParams + (4 * idx); - return DataPacker.getIntelInt(getBuffer(), pos); - } - - /** - * Get the setup parameter count - * - * @return int - */ - public final int getSetupCount() - { - byte[] buf = getBuffer(); - return (int) buf[NTSetupCount] & 0xFF; - } - - /** - * Return the offset to the setup words data - * - * @return int - */ - public final int getSetupOffset() - { - return NTFunction + 2; - } - - /** - * Get the NT transaction function code - * - * @return int - */ - public final int getNTFunction() - { - byte[] buf = getBuffer(); - return DataPacker.getIntelShort(buf, NTFunction); - } - - /** - * Initialize the transact SMB packet - * - * @param func NT transaction function code - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - * @param setupcnt Number of setup parameters - */ - public final void initTransact(int func, byte[] paramblk, int plen, byte[] datablk, int dlen, int setupcnt) - { - initTransact(func, paramblk, plen, datablk, dlen, setupcnt, DefaultReturnParams, DefaultReturnData); - } - - /** - * Initialize the transact SMB packet - * - * @param func NT transaction function code - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - * @param setupcnt Number of setup parameters - * @param maxPrm Maximum parameter bytes to return - * @param maxData Maximum data bytes to return - */ - public final void initTransact(int func, byte[] paramblk, int plen, byte[] datablk, int dlen, int setupcnt, - int maxPrm, int maxData) - { - - // Set the SMB command and parameter count - - setCommand(PacketType.NTTransact); - setParameterCount(StandardParams + setupcnt); - - // Initialize the parameters - - setTotalParameterCount(plen); - setTotalDataCount(dlen); - setMaximumParameterReturn(maxPrm); - setMaximumDataReturn(maxData); - setParameterCount(plen); - setParameterBlockOffset(0); - setDataBlockCount(dlen); - setDataBlockOffset(0); - - setSetupCount(setupcnt); - setNTFunction(func); - - resetBytePointerAlign(); - - // Pack the parameter block - - if (paramblk != null) - { - - // Set the parameter block offset, from the start of the SMB packet - - setParameterBlockOffset(getPosition()); - - // Pack the parameter block - - packBytes(paramblk, plen); - } - - // Pack the data block - - if (datablk != null) - { - - // Align the byte area offset and set the data block offset in the request - - alignBytePointer(); - setDataBlockOffset(getPosition()); - - // Pack the data block - - packBytes(datablk, dlen); - } - - // Set the byte count for the SMB packet - - setByteCount(); - } - - /** - * Initialize the NT transaction reply - * - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - */ - public final void initTransactReply(byte[] paramblk, int plen, byte[] datablk, int dlen) - { - - // Set the parameter count - - setParameterCount(ReplyParams); - setSetupCount(0); - - // Initialize the parameters - - setTotalParameterCount(plen); - setTotalDataCount(dlen); - - setReplyParameterCount(plen); - setReplyParameterOffset(0); - setReplyParameterDisplacement(0); - - setReplyDataCount(dlen); - setDataBlockOffset(0); - setReplyDataDisplacement(0); - - setSetupCount(0); - - resetBytePointerAlign(); - - // Pack the parameter block - - if (paramblk != null) - { - - // Set the parameter block offset, from the start of the SMB packet - - setReplyParameterOffset(getPosition() - 4); - - // Pack the parameter block - - packBytes(paramblk, plen); - } - - // Pack the data block - - if (datablk != null) - { - - // Align the byte area offset and set the data block offset in the request - - alignBytePointer(); - setReplyDataOffset(getPosition() - 4); - - // Pack the data block - - packBytes(datablk, dlen); - } - - // Set the byte count for the SMB packet - - setByteCount(); - } - - /** - * Initialize the NT transaction reply - * - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - * @param setupCnt Number of setup parameter - */ - public final void initTransactReply(byte[] paramblk, int plen, byte[] datablk, int dlen, int setupCnt) - { - - // Set the parameter count, add the setup parameter count - - setParameterCount(ReplyParams + setupCnt); - setSetupCount(setupCnt); - - // Initialize the parameters - - setTotalParameterCount(plen); - setTotalDataCount(dlen); - - setReplyParameterCount(plen); - setReplyParameterOffset(0); - setReplyParameterDisplacement(0); - - setReplyDataCount(dlen); - setDataBlockOffset(0); - setReplyDataDisplacement(0); - - setSetupCount(setupCnt); - - resetBytePointerAlign(); - - // Pack the parameter block - - if (paramblk != null) - { - - // Set the parameter block offset, from the start of the SMB packet - - setReplyParameterOffset(getPosition() - 4); - - // Pack the parameter block - - packBytes(paramblk, plen); - } - - // Pack the data block - - if (datablk != null) - { - - // Align the byte area offset and set the data block offset in the request - - alignBytePointer(); - setReplyDataOffset(getPosition() - 4); - - // Pack the data block - - packBytes(datablk, dlen); - } - - // Set the byte count for the SMB packet - - setByteCount(); - } - - /** - * Set the total parameter count - * - * @param cnt int - */ - public final void setTotalParameterCount(int cnt) - { - setNTParameter(0, cnt); - } - - /** - * Set the total data count - * - * @param cnt int - */ - public final void setTotalDataCount(int cnt) - { - setNTParameter(1, cnt); - } - - /** - * Set the maximum return parameter count - * - * @param cnt int - */ - public final void setMaximumParameterReturn(int cnt) - { - setNTParameter(2, cnt); - } - - /** - * Set the maximum return data count - * - * @param cnt int - */ - public final void setMaximumDataReturn(int cnt) - { - setNTParameter(3, cnt); - } - - /** - * Set the paramater block count - * - * @param disp int - */ - public final void setTransactParameterCount(int cnt) - { - setNTParameter(4, cnt); - } - - /** - * Set the reply parameter byte count - * - * @param cnt int - */ - public final void setReplyParameterCount(int cnt) - { - setNTParameter(2, cnt); - } - - /** - * Set the reply parameter offset - * - * @param off int - */ - public final void setReplyParameterOffset(int off) - { - setNTParameter(3, off); - } - - /** - * Set the reply parameter bytes displacement - * - * @param disp int - */ - public final void setReplyParameterDisplacement(int disp) - { - setNTParameter(4, disp); - } - - /** - * Set the reply data byte count - * - * @param cnt int - */ - public final void setReplyDataCount(int cnt) - { - setNTParameter(5, cnt); - } - - /** - * Set the reply data offset - * - * @param off int - */ - public final void setReplyDataOffset(int off) - { - setNTParameter(6, off); - } - - /** - * Set the reply data bytes displacement - * - * @param disp int - */ - public final void setReplyDataDisplacement(int disp) - { - setNTParameter(7, disp); - } - - /** - * Set the parameter block offset within the packet - * - * @param off int - */ - public final void setParameterBlockOffset(int off) - { - setNTParameter(5, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); - } - - /** - * Set the data block count - * - * @param cnt int - */ - public final void setDataBlockCount(int cnt) - { - setNTParameter(6, cnt); - } - - /** - * Set the data block offset - * - * @param disp int - */ - public final void setDataBlockOffset(int off) - { - setNTParameter(7, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); - } - - /** - * Set an NT parameter (32bit) - * - * @param idx int - * @param val int - */ - public final void setNTParameter(int idx, int val) - { - int pos = NTParams + (4 * idx); - DataPacker.putIntelInt(val, getBuffer(), pos); - } - - /** - * Set the maximum setup parameter count - * - * @param cnt Maximum count of setup paramater words - */ - public final void setMaximumSetupCount(int cnt) - { - byte[] buf = getBuffer(); - buf[NTMaxSetupCount] = (byte) cnt; - } - - /** - * Set the setup parameter count - * - * @param cnt Count of setup paramater words - */ - public final void setSetupCount(int cnt) - { - byte[] buf = getBuffer(); - buf[NTSetupCount] = (byte) cnt; - } - - /** - * Set the specified setup parameter - * - * @param setupIdx Setup parameter index - * @param setupVal Setup parameter value - */ - public final void setSetupParameter(int setupIdx, int setupVal) - { - int pos = NTSetupCount + 1 + (setupIdx * 2); - DataPacker.putIntelShort(setupVal, getBuffer(), pos); - } - - /** - * Set the NT transaction function code - * - * @param func int - */ - public final void setNTFunction(int func) - { - byte[] buf = getBuffer(); - DataPacker.putIntelShort(func, buf, NTFunction); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking setup paramaters items to the - * packet - */ - public final void resetSetupPointer() - { - m_pos = NTFunction + 2; - m_endpos = m_pos; - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking the transaction data block - */ - public final void resetDataBlockPointer() - { - m_pos = getDataBlockOffset(); - m_endpos = m_pos; - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking the transaction paramater block - */ - public final void resetParameterBlockPointer() - { - m_pos = getParameterBlockOffset(); - m_endpos = m_pos; - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/NamedPipeTransaction.java b/source/java/org/alfresco/filesys/smb/server/NamedPipeTransaction.java deleted file mode 100644 index 346238d111..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NamedPipeTransaction.java +++ /dev/null @@ -1,91 +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.smb.server; - -/** - *

- * Contains the named pipe transaction codes. - */ -public class NamedPipeTransaction -{ - - // Transaction sub-commands - - public static final int CallNamedPipe = 0x54; - public static final int WaitNamedPipe = 0x53; - public static final int PeekNmPipe = 0x23; - public static final int QNmPHandState = 0x21; - public static final int SetNmPHandState = 0x01; - public static final int QNmPipeInfo = 0x22; - public static final int TransactNmPipe = 0x26; - public static final int RawReadNmPipe = 0x11; - public static final int RawWriteNmPipe = 0x31; - - /** - * Return the named pipe transaction sub-command as a string - * - * @param subCmd int - * @return String - */ - public final static String getSubCommand(int subCmd) - { - - // Determine the sub-command code - - String ret = ""; - - switch (subCmd) - { - case CallNamedPipe: - ret = "CallNamedPipe"; - break; - case WaitNamedPipe: - ret = "WaitNamedPipe"; - break; - case PeekNmPipe: - ret = "PeekNmPipe"; - break; - case QNmPHandState: - ret = "QNmPHandState"; - break; - case SetNmPHandState: - ret = "SetNmPHandState"; - break; - case QNmPipeInfo: - ret = "QNmPipeInfo"; - break; - case TransactNmPipe: - ret = "TransactNmPipe"; - break; - case RawReadNmPipe: - ret = "RawReadNmPipe"; - break; - case RawWriteNmPipe: - ret = "RawWriteNmPipe"; - break; - } - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/NetBIOSPacketHandler.java b/source/java/org/alfresco/filesys/smb/server/NetBIOSPacketHandler.java deleted file mode 100644 index f53dc212a3..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NetBIOSPacketHandler.java +++ /dev/null @@ -1,185 +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.smb.server; - -import java.io.IOException; -import java.net.Socket; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.util.DataPacker; - -/** - * NetBIOS Protocol Packet Handler Class - */ -public class NetBIOSPacketHandler extends PacketHandler -{ - - /** - * Class constructor - * - * @param sock Socket - * @exception IOException If a network error occurs - */ - public NetBIOSPacketHandler(Socket sock) throws IOException - { - super(sock, SMBSrvPacket.PROTOCOL_NETBIOS, "NetBIOS", "NB"); - } - - /** - * Read a packet from the input stream - * - * @param pkt SMBSrvPacket - * @return int - * @exception IOexception If a network error occurs - */ - public final int readPacket(SMBSrvPacket pkt) throws IOException - { - - // Read the packet header - - byte[] buf = pkt.getBuffer(); - int len = 0; - - while (len < RFCNetBIOSProtocol.HEADER_LEN && len != -1) - len = readPacket(buf, len, RFCNetBIOSProtocol.HEADER_LEN - len); - - // Check if the connection has been closed, read length equals -1 - - if (len == -1) - return len; - - // Check if we received a valid NetBIOS header - - if (len < RFCNetBIOSProtocol.HEADER_LEN) - throw new IOException("Invalid NetBIOS header, len=" + len); - - // Get the packet type from the header - - int typ = (int) (buf[0] & 0xFF); - int flags = (int) buf[1]; - int dlen = (int) DataPacker.getShort(buf, 2); - - if ((flags & 0x01) != 0) - dlen += 0x10000; - - // Check for a session keep alive type message - - if (typ == RFCNetBIOSProtocol.SESSION_KEEPALIVE) - return 0; - - // Check if the packet buffer is large enough to hold the data + header - - if (buf.length < (dlen + RFCNetBIOSProtocol.HEADER_LEN)) - { - - // Allocate a new buffer to hold the data and copy the existing header - - byte[] newBuf = new byte[dlen + RFCNetBIOSProtocol.HEADER_LEN]; - for (int i = 0; i < 4; i++) - newBuf[i] = buf[i]; - - // Attach the new buffer to the SMB packet - - pkt.setBuffer(newBuf); - buf = newBuf; - } - - // Read the data part of the packet into the users buffer, this may take - // several reads - - int offset = RFCNetBIOSProtocol.HEADER_LEN; - int totlen = offset; - - while (dlen > 0) - { - - // Read the data - - len = readPacket(buf, offset, dlen); - - // Check if the connection has been closed - - if (len == -1) - return -1; - - // Update the received length and remaining data length - - totlen += len; - dlen -= len; - - // Update the user buffer offset as more reads will be required - // to complete the data read - - offset += len; - - } // end while reading data - - // Return the received packet length - - return totlen; - } - - /** - * Send a packet to the output stream - * - * @param pkt SMBSrvPacket - * @param len int - * @exception IOexception If a network error occurs - */ - public final void writePacket(SMBSrvPacket pkt, int len) throws IOException - { - - // Fill in the NetBIOS message header, this is already allocated as - // part of the users buffer. - - byte[] buf = pkt.getBuffer(); - buf[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; - buf[1] = (byte) 0; - - if (len > 0xFFFF) - { - - // Set the >64K flag - - buf[1] = (byte) 0x01; - - // Set the low word of the data length - - DataPacker.putShort((short) (len & 0xFFFF), buf, 2); - } - else - { - - // Set the data length - - DataPacker.putShort((short) len, buf, 2); - } - - // Output the data packet - - int bufSiz = len + RFCNetBIOSProtocol.HEADER_LEN; - writePacket(buf, 0, bufSiz); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/NetBIOSSessionSocketHandler.java b/source/java/org/alfresco/filesys/smb/server/NetBIOSSessionSocketHandler.java deleted file mode 100644 index 4c167944ac..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/NetBIOSSessionSocketHandler.java +++ /dev/null @@ -1,235 +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.smb.server; - -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; - -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.smb.mailslot.TcpipNetBIOSHostAnnouncer; - -/** - * NetBIOS Socket Session Handler Class - */ -public class NetBIOSSessionSocketHandler extends SessionSocketHandler -{ - // Session Thread group - private static final ThreadGroup THREAD_GROUP_SESSION = new ThreadGroup("NETBIOS_SESSION_GROUP"); - - /** - * Class constructor - * - * @param srv SMBServer - * @param port int - * @param bindAddr InetAddress - * @param debug boolean - */ - public NetBIOSSessionSocketHandler(SMBServer srv, int port, InetAddress bindAddr, boolean debug) - { - super("NetBIOS", srv, port, bindAddr, debug); - } - - /** - * Run the NetBIOS session socket handler - */ - public void run() - { - - try - { - - // Clear the shutdown flag - - clearShutdown(); - - // Wait for incoming connection requests - - while (hasShutdown() == false) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Waiting for NetBIOS session request ..."); - - // Wait for a connection - - Socket sessSock = getSocket().accept(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("NetBIOS session request received from " - + sessSock.getInetAddress().getHostAddress()); - - try - { - - // Create a packet handler for the session - - PacketHandler pktHandler = new NetBIOSPacketHandler(sessSock); - - // Create a server session for the new request, and set the session id. - - SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); - srvSess.setSessionId(getNextSessionId()); - srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); - - // Add the session to the active session list - - getServer().addSession(srvSess); - - // Start the new session in a seperate thread - - Thread srvThread = new Thread(THREAD_GROUP_SESSION, srvSess); - srvThread.setDaemon(true); - srvThread.setName("Sess_N" + srvSess.getSessionId() + "_" - + sessSock.getInetAddress().getHostAddress()); - srvThread.start(); - } - catch (Exception ex) - { - - // Debug - - logger.error("NetBIOS Failed to create session, ", 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("NetBIOS Socket error : ", ex); - } - 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("NetBIOS Server error : ", ex); - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("NetBIOS session handler closed"); - } - - /** - * Create the TCP/IP NetBIOS session socket handlers for the main SMB/CIFS server - * - * @param server SMBServer - * @param sockDbg boolean - * @exception Exception - */ - public final static void createSessionHandlers(SMBServer server, boolean sockDbg) throws Exception - { - - // Access the server configuration - - ServerConfiguration config = server.getConfiguration(); - - // Create the NetBIOS SMB handler - - SessionSocketHandler sessHandler = new NetBIOSSessionSocketHandler(server, config.getNetBIOSSessionPort(), config - .getSMBBindAddress(), sockDbg); - sessHandler.initialize(); - - // Add the session handler to the list of active handlers - - server.addSessionHandler(sessHandler); - - // Run the NetBIOS session handler in a seperate thread - - Thread nbThread = new Thread(sessHandler); - nbThread.setName("NetBIOS_Handler"); - nbThread.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("TCP NetBIOS session handler created on port " + config.getNetBIOSSessionPort()); - - // Check if a host announcer should be created - - if (config.hasEnableAnnouncer()) - { - - // Create the TCP NetBIOS host announcer - - TcpipNetBIOSHostAnnouncer announcer = new TcpipNetBIOSHostAnnouncer(); - - // Set the host name to be announced - - announcer.addHostName(config.getServerName()); - announcer.setDomain(config.getDomainName()); - announcer.setComment(config.getComment()); - announcer.setBindAddress(config.getSMBBindAddress()); - announcer.setPort(config.getNetBIOSDatagramPort()); - - // Set the announcement interval - - if (config.getHostAnnounceInterval() > 0) - announcer.setInterval(config.getHostAnnounceInterval()); - - try - { - announcer.setBroadcastAddress(config.getBroadcastMask()); - } - catch (Exception ex) - { - } - - // Set the server type flags - - announcer.setServerType(config.getServerType()); - - // Enable debug output - - if (config.hasHostAnnounceDebug()) - announcer.setDebug(true); - - // Add the host announcer to the SMS servers list - - server.addHostAnnouncer(announcer); - - // Start the host announcer thread - - announcer.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("TCP NetBIOS host announcer created on port " + config.getNetBIOSDatagramPort()); - } - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/OpenAndX.java b/source/java/org/alfresco/filesys/smb/server/OpenAndX.java deleted file mode 100644 index 84a4c8c9f3..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/OpenAndX.java +++ /dev/null @@ -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.smb.server; - -/** - * OpenAndX Flags Class - */ -class OpenAndX -{ - - // File types, for OpenAndX - - protected static final int FileTypeDisk = 0; - protected static final int FileTypeBytePipe = 1; - protected static final int FileTypeMsgPipe = 2; - protected static final int FileTypePrinter = 3; - protected static final int FileTypeUnknown = 0xFFFF; -} diff --git a/source/java/org/alfresco/filesys/smb/server/PacketHandler.java b/source/java/org/alfresco/filesys/smb/server/PacketHandler.java deleted file mode 100644 index c1516f5a97..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/PacketHandler.java +++ /dev/null @@ -1,307 +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.smb.server; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; - -/** - * Protocol Packet Handler Interface - */ -public abstract class PacketHandler -{ - - // Protocol type and name - - private int m_protoType; - private String m_protoName; - private String m_shortName; - - // Socket that this session is using. - - private Socket m_socket; - - // Input/output streams for receiving/sending SMB requests. - - private DataInputStream m_in; - private DataOutputStream m_out; - - // Client caller name - - private String m_clientName; - - /** - * Class constructor - * - * @param sock Socket - * @param typ int - * @param name String - * @param shortName String - * @exception IOException If a network error occurs - */ - public PacketHandler(Socket sock, int typ, String name, String shortName) throws IOException - { - m_socket = sock; - m_protoType = typ; - m_protoName = name; - m_shortName = shortName; - - // Set socket options - - sock.setTcpNoDelay(true); - - // Open the input/output streams - - m_in = new DataInputStream(m_socket.getInputStream()); - m_out = new DataOutputStream(m_socket.getOutputStream()); - } - - /** - * Class constructor - * - * @param typ int - * @param name String - * @param shortName String - */ - public PacketHandler(int typ, String name, String shortName, String clientName) - { - m_protoType = typ; - m_protoName = name; - m_shortName = shortName; - - m_clientName = clientName; - } - - /** - * Return the protocol type - * - * @return int - */ - public final int isProtocol() - { - return m_protoType; - } - - /** - * Return the protocol name - * - * @return String - */ - public final String isProtocolName() - { - return m_protoName; - } - - /** - * Return the short protocol name - * - * @return String - */ - public final String getShortName() - { - return m_shortName; - } - - /** - * Check if there is a remote address available - * - * @return boolean - */ - public final boolean hasRemoteAddress() - { - return m_socket != null ? true : false; - } - - /** - * Return the remote address for the socket connection - * - * @return InetAddress - */ - public final InetAddress getRemoteAddress() - { - return m_socket != null ? m_socket.getInetAddress() : null; - } - - /** - * Determine if the client name is available - * - * @return boolean - */ - public final boolean hasClientName() - { - return m_clientName != null ? true : false; - } - - /** - * Return the client name - * - * @return - */ - public final String getClientName() - { - return m_clientName; - } - - /** - * Return the count of available bytes in the receive input stream - * - * @return int - * @exception IOException If a network error occurs. - */ - public final int availableBytes() throws IOException - { - if (m_in != null) - return m_in.available(); - return 0; - } - - /** - * Read a packet - * - * @param pkt byte[] - * @param off int - * @param len int - * @return int - * @exception IOException If a network error occurs. - */ - public final int readPacket(byte[] pkt, int off, int len) throws IOException - { - - // Read a packet of data - - if (m_in != null) - return m_in.read(pkt, off, len); - return 0; - } - - /** - * Receive an SMB request packet - * - * @param pkt SMBSrvPacket - * @return int - * @exception IOException If a network error occurs. - */ - public abstract int readPacket(SMBSrvPacket pkt) throws IOException; - - /** - * Send an SMB request packet - * - * @param pkt byte[] - * @param off int - * @param len int - * @exception IOException If a network error occurs. - */ - public final void writePacket(byte[] pkt, int off, int len) throws IOException - { - - // Output the raw packet - - if (m_out != null) - m_out.write(pkt, off, len); - } - - /** - * Send an SMB response packet - * - * @param pkt SMBSrvPacket - * @param len int - * @exception IOException If a network error occurs. - */ - public abstract void writePacket(SMBSrvPacket pkt, int len) throws IOException; - - /** - * Send an SMB response packet - * - * @param pkt SMBSrvPacket - * @exception IOException If a network error occurs. - */ - public final void writePacket(SMBSrvPacket pkt) throws IOException - { - writePacket(pkt, pkt.getLength()); - } - - /** - * Flush the output socket - * - * @exception IOException If a network error occurs - */ - public final void flushPacket() throws IOException - { - if (m_out != null) - m_out.flush(); - } - - /** - * Close the protocol handler - */ - public void closeHandler() - { - - // Close the input stream - - if (m_in != null) - { - try - { - m_in.close(); - } - catch (Exception ex) - { - } - m_in = null; - } - - // Close the output stream - - if (m_out != null) - { - try - { - m_out.close(); - } - catch (Exception ex) - { - } - m_out = null; - } - - // Close the socket - - if (m_socket != null) - { - try - { - m_socket.close(); - } - catch (Exception ex) - { - } - m_socket = null; - } - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/PipeDevice.java b/source/java/org/alfresco/filesys/smb/server/PipeDevice.java deleted file mode 100644 index 81078c5f20..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/PipeDevice.java +++ /dev/null @@ -1,35 +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.smb.server; - -import org.alfresco.filesys.server.core.DeviceInterface; - -/** - * The pipe interface is implemented by classes that provide an interface for a named pipe type - * shared device. - */ -public interface PipeDevice extends DeviceInterface -{ -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/PipeLanmanHandler.java b/source/java/org/alfresco/filesys/smb/server/PipeLanmanHandler.java deleted file mode 100644 index 90054f57bc..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/PipeLanmanHandler.java +++ /dev/null @@ -1,644 +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.smb.server; - -import java.io.IOException; -import java.util.Enumeration; - -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.smb.PacketType; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.TransactBuffer; -import org.alfresco.filesys.util.DataBuffer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * IPC$ Transaction handler for \PIPE\LANMAN requests. - */ -class PipeLanmanHandler -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Server capability flags - - public static final int WorkStation = 0x00000001; - public static final int Server = 0x00000002; - public static final int SQLServer = 0x00000004; - public static final int DomainCtrl = 0x00000008; - public static final int DomainBakCtrl = 0x00000010; - public static final int TimeSource = 0x00000020; - public static final int AFPServer = 0x00000040; - public static final int NovellServer = 0x00000080; - public static final int DomainMember = 0x00000100; - public static final int PrintServer = 0x00000200; - public static final int DialinServer = 0x00000400; - public static final int UnixServer = 0x00000800; - public static final int NTServer = 0x00001000; - public static final int WfwServer = 0x00002000; - public static final int MFPNServer = 0x00004000; - public static final int NTNonDCServer = 0x00008000; - public static final int PotentialBrowse = 0x00010000; - public static final int BackupBrowser = 0x00020000; - public static final int MasterBrowser = 0x00040000; - public static final int DomainMaster = 0x00080000; - public static final int OSFServer = 0x00100000; - public static final int VMSServer = 0x00200000; - public static final int Win95Plus = 0x00400000; - public static final int DFSRoot = 0x00800000; - public static final int NTCluster = 0x01000000; - public static final int TerminalServer = 0x02000000; - public static final int DCEServer = 0x10000000; - public static final int AlternateXport = 0x20000000; - public static final int LocalListOnly = 0x40000000; - public static final int DomainEnum = 0x80000000; - - /** - * Process a \PIPE\LANMAN transaction request. - * - * @param tbuf Transaction setup, parameter and data buffers - * @param sess SMB server session that received the transaction. - * @param trans Packet to use for reply - * @return true if the transaction has been handled, else false. - * @exception java.io.IOException If an I/O error occurs - * @exception SMBSrvException If an SMB protocol error occurs - */ - public final static boolean processRequest(TransactBuffer tbuf, SMBSrvSession sess, SMBSrvPacket trans) - throws IOException, SMBSrvException - { - - // Create a transaction packet - - SMBSrvTransPacket tpkt = new SMBSrvTransPacket(trans.getBuffer()); - - // Get the transaction command code, parameter descriptor and data descriptor strings from - // the parameter block. - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int cmd = paramBuf.getShort(); - String prmDesc = paramBuf.getString(false); - String dataDesc = paramBuf.getString(false); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("\\PIPE\\LANMAN\\ transact request, cmd=" + cmd + ", prm=" + prmDesc + ", data=" + dataDesc); - - // Call the required transaction handler - - boolean processed = false; - - switch (cmd) - { - - // Share - - case PacketType.RAPShareEnum: - processed = procNetShareEnum(sess, tbuf, prmDesc, dataDesc, tpkt); - break; - - // Get share information - - case PacketType.RAPShareGetInfo: - processed = procNetShareGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt); - break; - - // Workstation information - - case PacketType.RAPWkstaGetInfo: - processed = procNetWkstaGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt); - break; - - // Server information - - case PacketType.RAPServerGetInfo: - processed = procNetServerGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt); - break; - - // Print queue information - - case PacketType.NetPrintQGetInfo: - processed = procNetPrintQGetInfo(sess, tbuf, prmDesc, dataDesc, tpkt); - break; - - // No handler - - default: - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("No handler for \\PIPE\\LANMAN\\ request, cmd=" + cmd + ", prm=" + prmDesc + ", data=" - + dataDesc); - break; - } - - // Return the transaction processed status - - return processed; - } - - /** - * Process a NetServerGetInfo transaction request. - * - * @param sess Server session that received the request. - * @param tbuf Transaction buffer - * @param prmDesc Parameter descriptor string. - * @param dataDesc Data descriptor string. - * @param tpkt Transaction reply packet - * @return true if the transaction has been processed, else false. - */ - protected final static boolean procNetServerGetInfo(SMBSrvSession sess, TransactBuffer tbuf, String prmDesc, - String dataDesc, SMBSrvTransPacket tpkt) throws IOException, SMBSrvException - { - - // Validate the parameter string - - if (prmDesc.compareTo("WrLh") != 0) - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // Unpack the server get information specific parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevel = paramBuf.getShort(); - int bufSize = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetServerGetInfo infoLevel=" + infoLevel); - - // Check if the information level requested and data descriptor string match - - if (infoLevel == 1 && dataDesc.compareTo("B16BBDz") == 0) - { - - // Create the transaction reply data buffer - - TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024); - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(0); // status code - paramBuf.putShort(0); // converter for strings - paramBuf.putShort(1); // number of entries - - // Pack the data block, calculate the size of the fixed data block - - DataBuffer dataBuf = replyBuf.getDataBuffer(); - int strPos = SMBSrvTransPacket.CalculateDataItemSize("B16BBDz"); - - // Pack the server name pointer and string - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putFixedStringAt(sess.getServerName(), 16, strPos); - - // Pack the major/minor version - - dataBuf.putByte(1); - dataBuf.putByte(0); - - // Pack the server capability flags - - dataBuf.putInt(sess.getSMBServer().getServerType()); - - // Pack the server comment string - - String srvComment = sess.getSMBServer().getComment(); - if (srvComment == null) - srvComment = ""; - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putStringAt(srvComment, strPos, false, true); - - // Set the data block length - - dataBuf.setLength(strPos); - - // Send the transaction response - - tpkt.doTransactionResponse(sess, replyBuf); - } - else - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // We processed the request - - return true; - } - - /** - * Process a NetShareEnum transaction request. - * - * @param sess Server session that received the request. - * @param tbuf Transaction buffer - * @param prmDesc Parameter descriptor string. - * @param dataDesc Data descriptor string. - * @param tpkt Transaction reply packet - * @return true if the transaction has been processed, else false. - */ - protected final static boolean procNetShareEnum(SMBSrvSession sess, TransactBuffer tbuf, String prmDesc, - String dataDesc, SMBSrvTransPacket tpkt) throws IOException, SMBSrvException - { - - // Validate the parameter string - - if (prmDesc.compareTo("WrLeh") != 0) - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // Unpack the server get information specific parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevel = paramBuf.getShort(); - int bufSize = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetShareEnum infoLevel=" + infoLevel); - - // Check if the information level requested and data descriptor string match - - if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) - { - - // Get the share list from the server - - SharedDeviceList shrList = sess.getSMBServer().getShareList(null, sess); - int shrCount = 0; - int strPos = 0; - - if (shrList != null) - { - - // Calculate the fixed data length - - shrCount = shrList.numberOfShares(); - strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz") * shrCount; - } - - // Create the transaction reply data buffer - - TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, bufSize); - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(0); // status code - paramBuf.putShort(0); // converter for strings - paramBuf.putShort(shrCount); // number of entries - paramBuf.putShort(shrCount); // total number of entries - - // Pack the data block - - DataBuffer dataBuf = replyBuf.getDataBuffer(); - Enumeration enm = shrList.enumerateShares(); - - while (enm.hasMoreElements()) - { - - // Get the current share - - SharedDevice shrDev = enm.nextElement(); - - // Pack the share name, share type and comment pointer - - dataBuf.putFixedString(shrDev.getName(), 13); - dataBuf.putByte(0); - dataBuf.putShort(ShareType.asShareInfoType(shrDev.getType())); - dataBuf.putStringPointer(strPos); - - if (shrDev.getComment() != null) - strPos = dataBuf.putStringAt(shrDev.getComment(), strPos, false, true); - else - strPos = dataBuf.putStringAt("", strPos, false, true); - } - - // Set the data block length - - dataBuf.setLength(strPos); - - // Send the transaction response - - tpkt.doTransactionResponse(sess, replyBuf); - } - else - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // We processed the request - - return true; - } - - /** - * Process a NetShareGetInfo transaction request. - * - * @param sess Server session that received the request. - * @param tbuf Transaction buffer - * @param prmDesc Parameter descriptor string. - * @param dataDesc Data descriptor string. - * @param tpkt Transaction reply packet - * @return true if the transaction has been processed, else false. - */ - protected final static boolean procNetShareGetInfo(SMBSrvSession sess, TransactBuffer tbuf, String prmDesc, - String dataDesc, SMBSrvTransPacket tpkt) throws IOException, SMBSrvException - { - - // Validate the parameter string - - if (prmDesc.compareTo("zWrLh") != 0) - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // Unpack the share get information specific parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - String shareName = paramBuf.getString(32, false); - int infoLevel = paramBuf.getShort(); - int bufSize = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetShareGetInfo - " + shareName + ", infoLevel=" + infoLevel); - - // Check if the information level requested and data descriptor string match - - if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) - { - - // Find the required share information - - SharedDevice share = null; - - try - { - - // Get the shared device details - - share = sess.getSMBServer().findShare(null, shareName, ShareType.UNKNOWN, sess, false); - } - catch (Exception ex) - { - } - - if (share == null) - { - sess.sendErrorResponseSMB(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - return true; - } - - // Create the transaction reply data buffer - - TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024); - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(0); // status code - paramBuf.putShort(0); // converter for strings - paramBuf.putShort(1); // number of entries - - // Pack the data block, calculate the size of the fixed data block - - DataBuffer dataBuf = replyBuf.getDataBuffer(); - int strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz"); - - // Pack the share name - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putFixedStringAt(share.getName(), 13, strPos); - - // Pack unknown byte, alignment ? - - dataBuf.putByte(0); - - // Pack the share type flags - - dataBuf.putShort(share.getType()); - - // Pack the share comment - - dataBuf.putStringPointer(strPos); - - if (share.getComment() != null) - strPos = dataBuf.putStringAt(share.getComment(), strPos, false, true); - else - strPos = dataBuf.putStringAt("", strPos, false, true); - - // Set the data block length - - dataBuf.setLength(strPos); - - // Send the transaction response - - tpkt.doTransactionResponse(sess, replyBuf); - } - else - { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetShareGetInfo - UNSUPPORTED " + shareName + ", infoLevel=" + infoLevel + ", dataDesc=" - + dataDesc); - - // Server error - - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - } - - // We processed the request - - return true; - } - - /** - * Process a NetWkstaGetInfo transaction request. - * - * @param sess Server session that received the request. - * @param tbuf Transaction buffer - * @param prmDesc Parameter descriptor string. - * @param dataDesc Data descriptor string. - * @param tpkt Transaction reply packet - * @return true if the transaction has been processed, else false. - */ - protected final static boolean procNetWkstaGetInfo(SMBSrvSession sess, TransactBuffer tbuf, String prmDesc, - String dataDesc, SMBSrvTransPacket tpkt) throws IOException, SMBSrvException - { - - // Validate the parameter string - - if (prmDesc.compareTo("WrLh") != 0) - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // Unpack the share get information specific parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - int infoLevel = paramBuf.getShort(); - int bufSize = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetWkstaGetInfo infoLevel=" + infoLevel); - - // Check if the information level requested and data descriptor string match - - if ((infoLevel == 1 && dataDesc.compareTo("zzzBBzzz") == 0) - || (infoLevel == 10 && dataDesc.compareTo("zzzBBzz") == 0)) - { - - // Create the transaction reply data buffer - - TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024); - - // Pack the data block, calculate the size of the fixed data block - - DataBuffer dataBuf = replyBuf.getDataBuffer(); - int strPos = SMBSrvTransPacket.CalculateDataItemSize(dataDesc); - - // Pack the server name - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putStringAt(sess.getServerName(), strPos, false, true); - - // Pack the user name - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putStringAt("", strPos, false, true); - - // Pack the domain name - - dataBuf.putStringPointer(strPos); - - String domain = sess.getServer().getConfiguration().getDomainName(); - if (domain == null) - domain = ""; - strPos = dataBuf.putStringAt(domain, strPos, false, true); - - // Pack the major/minor version number - - dataBuf.putByte(4); - dataBuf.putByte(2); - - // Pack the logon domain - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putStringAt("", strPos, false, true); - - // Check if the other domains should be packed - - if (infoLevel == 1 && dataDesc.compareTo("zzzBBzzz") == 0) - { - - // Pack the other domains - - dataBuf.putStringPointer(strPos); - strPos = dataBuf.putStringAt("", strPos, false, true); - } - - // Set the data block length - - dataBuf.setLength(strPos); - - // Pack the parameter block - - paramBuf = replyBuf.getParameterBuffer(); - - paramBuf.putShort(0); // status code - paramBuf.putShort(0); // converter for strings - paramBuf.putShort(dataBuf.getLength()); - paramBuf.putShort(0); // number of entries - - // Send the transaction response - - tpkt.doTransactionResponse(sess, replyBuf); - } - else - { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetWkstaGetInfo UNSUPPORTED infoLevel=" + infoLevel + ", dataDesc=" + dataDesc); - - // Unsupported request - - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - } - - // We processed the request - - return true; - } - - /** - * Process a NetPrintQGetInfo transaction request. - * - * @param sess Server session that received the request. - * @param tbuf Transaction buffer - * @param prmDesc Parameter descriptor string. - * @param dataDesc Data descriptor string. - * @param tpkt Transaction reply packet - * @return true if the transaction has been processed, else false. - */ - protected final static boolean procNetPrintQGetInfo(SMBSrvSession sess, TransactBuffer tbuf, String prmDesc, - String dataDesc, SMBSrvTransPacket tpkt) throws IOException, SMBSrvException - { - - // Validate the parameter string - - if (prmDesc.compareTo("zWrLh") != 0) - throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); - - // Unpack the share get information specific parameters - - DataBuffer paramBuf = tbuf.getParameterBuffer(); - - String shareName = paramBuf.getString(32, false); - int infoLevel = paramBuf.getShort(); - int bufSize = paramBuf.getShort(); - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_IPC)) - logger.debug("NetPrintQGetInfo - " + shareName + ", infoLevel=" + infoLevel); - - // We did not process the request - - return false; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/ProtocolFactory.java b/source/java/org/alfresco/filesys/smb/server/ProtocolFactory.java deleted file mode 100644 index 5127820c36..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/ProtocolFactory.java +++ /dev/null @@ -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.smb.server; - -import org.alfresco.filesys.smb.Dialect; - -/** - * SMB Protocol Factory Class. - *

- * The protocol factory class generates protocol handlers for SMB dialects. - */ -class ProtocolFactory -{ - - /** - * ProtocolFactory constructor comment. - */ - public ProtocolFactory() - { - super(); - } - - /** - * Return a protocol handler for the specified SMB dialect type, or null if there is no - * appropriate protocol handler. - * - * @param dialect int - * @return ProtocolHandler - */ - protected static ProtocolHandler getHandler(int dialect) - { - - // Determine the SMB dialect type - - ProtocolHandler handler = null; - - switch (dialect) - { - - // Core dialect - - case Dialect.Core: - case Dialect.CorePlus: - handler = new CoreProtocolHandler(); - break; - - // LanMan dialect - - case Dialect.DOSLanMan1: - case Dialect.DOSLanMan2: - case Dialect.LanMan1: - case Dialect.LanMan2: - case Dialect.LanMan2_1: - handler = new LanManProtocolHandler(); - break; - - // NT dialect - - case Dialect.NT: - handler = new NTProtocolHandler(); - break; - } - - // Return the protocol handler - - return handler; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/ProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/ProtocolHandler.java deleted file mode 100644 index bf9b1290d6..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/ProtocolHandler.java +++ /dev/null @@ -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.smb.server; - -import java.io.IOException; - -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.DiskSizeInterface; -import org.alfresco.filesys.server.filesys.DiskVolumeInterface; -import org.alfresco.filesys.server.filesys.SrvDiskInfo; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.VolumeInfo; -import org.alfresco.filesys.smb.PacketType; - -/** - * Protocol handler abstract base class. - *

- * The protocol handler class is the base of all SMB protocol/dialect handler classes. - */ -abstract class ProtocolHandler -{ - - // Server session that this protocol handler is associated with. - - protected SMBSrvSession m_sess; - - /** - * Create a protocol handler for the specified session. - */ - protected ProtocolHandler() - { - } - - /** - * Create a protocol handler for the specified session. - * - * @param sess SMBSrvSession - */ - protected ProtocolHandler(SMBSrvSession sess) - { - m_sess = sess; - } - - /** - * Return the protocol handler name. - * - * @return java.lang.String - */ - public abstract String getName(); - - /** - * Run the SMB protocol handler for this server session. - * - * @exception java.io.IOException - * @exception SMBSrvException - */ - public abstract boolean runProtocol() throws IOException, SMBSrvException, TooManyConnectionsException; - - /** - * Get the server session that this protocol handler is associated with. - * - * @param sess SMBSrvSession - */ - protected final SMBSrvSession getSession() - { - return m_sess; - } - - /** - * Set the server session that this protocol handler is associated with. - * - * @param sess SMBSrvSession - */ - protected final void setSession(SMBSrvSession sess) - { - m_sess = sess; - } - - /** - * Determine if the request is a chained (AndX) type command and there is a chained command in - * this request. - * - * @param pkt SMBSrvPacket - * @return true if there is a chained request to be handled, else false. - */ - protected final boolean hasChainedCommand(SMBSrvPacket pkt) - { - - // Determine if the command code is an AndX command - - int cmd = pkt.getCommand(); - - if (cmd == PacketType.SessionSetupAndX || cmd == PacketType.TreeConnectAndX || cmd == PacketType.OpenAndX - || cmd == PacketType.WriteAndX || cmd == PacketType.ReadAndX || cmd == PacketType.LogoffAndX - || cmd == PacketType.LockingAndX || cmd == PacketType.NTCreateAndX) - { - - // Check if there is a chained command - - return pkt.hasAndXCommand(); - } - - // Not a chained type command - - return false; - } - - /** - * Get disk sizing information from the specified driver and context. - * - * @param disk DiskInterface - * @param ctx DiskDeviceContext - * @return SrvDiskInfo - * @exception IOException - */ - protected final SrvDiskInfo getDiskInformation(DiskInterface disk, DiskDeviceContext ctx) throws IOException - { - - // Get the static disk information from the context, if available - - SrvDiskInfo diskInfo = ctx.getDiskInformation(); - - // If we did not get valid disk information from the device context check if the driver - // implements the - // disk sizing interface - - if (diskInfo == null) - diskInfo = new SrvDiskInfo(); - - // Check if the driver implements the dynamic sizing interface to get realtime disk size - // information - - if (disk instanceof DiskSizeInterface) - { - - // Get the dynamic disk sizing information - - DiskSizeInterface sizeInterface = (DiskSizeInterface) disk; - sizeInterface.getDiskInformation(ctx, diskInfo); - } - - // Return the disk information - - return diskInfo; - } - - /** - * Get disk volume information from the specified driver and context - * - * @param disk DiskInterface - * @param ctx DiskDeviceContext - * @return VolumeInfo - */ - protected final VolumeInfo getVolumeInformation(DiskInterface disk, DiskDeviceContext ctx) - { - - // Get the static volume information from the context, if available - - VolumeInfo volInfo = ctx.getVolumeInformation(); - - // If we did not get valid volume information from the device context check if the driver - // implements the - // disk volume interface - - if (disk instanceof DiskVolumeInterface) - { - - // Get the dynamic disk volume information - - DiskVolumeInterface volInterface = (DiskVolumeInterface) disk; - volInfo = volInterface.getVolumeInformation(ctx); - } - - // If we still have not got valid volume information then create empty volume information - - if (volInfo == null) - volInfo = new VolumeInfo(""); - - // Return the volume information - - return volInfo; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/QueryInfoPacker.java b/source/java/org/alfresco/filesys/smb/server/QueryInfoPacker.java deleted file mode 100644 index 5b53beac47..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/QueryInfoPacker.java +++ /dev/null @@ -1,751 +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.smb.server; - -import org.alfresco.filesys.server.filesys.FileInfo; -import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException; -import org.alfresco.filesys.smb.FileInfoLevel; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.WinNT; -import org.alfresco.filesys.smb.server.ntfs.StreamInfo; -import org.alfresco.filesys.smb.server.ntfs.StreamInfoList; -import org.alfresco.filesys.util.DataBuffer; - -/** - * Query File Information Packer Class - *

- * Packs file/directory information for the specified information level. - */ -public class QueryInfoPacker -{ - - /** - * Pack a file information object into the specified buffer, using the specified information - * level. - * - * @param info File information to be packed. - * @param buf Buffer to pack the data into. - * @param infoLevel File information level. - * @param uni Pack Unicode strings if true, else pack ASCII strings - * @return int Length of data packed - */ - public final static int packInfo(FileInfo info, DataBuffer buf, int infoLevel, boolean uni) - throws UnsupportedInfoLevelException - { - - // Determine the information level - - int curPos = buf.getPosition(); - - switch (infoLevel) - { - - // Standard information - - case FileInfoLevel.PathStandard: - packInfoStandard(info, buf, false, uni); - break; - - // Standard information plus EA size - - case FileInfoLevel.PathQueryEASize: - packInfoStandard(info, buf, true, uni); - break; - - // Extended attributes list - - case FileInfoLevel.PathQueryEAsFromList: - break; - - // All extended attributes - - case FileInfoLevel.PathAllEAs: - break; - - // Validate a file name - - case FileInfoLevel.PathIsNameValid: - break; - - // Basic file information - - case FileInfoLevel.PathFileBasicInfo: - case FileInfoLevel.NTFileBasicInfo: - packBasicFileInfo(info, buf); - break; - - // Standard file information - - case FileInfoLevel.PathFileStandardInfo: - case FileInfoLevel.NTFileStandardInfo: - packStandardFileInfo(info, buf); - break; - - // Extended attribute information - - case FileInfoLevel.PathFileEAInfo: - case FileInfoLevel.NTFileEAInfo: - packEAFileInfo(info, buf); - break; - - // File name information - - case FileInfoLevel.PathFileNameInfo: - case FileInfoLevel.NTFileNameInfo: - packNameFileInfo(info, buf, uni); - break; - - // All information - - case FileInfoLevel.PathFileAllInfo: - case FileInfoLevel.NTFileAllInfo: - packAllFileInfo(info, buf, uni); - break; - - // Alternate name information - - case FileInfoLevel.PathFileAltNameInfo: - case FileInfoLevel.NTFileAltNameInfo: - packAlternateNameFileInfo(info, buf); - break; - - // Stream information - - case FileInfoLevel.PathFileStreamInfo: - case FileInfoLevel.NTFileStreamInfo: - packStreamFileInfo(info, buf, uni); - break; - - // Compression information - - case FileInfoLevel.PathFileCompressionInfo: - case FileInfoLevel.NTFileCompressionInfo: - packCompressionFileInfo(info, buf); - break; - - // File internal information - - case FileInfoLevel.NTFileInternalInfo: - packFileInternalInfo(info, buf); - break; - - // File position information - - case FileInfoLevel.NTFilePositionInfo: - packFilePositionInfo(info, buf); - break; - - // Attribute tag information - - case FileInfoLevel.NTAttributeTagInfo: - packFileAttributeTagInfo(info, buf); - break; - - // Network open information - - case FileInfoLevel.NTNetworkOpenInfo: - packFileNetworkOpenInfo(info, buf); - break; - } - - // Return the length of the data that was packed - - return buf.getPosition() - curPos; - } - - /** - * Pack the standard file information - * - * @param info File information - * @param buf Buffer to pack data into - * @param eaFlag Return EA size - * @param uni Pack unicode strings - */ - private static void packInfoStandard(FileInfo info, DataBuffer buf, boolean eaFlag, boolean uni) - { - - // Information format :- - // SMB_DATE CreationDate - // SMB_TIME CreationTime - // SMB_DATE LastAccessDate - // SMB_TIME LastAccessTime - // SMB_DATE LastWriteDate - // SMB_TIME LastWriteTime - // ULONG File size - // ULONG Allocation size - // USHORT File attributes - // [ ULONG EA size ] - - // Pack the creation date/time - - SMBDate dateTime = new SMBDate(0); - - if (info.hasCreationDateTime()) - { - dateTime.setTime(info.getCreationDateTime()); - buf.putShort(dateTime.asSMBDate()); - buf.putShort(dateTime.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - dateTime.setTime(info.getAccessDateTime()); - buf.putShort(dateTime.asSMBDate()); - buf.putShort(dateTime.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the last write date/time - - if (info.hasModifyDateTime()) - { - dateTime.setTime(info.getModifyDateTime()); - buf.putShort(dateTime.asSMBDate()); - buf.putShort(dateTime.asSMBTime()); - } - else - buf.putZeros(4); - - // Pack the file size and allocation size - - buf.putInt(info.getSizeInt()); - - if (info.getAllocationSize() < info.getSize()) - buf.putInt(info.getSizeInt()); - else - buf.putInt(info.getAllocationSizeInt()); - - // Pack the file attributes - - buf.putShort(info.getFileAttributes()); - - // Pack the EA size, always zero - - if (eaFlag == true) - buf.putZeros(4); - } - - /** - * Pack the basic file information (level 0x101) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packBasicFileInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // LARGE_INTEGER Creation date/time - // LARGE_INTEGER Access date/time - // LARGE_INTEGER Write date/time - // LARGE_INTEGER Change date/time - // UINT Attributes - // UINT Unknown - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write and change date/time - - if (info.hasModifyDateTime()) - { - long ntTime = NTTime.toNTTime(info.getModifyDateTime()); - buf.putLong(ntTime); - buf.putLong(ntTime); - } - else - buf.putZeros(16); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack unknown value - - buf.putZeros(4); - } - - /** - * Pack the standard file information (level 0x102) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packStandardFileInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // LARGE_INTEGER AllocationSize - // LARGE_INTEGER EndOfFile - // UINT NumberOfLinks - // BOOLEAN DeletePending - // BOOLEAN Directory - // SHORT Unknown - - // Pack the allocation and file sizes - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - buf.putLong(info.getSize()); - - // Pack the number of links, always one for now - - buf.putInt(1); - - // Pack the delete pending and directory flags - - buf.putByte(0); - buf.putByte(info.isDirectory() ? 1 : 0); - - // buf.putZeros(2); - } - - /** - * Pack the extended attribute information (level 0x103) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packEAFileInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG EASize - - // Pack the extended attribute size - - buf.putInt(0); - } - - /** - * Pack the file name information (level 0x104) - * - * @param info File information - * @param buf Buffer to pack data into - * @param uni Pack unicode strings - */ - private static void packNameFileInfo(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // UINT FileNameLength - // WCHAR FileName[] - - // Pack the file name length and name string as Unicode - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - buf.putString(info.getFileName(), uni, false); - } - - /** - * Pack the all file information (level 0x107) - * - * @param info File information - * @param buf Buffer to pack data into - * @param uni Pack unicode strings - */ - private static void packAllFileInfo(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // LARGE_INTEGER Creation date/time - // LARGE_INTEGER Access date/time - // LARGE_INTEGER Write date/time - // LARGE_INTEGER Change date/time - // UINT Attributes - // UINT Number of links - // LARGE_INTEGER Allocation - // LARGE_INTEGER Size - // BYTE Delete pending - // BYTE Directory flag - // 2 byte longword alignment - // UINT EA Size - // UINT Access mask - // UINT File name length - // WCHAR FileName[] - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write and change date/time - - if (info.hasModifyDateTime()) - { - long ntTime = NTTime.toNTTime(info.getModifyDateTime()); - buf.putLong(ntTime); - buf.putLong(ntTime); - } - else - buf.putZeros(16); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Number of links - - buf.putInt(1); - - // Pack the allocation and used file sizes - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - buf.putLong(info.getSize()); - - // Pack the delete pending and directory flags - - buf.putByte(0); - buf.putByte(info.isDirectory() ? 1 : 0); - buf.putShort(0); // Alignment - - // EA list size - - buf.putInt(0); - - // Access mask - - buf.putInt(0x00000003); - - // File name length in bytes and file name, Unicode - - int nameLen = info.getFileName().length(); - if (uni) - nameLen *= 2; - - buf.putInt(nameLen); - buf.putString(info.getFileName(), uni, false); - } - - /** - * Pack the alternate name information (level 0x108) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packAlternateNameFileInfo(FileInfo info, DataBuffer buf) - { - } - - /** - * Pack the stream information (level 0x109) - * - * @param info File information - * @param buf Buffer to pack data into - * @param uni Pack unicode strings - */ - private static void packStreamFileInfo(FileInfo info, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG OffsetToNextStreamInfo - // ULONG NameLength (in bytes) - // LARGE_INTEGER StreamSize - // LARGE_INTEGER StreamAlloc - // WCHAR StreamName[] - - // Pack a dummy data stream for now - - String streamName = "::$DATA"; - - buf.putInt(0); // offset to next info (no more info) - - int nameLen = streamName.length(); - if (uni) - nameLen *= 2; - buf.putInt(nameLen); - - // Stream size - - buf.putLong(info.getSize()); - - // Allocation size - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - buf.putString(streamName, uni, false); - } - - /** - * Pack the stream information (level 0x109) - * - * @param streams List of streams - * @param buf Buffer to pack data into - * @param uni Pack unicode strings - * @return int - */ - public static int packStreamFileInfo(StreamInfoList streams, DataBuffer buf, boolean uni) - { - - // Information format :- - // ULONG OffsetToNextStreamInfo - // ULONG NameLength (in bytes) - // LARGE_INTEGER StreamSize - // LARGE_INTEGER StreamAlloc - // WCHAR StreamName[] - - // Loop through the available streams - - int curPos = buf.getPosition(); - int startPos = curPos; - int pos = 0; - - for (int i = 0; i < streams.numberOfStreams(); i++) - { - - // Get the current stream information - - StreamInfo sinfo = streams.getStreamAt(i); - - // Skip the offset to the next stream information structure - - buf.putInt(0); - - // Set the stream name length - - int nameLen = sinfo.getName().length(); - if (uni) - nameLen *= 2; - buf.putInt(nameLen); - - // Stream size - - buf.putLong(sinfo.getSize()); - - // Allocation size - - if (sinfo.getAllocationSize() < sinfo.getSize()) - buf.putLong(sinfo.getSize()); - else - buf.putLong(sinfo.getAllocationSize()); - - buf.putString(sinfo.getName(), uni, false); - - // Word align the buffer - - buf.wordAlign(); - - // Fill in the offset to the next stream information, if this is not the last stream - - if (i < (streams.numberOfStreams() - 1)) - { - - // Fill in the offset from the current stream information structure to the next - - pos = buf.getPosition(); - buf.setPosition(startPos); - buf.putInt(pos - startPos); - buf.setPosition(pos); - startPos = pos; - } - } - - // Return the data length - - return buf.getPosition() - curPos; - } - - /** - * Pack the compression information (level 0x10B) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packCompressionFileInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // LARGE_INTEGER CompressedSize - // ULONG CompressionFormat (sess WinNT class) - - buf.putLong(info.getSize()); - buf.putInt(WinNT.CompressionFormatNone); - } - - /** - * Pack the file internal information (level 1006) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packFileInternalInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG Unknown1 - // ULONG Unknown2 - - buf.putInt(1); - buf.putInt(0); - } - - /** - * Pack the file position information (level 1014) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packFilePositionInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG Unknown1 - // ULONG Unknown2 - - buf.putInt(0); - buf.putInt(0); - } - - /** - * Pack the network open information (level 1034) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packFileNetworkOpenInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // LARGE_INTEGER Creation date/time - // LARGE_INTEGER Access date/time - // LARGE_INTEGER Write date/time - // LARGE_INTEGER Change date/time - // LARGE_INTEGER Allocation - // LARGE_INTEGER Size - // UINT Attributes - // UNIT Unknown - - // Pack the creation date/time - - if (info.hasCreationDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getCreationDateTime())); - } - else - buf.putZeros(8); - - // Pack the last access date/time - - if (info.hasAccessDateTime()) - { - buf.putLong(NTTime.toNTTime(info.getAccessDateTime())); - } - else - buf.putZeros(8); - - // Pack the last write and change date/time - - if (info.hasModifyDateTime()) - { - long ntTime = NTTime.toNTTime(info.getModifyDateTime()); - buf.putLong(ntTime); - buf.putLong(ntTime); - } - else - buf.putZeros(16); - - // Pack the allocation and used file sizes - - if (info.getAllocationSize() < info.getSize()) - buf.putLong(info.getSize()); - else - buf.putLong(info.getAllocationSize()); - - buf.putLong(info.getSize()); - - // Pack the file attributes - - buf.putInt(info.getFileAttributes()); - - // Pack the unknown value - - buf.putInt(0); - } - - /** - * Pack the attribute tag information (level 1035) - * - * @param info File information - * @param buf Buffer to pack data into - */ - private static void packFileAttributeTagInfo(FileInfo info, DataBuffer buf) - { - - // Information format :- - // ULONG Unknown1 - // ULONG Unknown2 - - buf.putLong(0); - buf.putLong(0); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/SMBPacket.java b/source/java/org/alfresco/filesys/smb/server/SMBPacket.java deleted file mode 100644 index 86e2560397..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBPacket.java +++ /dev/null @@ -1,1043 +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.smb.server; - -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataPacker; - -/** - * SMB packet type class - */ -public class SMBPacket -{ - - // SMB packet offsets, assuming an RFC NetBIOS transport - - public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN; - public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN; - - // SMB packet header length for a transaction type request - - public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN; - - // Minimum receive length for a valid SMB packet - - public static final int MIN_RXLEN = 32; - - // Default buffer size to allocate for SMB packets - - public static final int DEFAULT_BUFSIZE = 4096; - - // Flag bits - - public static final int FLG_SUBDIALECT = 0x01; - public static final int FLG_CASELESS = 0x08; - public static final int FLG_CANONICAL = 0x10; - public static final int FLG_OPLOCK = 0x20; - public static final int FLG_NOTIFY = 0x40; - public static final int FLG_RESPONSE = 0x80; - - // Flag2 bits - - public static final int FLG2_LONGFILENAMES = 0x0001; - public static final int FLG2_EXTENDEDATTRIB = 0x0002; - public static final int FLG2_SECURITYSIGS = 0x0004; - public static final int FLG2_LONGNAMESUSED = 0x0040; - public static final int FLG2_EXTENDNEGOTIATE = 0x0800; - public static final int FLG2_DFSRESOLVE = 0x1000; - public static final int FLG2_READIFEXE = 0x2000; - public static final int FLG2_LONGERRORCODE = 0x4000; - public static final int FLG2_UNICODE = 0x8000; - - // Security mode bits - - public static final int SEC_USER = 0x0001; - public static final int SEC_ENCRYPT = 0x0002; - - // Raw mode bits - - public static final int RAW_READ = 0x0001; - public static final int RAW_WRITE = 0x0002; - - // SMB packet buffer - - private byte[] m_smbbuf; - - // Packet type - - private int m_pkttype; - - // Current byte area pack/unpack position - - protected int m_pos; - protected int m_endpos; - - /** - * Default constructor - */ - public SMBPacket() - { - m_smbbuf = new byte[DEFAULT_BUFSIZE]; - InitializeBuffer(); - } - - /** - * Construct an SMB packet using the specified packet buffer. - * - * @param buf SMB packet buffer. - */ - public SMBPacket(byte[] buf) - { - m_smbbuf = buf; - } - - /** - * Construct an SMB packet of the specified size. - * - * @param siz Size of SMB packet buffer to allocate. - */ - public SMBPacket(int siz) - { - m_smbbuf = new byte[siz]; - InitializeBuffer(); - } - - /** - * Copy constructor - * - * @param pkt SMBPacket - */ - public SMBPacket(SMBPacket pkt) - { - - // Allocate a new buffer - - m_smbbuf = new byte[pkt.getBuffer().length]; - - // Copy the valid data to the new packet - - System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, pkt.getLength()); - } - - /** - * Clear the data byte count - */ - public final void clearBytes() - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(0, m_smbbuf, offset); - } - - /** - * Dump the SMB packet to the debug stream - */ - public final void DumpPacket() - { - } - - /** - * Check if the error class/code match the specified error/class - * - * @param errClass int - * @param errCode int - * @return boolean - */ - public final boolean equalsError(int errClass, int errCode) - { - if (getErrorClass() == errClass && getErrorCode() == errCode) - return true; - return false; - } - - /** - * Get the secondary command code - * - * @return Secondary command code - */ - public final int getAndXCommand() - { - return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF); - } - - /** - * Return the byte array used for the SMB packet - * - * @return Byte array used for the SMB packet. - */ - public final byte[] getBuffer() - { - return m_smbbuf; - } - - /** - * Return the total buffer size available to the SMB request - * - * @return Total SMB buffer length available. - */ - public final int getBufferLength() - { - return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Get the data byte count for the SMB packet - * - * @return Data byte count - */ - public final int getByteCount() - { - - // Calculate the offset of the byte count - - int pos = PARAMWORDS + (2 * getParameterCount()); - return (int) DataPacker.getIntelShort(m_smbbuf, pos); - } - - /** - * Get the data byte area offset within the SMB packet - * - * @return Data byte offset within the SMB packet. - */ - public final int getByteOffset() - { - - // Calculate the offset of the byte buffer - - int pCnt = getParameterCount(); - int pos = WORDCNT + (2 * pCnt) + 3; - return pos; - } - - /** - * Get the SMB command - * - * @return SMB command code. - */ - public final int getCommand() - { - return (int) (m_smbbuf[COMMAND] & 0xFF); - } - - /** - * Determine if normal or long error codes have been returned - * - * @return boolean - */ - public final boolean hasLongErrorCode() - { - if ((getFlags2() & FLG2_LONGERRORCODE) == 0) - return false; - return true; - } - - /** - * Check if the packet contains ASCII or Unicode strings - * - * @return boolean - */ - public final boolean isUnicode() - { - return (getFlags2() & FLG2_UNICODE) != 0 ? true : false; - } - - /** - * Check if the packet is using caseless filenames - * - * @return boolean - */ - public final boolean isCaseless() - { - return (getFlags() & FLG_CASELESS) != 0 ? true : false; - } - - /** - * Check if long file names are being used - * - * @return boolean - */ - public final boolean isLongFileNames() - { - return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false; - } - - /** - * Check if long error codes are being used - * - * @return boolean - */ - public final boolean isLongErrorCode() - { - return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false; - } - - /** - * Get the SMB error class - * - * @return SMB error class. - */ - public final int getErrorClass() - { - return (int) m_smbbuf[ERRORCLASS] & 0xFF; - } - - /** - * Get the SMB error code - * - * @return SMB error code. - */ - public final int getErrorCode() - { - return (int) m_smbbuf[ERROR] & 0xFF; - } - - /** - * Get the SMB flags value. - * - * @return SMB flags value. - */ - public final int getFlags() - { - return (int) m_smbbuf[FLAGS] & 0xFF; - } - - /** - * Get the SMB flags2 value. - * - * @return SMB flags2 value. - */ - public final int getFlags2() - { - return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2); - } - - /** - * Calculate the total used packet length. - * - * @return Total used packet length. - */ - public final int getLength() - { - return (getByteOffset() + getByteCount()) - SIGNATURE; - } - - /** - * Get the long SMB error code - * - * @return Long SMB error code. - */ - public final int getLongErrorCode() - { - return DataPacker.getIntelInt(m_smbbuf, ERRORCODE); - } - - /** - * Get the multiplex identifier. - * - * @return Multiplex identifier. - */ - public final int getMultiplexId() - { - return DataPacker.getIntelShort(m_smbbuf, MID); - } - - /** - * Get a parameter word from the SMB packet. - * - * @param idx Parameter index (zero based). - * @return Parameter word value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getParameterCount()) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = WORDCNT + (2 * idx) + 1; - return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); - } - - /** - * Get the specified parameter words, as an int value. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - public final int getParameterLong(int idx) - { - int pos = WORDCNT + (2 * idx) + 1; - return DataPacker.getIntelInt(m_smbbuf, pos); - } - - /** - * Get the parameter count - * - * @return Parameter word count. - */ - public final int getParameterCount() - { - return (int) m_smbbuf[WORDCNT]; - } - - /** - * Get the process indentifier (PID) - * - * @return Process identifier value. - */ - public final int getProcessId() - { - return DataPacker.getIntelShort(m_smbbuf, PID); - } - - /** - * Get the tree identifier (TID) - * - * @return Tree identifier (TID) - */ - public final int getTreeId() - { - return DataPacker.getIntelShort(m_smbbuf, TID); - } - - /** - * Get the user identifier (UID) - * - * @return User identifier (UID) - */ - public final int getUserId() - { - return DataPacker.getIntelShort(m_smbbuf, UID); - } - - /** - * Initialize the SMB packet buffer. - */ - private final void InitializeBuffer() - { - - // Set the packet signature - - m_smbbuf[SIGNATURE] = (byte) 0xFF; - m_smbbuf[SIGNATURE + 1] = (byte) 'S'; - m_smbbuf[SIGNATURE + 2] = (byte) 'M'; - m_smbbuf[SIGNATURE + 3] = (byte) 'B'; - } - - /** - * Determine if this packet is an SMB response, or command packet - * - * @return true if this SMB packet is a response, else false - */ - public final boolean isResponse() - { - int resp = getFlags(); - if ((resp & FLG_RESPONSE) != 0) - return true; - return false; - } - - /** - * Check if the response packet is valid, ie. type and flags - * - * @return true if the SMB packet is a response packet and the response is valid, else false. - */ - public final boolean isValidResponse() - { - - // Check if this is a response packet, and the correct type of packet - - if (isResponse() && getCommand() == m_pkttype) - { - - // Check if standard error codes or NT 32-bit error codes are being used - - if ((getFlags2() & FLG2_LONGERRORCODE) == 0) - { - if (getErrorClass() == SMBStatus.Success) - return true; - } - else if (getLongErrorCode() == SMBStatus.NTSuccess) - return true; - } - return false; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val byte - */ - public final void packByte(byte val) - { - m_smbbuf[m_pos++] = val; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val int - */ - public final void packByte(int val) - { - m_smbbuf[m_pos++] = (byte) val; - } - - /** - * Pack the specified bytes into the byte area - * - * @param byts byte[] - * @param len int - */ - public final void packBytes(byte[] byts, int len) - { - for (int i = 0; i < len; i++) - m_smbbuf[m_pos++] = byts[i]; - } - - /** - * Pack a string using either ASCII or Unicode into the byte area - * - * @param str String - * @param uni boolean - */ - public final void packString(String str, boolean uni) - { - - // Check for Unicode or ASCII - - if (uni) - { - - // Word align the buffer position, pack the Unicode string - - m_pos = DataPacker.wordAlign(m_pos); - DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true); - m_pos += (str.length() * 2) + 2; - } - else - { - - // Pack the ASCII string - - DataPacker.putString(str, m_smbbuf, m_pos, true); - m_pos += str.length() + 1; - } - } - - /** - * Pack a word (16 bit) value into the byte area - * - * @param val int - */ - public final void packWord(int val) - { - DataPacker.putIntelShort(val, m_smbbuf, m_pos); - m_pos += 2; - } - - /** - * Pack a 32 bit integer value into the byte area - * - * @param val int - */ - public final void packInt(int val) - { - DataPacker.putIntelInt(val, m_smbbuf, m_pos); - m_pos += 4; - } - - /** - * Pack a long integer (64 bit) value into the byte area - * - * @param val long - */ - public final void packLong(long val) - { - DataPacker.putIntelLong(val, m_smbbuf, m_pos); - m_pos += 8; - } - - /** - * Return the current byte area buffer position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Unpack a byte value from the byte area - * - * @return int - */ - public final int unpackByte() - { - return (int) m_smbbuf[m_pos++]; - } - - /** - * Unpack a block of bytes from the byte area - * - * @param len int - * @return byte[] - */ - public final byte[] unpackBytes(int len) - { - if (len <= 0) - return null; - - byte[] buf = new byte[len]; - System.arraycopy(m_smbbuf, m_pos, buf, 0, len); - m_pos += len; - return buf; - } - - /** - * Unpack a word (16 bit) value from the byte area - * - * @return int - */ - public final int unpackWord() - { - int val = DataPacker.getIntelShort(m_smbbuf, m_pos); - m_pos += 2; - return val; - } - - /** - * Unpack an integer (32 bit) value from the byte/parameter area - * - * @return int - */ - public final int unpackInt() - { - int val = DataPacker.getIntelInt(m_smbbuf, m_pos); - m_pos += 4; - return val; - } - - /** - * Unpack a long integer (64 bit) value from the byte area - * - * @return long - */ - public final long unpackLong() - { - long val = DataPacker.getIntelLong(m_smbbuf, m_pos); - m_pos += 8; - return val; - } - - /** - * Unpack a string from the byte area - * - * @param uni boolean - * @return String - */ - public final String unpackString(boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - - if (uni) - { - - // Word align the current buffer position - - m_pos = DataPacker.wordAlign(m_pos); - ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += (ret.length() * 2) + 2; - } - else - { - - // Unpack the ASCII string - - ret = DataPacker.getString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += ret.length() + 1; - } - - // Return the string - - return ret; - } - - /** - * Unpack a string from the byte area - * - * @param len int - * @param uni boolean - * @return String - */ - public final String unpackString(int len, boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - - if (uni) - { - - // Word align the current buffer position - - m_pos = DataPacker.wordAlign(m_pos); - ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len); - if (ret != null) - m_pos += (ret.length() * 2); - } - else - { - - // Unpack the ASCII string - - ret = DataPacker.getString(m_smbbuf, m_pos, len); - if (ret != null) - m_pos += ret.length(); - } - - // Return the string - - return ret; - } - - /** - * Check if there is more data in the byte area - * - * @return boolean - */ - public final boolean hasMoreData() - { - if (m_pos < m_endpos) - return true; - return false; - } - - /** - * Receive an SMB response packet. - * - * @param sess NetBIOS session to receive the SMB packet on. - * @exception java.io.IOException If an I/O error occurs. - */ - private final void ReceiveSMB(NetBIOSSession sess) throws java.io.IOException - { - - if (sess.Receive(m_smbbuf, RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) - return; - - // Not enough data received for an SMB header - - throw new java.io.IOException("Short NetBIOS receive"); - } - - /** - * Set the secondary SMB command - * - * @param cmd Secondary SMB command code. - */ - public final void setAndXCommand(int cmd) - { - - // Set the chained command packet type - - m_smbbuf[ANDXCOMMAND] = (byte) cmd; - m_smbbuf[ANDXRESERVED] = (byte) 0; - - // If the AndX command is disabled clear the offset to the chained packet - - if (cmd == PacketType.NoChainedCommand) - setParameter(1, 0); - } - - /** - * Set the data byte count for this SMB packet - * - * @param cnt Data byte count. - */ - public final void setByteCount(int cnt) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(cnt, m_smbbuf, offset); - } - - /** - * Set the data byte count for this SMB packet - */ - - public final void setByteCount() - { - int offset = getByteOffset() - 2; - int len = m_pos - getByteOffset(); - DataPacker.putIntelShort(len, m_smbbuf, offset); - } - - /** - * Set the data byte area in the SMB packet - * - * @param byts Byte array containing the data to be copied to the SMB packet. - */ - public final void setBytes(byte[] byts) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(byts.length, m_smbbuf, offset); - - offset += 2; - - for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) - ; - } - - /** - * Set the SMB command - * - * @param cmd SMB command code - */ - public final void setCommand(int cmd) - { - m_pkttype = cmd; - m_smbbuf[COMMAND] = (byte) cmd; - } - - /** - * Set the SMB error class. - * - * @param cl SMB error class. - */ - public final void setErrorClass(int cl) - { - m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF); - } - - /** - * Set the SMB error code - * - * @param sts SMB error code. - */ - public final void setErrorCode(int sts) - { - m_smbbuf[ERROR] = (byte) (sts & 0xFF); - } - - /** - * Set the SMB flags value. - * - * @param flg SMB flags value. - */ - public final void setFlags(int flg) - { - m_smbbuf[FLAGS] = (byte) flg; - } - - /** - * Set the SMB flags2 value. - * - * @param flg SMB flags2 value. - */ - public final void setFlags2(int flg) - { - DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2); - } - - /** - * Set the multiplex identifier. - * - * @param mid Multiplex identifier - */ - public final void setMultiplexId(int mid) - { - DataPacker.putIntelShort(mid, m_smbbuf, MID); - } - - /** - * Set the specified parameter word. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - public final void setParameter(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelShort(val, m_smbbuf, pos); - } - - /** - * Set the specified parameter words. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final void setParameterLong(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelInt(val, m_smbbuf, pos); - } - - /** - * Set the parameter count - * - * @param cnt Parameter word count. - */ - public final void setParameterCount(int cnt) - { - m_smbbuf[WORDCNT] = (byte) cnt; - } - - /** - * Set the process identifier value (PID). - * - * @param pid Process identifier value. - */ - public final void setProcessId(int pid) - { - DataPacker.putIntelShort(pid, m_smbbuf, PID); - } - - /** - * Set the packet sequence number, for connectionless commands. - * - * @param seq Sequence number. - */ - public final void setSeqNo(int seq) - { - DataPacker.putIntelShort(seq, m_smbbuf, SEQNO); - } - - /** - * Set the session id. - * - * @param sid Session id. - */ - public final void setSID(int sid) - { - DataPacker.putIntelShort(sid, m_smbbuf, SID); - } - - /** - * Set the tree identifier (TID) - * - * @param tid Tree identifier value. - */ - public final void setTreeId(int tid) - { - DataPacker.putIntelShort(tid, m_smbbuf, TID); - } - - /** - * Set the user identifier (UID) - * - * @param uid User identifier value. - */ - public final void setUserId(int uid) - { - DataPacker.putIntelShort(uid, m_smbbuf, UID); - } - - /** - * Align the byte area pointer on an int (32bit) boundary - */ - public final void alignBytePointer() - { - m_pos = DataPacker.longwordAlign(m_pos); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking data items from the packet - */ - public final void resetBytePointer() - { - m_pos = getByteOffset(); - m_endpos = m_pos + getByteCount(); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and - * align the buffer on an int (32bit) boundary - */ - public final void resetBytePointerAlign() - { - m_pos = DataPacker.longwordAlign(getByteOffset()); - m_endpos = m_pos + getByteCount(); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking paramaters from the packet - */ - public final void resetParameterPointer() - { - m_pos = PARAMWORDS; - } - - /** - * Set the unpack pointer to the specified offset, for AndX processing - * - * @param off int - * @param len int - */ - public final void setBytePointer(int off, int len) - { - m_pos = off; - m_endpos = m_pos + len; - } - - /** - * Skip a number of bytes in the parameter/byte area - * - * @param cnt int - */ - public final void skipBytes(int cnt) - { - m_pos += cnt; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBServer.java b/source/java/org/alfresco/filesys/smb/server/SMBServer.java deleted file mode 100644 index 260576fa05..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBServer.java +++ /dev/null @@ -1,826 +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.smb.server; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.util.Enumeration; -import java.util.UUID; -import java.util.Vector; - -import org.alfresco.filesys.netbios.NetworkSettings; -import org.alfresco.filesys.server.ServerListener; -import org.alfresco.filesys.server.SrvSessionList; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException; -import org.alfresco.filesys.server.core.ShareType; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.NetworkFileServer; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.ServerType; -import org.alfresco.filesys.smb.mailslot.HostAnnouncer; -import org.alfresco.filesys.smb.server.win32.Win32NetBIOSLanaMonitor; -import org.alfresco.filesys.smb.server.win32.Win32NetBIOSSessionSocketHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * SMB Server Class - * - *

Creates an SMB server with the specified host name. - * - *

The server can optionally announce itself so that it will appear under the Network Neighborhood, - * by enabling the host announcer in the server configuration or using the enableAnnouncer() method. - */ -public class SMBServer extends NetworkFileServer implements Runnable -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Server version - - private static final String ServerVersion = "3.5.1"; - - // Server thread - - private Thread m_srvThread; - - // Session socket handlers (NetBIOS over TCP/IP, native SMB and/or Win32 NetBIOS) - - private Vector m_sessionHandlers; - - // Host announcers, server will appear under Network Neighborhood - - private Vector m_hostAnnouncers; - - // Active session list - - private SrvSessionList m_sessions; - - // Server type flags, used when announcing the host - - private int m_srvType = ServerType.WorkStation + ServerType.Server + ServerType.NTServer; - - // Server GUID - - private UUID m_serverGUID; - - /** - * Create an SMB server using the specified configuration. - * - * @param serviceRegistry repository connection - * @param cfg ServerConfiguration - */ - public SMBServer(ServerConfiguration cfg) throws IOException - { - super("SMB", cfg); - - // Call the common constructor - CommonConstructor(); - } - - /** - * Add a shared device to the server. - * - * @param shr Shared device to be added to the server. - * @return True if the share was added successfully, else false. - */ - public final synchronized boolean addShare(SharedDevice shr) - { - - // For disk devices check if the shared device is read-only, this should also check if the - // shared device path actully exists. - - if (shr.getType() == ShareType.DISK) - { - - // Check if the disk device is read-only - - checkReadOnly(shr); - } - - // Add the share to the shared device list - - boolean sts = getConfiguration().getShares().addShare(shr); - - // Debug - - if (logger.isInfoEnabled()) - logger.info("Add Share " + shr.toString() + " : " + sts); - - // Return the add share status - - return sts; - } - - /** - * Add a session handler - * - * @param sessHandler SessionSocketHandler - */ - public final void addSessionHandler(SessionSocketHandler handler) - { - - // Check if the session handler list has been allocated - - if (m_sessionHandlers == null) - m_sessionHandlers = new Vector(); - - // Add the session handler - - m_sessionHandlers.addElement(handler); - } - - /** - * Add a host announcer - * - * @param announcer HostAnnouncer - */ - public final void addHostAnnouncer(HostAnnouncer announcer) - { - - // Check if the host announcer list has been allocated - - if (m_hostAnnouncers == null) - m_hostAnnouncers = new Vector(); - - // Add the host announcer - - m_hostAnnouncers.addElement(announcer); - } - - /** - * Add a new session to the server - * - * @param sess SMBSrvSession - */ - public final void addSession(SMBSrvSession sess) - { - - // Add the session to the session list - - m_sessions.addSession(sess); - - // Propagate the debug settings to the new session - - sess.setDebug(getConfiguration().getSessionDebugFlags()); - } - - /** - * Check if the disk share is read-only. - * - * @param shr SharedDevice - */ - protected final void checkReadOnly(SharedDevice shr) - { - - // For disk devices check if the shared device is read-only, this should also check if the - // shared device - // path actully exists. - - if (shr.getType() == ShareType.DISK) - { - - // Check if the disk device is read-only - - try - { - - // Get the device interface for the shared device - - DiskInterface disk = (DiskInterface) shr.getInterface(); - if (disk.isReadOnly(null, shr.getContext())) - { - - // The disk is read-only, mark the share as read-only - - int attr = shr.getAttributes(); - if ((attr & SharedDevice.ReadOnly) == 0) - attr += SharedDevice.ReadOnly; - shr.setAttributes(attr); - - // Debug - - if (logger.isInfoEnabled()) - logger.info("[SMB] Add Share " + shr.toString() + " : isReadOnly"); - } - } - catch (InvalidDeviceInterfaceException ex) - { - - // Shared device interface error - - if (logger.isInfoEnabled()) - logger.info("[SMB] Add Share " + shr.toString() + " : " + ex.toString()); - return; - } - catch (FileNotFoundException ex) - { - - // Shared disk device local path does not exist - - if (logger.isInfoEnabled()) - logger.info("[SMB] Add Share " + shr.toString() + " : " + ex.toString()); - return; - } - catch (IOException ex) - { - - // Shared disk device access error - - if (logger.isInfoEnabled()) - logger.info("[SMB] Add Share " + shr.toString() + " : " + ex.toString()); - return; - } - } - } - - /** - * Common constructor code. - */ - private void CommonConstructor() throws IOException - { - - // Set the server version - - setVersion(ServerVersion); - - // Create the session socket handler list - - m_sessionHandlers = new Vector(); - - // Create the active session list - - m_sessions = new SrvSessionList(); - - // Set the global domain name - - NetworkSettings.setDomain(getConfiguration().getDomainName()); - NetworkSettings.setBroadcastMask(getConfiguration().getBroadcastMask()); - } - - /** - * Close the host announcer, if enabled - */ - protected void closeHostAnnouncers() - { - - // Check if there are active host announcers - - if (m_hostAnnouncers != null) - { - - // Shutdown the host announcers - - for (int i = 0; i < m_hostAnnouncers.size(); i++) - { - - // Get the current host announcer from the active list - - HostAnnouncer announcer = (HostAnnouncer) m_hostAnnouncers.elementAt(i); - - // Shutdown the host announcer - - announcer.shutdownAnnouncer(); - } - } - } - - /** - * Close the session handlers - */ - protected void closeSessionHandlers() - { - - // Close the session handlers - - for (SessionSocketHandler handler : m_sessionHandlers) - { - - // Request the handler to shutdown - - handler.shutdownRequest(); - } - - // Clear the session handler list - - m_sessionHandlers.removeAllElements(); - } - - /** - * Delete the specified shared device from the server. - * - * @param name String Name of the shared resource to remove from the server. - * @return SharedDevice that has been removed from the server, else null. - */ - public final synchronized SharedDevice deleteShare(String name) - { - return getConfiguration().getShares().deleteShare(name); - } - - /** - * Delete temporary shares created by the share mapper for the specified session - * - * @param sess SMBSrvSession - */ - public final void deleteTemporaryShares(SMBSrvSession sess) - { - - // Delete temporary shares via the share mapper - - getConfiguration().getShareMapper().deleteShares(sess); - } - - /** - * Return an enumeration to allow the shared devices to be listed. - * - * @return java.util.Enumeration - */ - public final Enumeration enumerateShares() - { - return getConfiguration().getShares().enumerateShares(); - } - - /** - * Return the server comment. - * - * @return java.lang.String - */ - public final String getComment() - { - return getConfiguration().getComment(); - } - - /** - * Return the server type flags. - * - * @return int - */ - public final int getServerType() - { - return m_srvType; - } - - /** - * Return the per session debug flag settings. - */ - public final int getSessionDebug() - { - return getConfiguration().getSessionDebugFlags(); - } - - /** - * Return the active session list - * - * @return SrvSessionList - */ - public final SrvSessionList getSessions() - { - return m_sessions; - } - - /** - * Start the SMB server. - */ - public void run() - { - - // Indicate that the server is active - - setActive(true); - - // Check if we are running under Windows - - boolean isWindows = isWindowsNTOnwards(); - - // Generate a GUID for the server based on the server name - - m_serverGUID = UUID.nameUUIDFromBytes( getServerName().getBytes()); - - // Debug - - if (logger.isInfoEnabled()) - { - - // Dump the server name and GUID - - logger.info("SMB Server " + getServerName() + " starting"); - logger.info("GUID " + m_serverGUID); - - // Output the authenticator details - - if (getAuthenticator() != null) - logger.info("Using authenticator " + getAuthenticator().getClass().getName()); - - // Display the timezone offset/name - - if (getConfiguration().getTimeZone() != null) - logger.info("Server timezone " + getConfiguration().getTimeZone() + ", offset from UTC = " - + getConfiguration().getTimeZoneOffset() / 60 + "hrs"); - else - logger.info("Server timezone offset = " + getConfiguration().getTimeZoneOffset() / 60 + "hrs"); - - // Dump the share list - - logger.info("Shares:"); - Enumeration enm = getFullShareList(getServerName(), null).enumerateShares(); - - while (enm.hasMoreElements()) - { - SharedDevice share = enm.nextElement(); - logger.info(" " + share.toString() + " " + share.getContext().toString()); - } - } - - // Create a server socket to listen for incoming session requests - - try - { - - // Add the IPC$ named pipe shared device - - AdminSharedDevice admShare = new AdminSharedDevice(); - addShare(admShare); - - // Clear the server shutdown flag - - setShutdown(false); - - // Get the list of IP addresses the server is bound to - - getServerIPAddresses(); - - // Check if the socket connection debug flag is enabled - - boolean sockDbg = false; - - if ((getSessionDebug() & SMBSrvSession.DBG_SOCKET) != 0) - sockDbg = true; - - // Create the NetBIOS session socket handler, if enabled - - if (getConfiguration().hasNetBIOSSMB()) - { - - // Create the TCP/IP NetBIOS SMB/CIFS session handler(s), and host announcer(s) if - // enabled - - NetBIOSSessionSocketHandler.createSessionHandlers(this, sockDbg); - } - - // Create the TCP/IP SMB session socket handler, if enabled - - if (getConfiguration().hasTcpipSMB()) - { - - // Create the TCP/IP native SMB session handler(s) - - TcpipSMBSessionSocketHandler.createSessionHandlers(this, sockDbg); - } - - // Create the Win32 NetBIOS session handler, if enabled - - if (getConfiguration().hasWin32NetBIOS()) - { - - // Only enable if running under Windows - - if (isWindows == true) - { - - // Create the Win32 NetBIOS SMB handler(s), and host announcer(s) if enabled - - Win32NetBIOSSessionSocketHandler.createSessionHandlers(this, sockDbg); - } - } - - // Check if there are any session handlers installed, if not then close the server - - if (m_sessionHandlers.size() > 0 || getConfiguration().hasWin32NetBIOS()) - { - - // Wait for incoming connection requests - - while (hasShutdown() == false) - { - - // Sleep for a while - - try - { - Thread.sleep(1000L); - } - catch (InterruptedException ex) - { - } - } - } - else if (logger.isInfoEnabled()) - { - - // DEBUG - - logger.info("No valid session handlers, server closing"); - } - } - catch (SMBException ex) - { - - // Output the exception - - logger.error("SMB server error", ex); - - // Store the error, fire a server error event - - 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("Server error : ", ex); - - // Store the error, fire a server error event - - setException(ex); - fireServerEvent(ServerListener.ServerError); - } - } - - // Debug - - if (logger.isInfoEnabled()) - logger.info("SMB Server shutting down ..."); - - // Close the host announcer and session handlers - - closeHostAnnouncers(); - closeSessionHandlers(); - - // Shutdown the Win32 NetBIOS LANA monitor, if enabled - - if (isWindows && Win32NetBIOSLanaMonitor.getLanaMonitor() != null) - Win32NetBIOSLanaMonitor.getLanaMonitor().shutdownRequest(); - - // Indicate that the server is not active - - setActive(false); - fireServerEvent(ServerListener.ServerShutdown); - } - - /** - * Notify the server that a session has been closed. - * - * @param sess SMBSrvSession - */ - protected final void sessionClosed(SMBSrvSession sess) - { - - // Remove the session from the active session list - - m_sessions.removeSession(sess); - - // Notify session listeners that a session has been closed - - fireSessionClosedEvent(sess); - } - - /** - * Notify the server that a user has logged on. - * - * @param sess SMBSrvSession - */ - protected final void sessionLoggedOn(SMBSrvSession sess) - { - - // Notify session listeners that a user has logged on. - - fireSessionLoggedOnEvent(sess); - } - - /** - * Notify the server that a session has been closed. - * - * @param sess SMBSrvSession - */ - protected final void sessionOpened(SMBSrvSession sess) - { - - // Notify session listeners that a session has been closed - - fireSessionOpenEvent(sess); - } - - /** - * Shutdown the SMB server - * - * @param immediate boolean - */ - public final void shutdownServer(boolean immediate) - { - - // Indicate that the server is closing - - setShutdown(true); - - try - { - - // Close the session handlers - - closeSessionHandlers(); - } - catch (Exception ex) - { - } - - // Close the active sessions - - Enumeration enm = m_sessions.enumerate(); - - while (enm.hasMoreElements()) - { - - // Get the session id and associated session - - Integer sessId = enm.nextElement(); - SMBSrvSession sess = (SMBSrvSession) m_sessions.findSession(sessId); - - // Inform listeners that the session has been closed - - fireSessionClosedEvent(sess); - - // Close the session - - sess.closeSession(); - } - - // 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 SMB server in a seperate thread - */ - public void startServer() - { - - // Create a seperate thread to run the SMB server - - m_srvThread = new Thread(this); - m_srvThread.setName("SMB Server"); - m_srvThread.setDaemon(true); - - m_srvThread.start(); - - // Fire a server startup event - - fireServerEvent(ServerListener.ServerStartup); - } - - /** - * Determine if we are running under Windows NT onwards - * - * @return boolean - */ - private final boolean isWindowsNTOnwards() - { - - // Get the operating system name property - - String osName = System.getProperty("os.name"); - - if (osName.startsWith("Windows")) - { - if (osName.endsWith("95") || osName.endsWith("98") || osName.endsWith("ME")) - { - - // Windows 95-ME - - return false; - } - - // Looks like Windows NT onwards - - return true; - } - - // Not Windows - - return false; - } - - /** - * Get the list of local IP addresses - */ - private final void getServerIPAddresses() - { - - try - { - - // Get the local IP address list - - Enumeration enm = NetworkInterface.getNetworkInterfaces(); - Vector addrList = new Vector(); - - while (enm.hasMoreElements()) - { - - // Get the current network interface - - NetworkInterface ni = enm.nextElement(); - - // Get the address list for the current interface - - Enumeration addrs = ni.getInetAddresses(); - - while (addrs.hasMoreElements()) - addrList.add(addrs.nextElement()); - } - - // Convert the vector of addresses to an array - - if (addrList.size() > 0) - { - - // Convert the address vector to an array - - InetAddress[] inetAddrs = new InetAddress[addrList.size()]; - - // Copy the address details to the array - - for (int i = 0; i < addrList.size(); i++) - inetAddrs[i] = (InetAddress) addrList.elementAt(i); - - // Set the server IP address list - - setServerAddresses(inetAddrs); - } - } - catch (Exception ex) - { - - // DEBUG - - logger.error("Error getting local IP addresses", ex); - } - } - - /** - * Return the server GUID - * - * @return UUID - */ - public final UUID getServerGUID() - { - return m_serverGUID; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java deleted file mode 100644 index a182a7d1d7..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvException.java +++ /dev/null @@ -1,175 +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.smb.server; - -import org.alfresco.filesys.smb.SMBErrorText; -import org.alfresco.filesys.smb.SMBStatus; - -/** - * SMB exception class - *

- * This class holds the detail of an SMB network error. The SMB error class and error code are - * available to give extra detail about the error condition. - */ -public class SMBSrvException extends Exception -{ - private static final long serialVersionUID = 3976733662123341368L; - - // SMB error class - - protected int m_errorclass; - - // SMB error code - - protected int m_errorcode; - - // NT 32-bit error code - - protected int m_NTerror = -1; - - /** - * Construct an SMB exception with the specified error class/error code. - * - * @param errclass int - * @param errcode int - */ - public SMBSrvException(int errclass, int errcode) - { - super(SMBErrorText.ErrorString(errclass, errcode)); - m_errorclass = errclass; - m_errorcode = errcode; - } - - /** - * Construct an SMB exception with the specified error class/error code and additional text - * error message. - * - * @param errclass int - * @param errcode int - * @param msg String - */ - public SMBSrvException(int errclass, int errcode, String msg) - { - super(msg); - m_errorclass = errclass; - m_errorcode = errcode; - } - - /** - * Construct an SMB exception using the error class/error code in the SMB packet - * - * @param pkt SMBSrvPacket - */ - protected SMBSrvException(SMBSrvPacket pkt) - { - super(SMBErrorText.ErrorString(pkt.getErrorClass(), pkt.getErrorCode())); - m_errorclass = pkt.getErrorClass(); - m_errorcode = pkt.getErrorCode(); - } - - /** - * Construct an SMB exception with the specified error class/error code. - * - * @param nterror int - * @param errclass int - * @param errcode int - */ - public SMBSrvException(int nterror, int errclass, int errcode) - { - super(SMBErrorText.ErrorString(errclass, errcode)); - m_errorclass = errclass; - m_errorcode = errcode; - m_NTerror = nterror; - } - - /** - * Return the error class for this SMB exception. - * - * @return SMB error class. - */ - public int getErrorClass() - { - return m_errorclass; - } - - /** - * Return the error code for this SMB exception - * - * @return SMB error code - */ - public int getErrorCode() - { - return m_errorcode; - } - - /** - * Check if the NT error code has been set - * - * @return boolean - */ - public final boolean hasNTErrorCode() - { - return m_NTerror != -1 ? true : false; - } - - /** - * Return the NT error code - * - * @return int - */ - public int getNTErrorCode() { - return m_NTerror; - } - - /** - * Return the error text for the SMB exception - * - * @return Error text string. - */ - public String getErrorText() - { - if ( getNTErrorCode() != 0) - return SMBErrorText.ErrorString(SMBStatus.NTErr, getNTErrorCode()); - return SMBErrorText.ErrorString(m_errorclass, m_errorcode); - } - - /** - * Return the error message - * - * @return String - */ - public String getMessage() { - return getErrorText(); - } - - /** - * Return the exception as a string - * - * @return String - */ - public String toString() { - return getErrorText(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvPacket.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvPacket.java deleted file mode 100644 index adc28501e3..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvPacket.java +++ /dev/null @@ -1,1784 +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.smb.server; - -import java.io.DataOutputStream; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBErrorText; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.HexDump; - -/** - * SMB packet type class - */ -public class SMBSrvPacket -{ - - // Protocol type, either NetBIOS or TCP/IP native SMB - // - // All protocols reserve a 4 byte header, header is not used by Win32 NetBIOS - - public static final int PROTOCOL_NETBIOS = 0; - public static final int PROTOCOL_TCPIP = 1; - public static final int PROTOCOL_WIN32NETBIOS = 2; - - // SMB packet offsets, assuming an RFC NetBIOS transport - - public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN; - public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN; - - // SMB packet header length for a transaction type request - - public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN; - - // Minimum receive length for a valid SMB packet - - public static final int MIN_RXLEN = 32; - - // Default buffer size to allocate for SMB packets - - public static final int DEFAULT_BUFSIZE = 4096; - - // Flag bits - - public static final int FLG_SUBDIALECT = 0x01; - public static final int FLG_CASELESS = 0x08; - public static final int FLG_CANONICAL = 0x10; - public static final int FLG_OPLOCK = 0x20; - public static final int FLG_NOTIFY = 0x40; - public static final int FLG_RESPONSE = 0x80; - - // Flag2 bits - - public static final int FLG2_LONGFILENAMES = 0x0001; - public static final int FLG2_EXTENDEDATTRIB = 0x0002; - public static final int FLG2_EXTENDEDSECURITY = 0x0800; - public static final int FLG2_READIFEXE = 0x2000; - public static final int FLG2_LONGERRORCODE = 0x4000; - public static final int FLG2_UNICODE = 0x8000; - - // Security mode bits - - public static final int SEC_USER = 0x0001; - public static final int SEC_ENCRYPT = 0x0002; - - // Raw mode bits - - public static final int RAW_READ = 0x0001; - public static final int RAW_WRITE = 0x0002; - - // No chained AndX command indicator - - public static final int NO_ANDX_CMD = 0x00FF; - - // SMB packet buffer - - private byte[] m_smbbuf; - - // Received data length (actual buffer used) - - private int m_rxLen; - - // Packet type - - private int m_pkttype; - - // Current byte area pack/unpack position - - protected int m_pos; - protected int m_endpos; - - /** - * Default constructor - */ - - public SMBSrvPacket() - { - m_smbbuf = new byte[DEFAULT_BUFSIZE]; - InitializeBuffer(); - } - - /** - * Construct an SMB packet using the specified packet buffer. - * - * @param buf SMB packet buffer. - */ - - public SMBSrvPacket(byte[] buf) - { - m_smbbuf = buf; - } - - /** - * Construct an SMB packet of the specified size. - * - * @param siz Size of SMB packet buffer to allocate. - */ - - public SMBSrvPacket(int siz) - { - m_smbbuf = new byte[siz]; - InitializeBuffer(); - } - - /** - * Copy constructor. - * - * @param buf SMB packet buffer. - */ - - public SMBSrvPacket(SMBSrvPacket pkt) - { - - // Create a packet buffer of the same size - - m_smbbuf = new byte[pkt.getBuffer().length]; - - // Copy the data from the specified packet - - System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, m_smbbuf.length); - } - - /** - * Copy constructor. - * - * @param buf SMB packet buffer. - * @param len Length of packet to be copied - */ - - public SMBSrvPacket(SMBSrvPacket pkt, int len) - { - - // Create a packet buffer of the same size - - m_smbbuf = new byte[pkt.getBuffer().length]; - - // Copy the data from the specified packet - - System.arraycopy(pkt.getBuffer(), 0, m_smbbuf, 0, len); - } - - /** - * Check the SMB AndX command for the required minimum parameter count and byte count. - * - * @param off Offset to the AndX command within the SMB packet. - * @param reqWords Minimum number of parameter words expected. - * @param reqBytes Minimum number of bytes expected. - * @return boolean True if the packet passes the checks, else false. - */ - public final boolean checkAndXPacketIsValid(int off, int reqWords, int reqBytes) - { - - // Check the received parameter word count - - if (getAndXParameterCount(off) < reqWords || getAndXByteCount(off) < reqBytes) - return false; - - // Initial SMB packet checks passed - - return true; - } - - /** - * Check the SMB packet for a valid SMB signature, and the required minimum parameter count and - * byte count. - * - * @param reqWords Minimum number of parameter words expected. - * @param reqBytes Minimum number of bytes expected. - * @return boolean True if the packet passes the checks, else false. - */ - public final boolean checkPacketIsValid(int reqWords, int reqBytes) - { - - // Check for the SMB signature block - - if (m_smbbuf[SIGNATURE] != (byte) 0xFF || m_smbbuf[SIGNATURE + 1] != 'S' || m_smbbuf[SIGNATURE + 2] != 'M' - || m_smbbuf[SIGNATURE + 3] != 'B') - return false; - - // Check the received parameter word count - - if (getParameterCount() < reqWords || getByteCount() < reqBytes) - return false; - - // Initial SMB packet checks passed - - return true; - } - - /** - * Check the SMB packet has a valid SMB signature. - * - * @return boolean True if the SMB signature is valid, else false. - */ - public final boolean checkPacketSignature() - { - - // Check for the SMB signature block - - if (m_smbbuf[SIGNATURE] == (byte) 0xFF && m_smbbuf[SIGNATURE + 1] == 'S' && m_smbbuf[SIGNATURE + 2] == 'M' - && m_smbbuf[SIGNATURE + 3] == 'B') - return true; - - // Invalid SMB packet format - - return false; - } - - /** - * Check if the SMB packet has an SMB2 signature. - * - * @return boolean True if the packet has an SMB2 signature, else false. - */ - public final boolean isSMB2() - { - - // Check for the SMB2 signature block - - if (m_smbbuf[SIGNATURE] == (byte) 0xFE && m_smbbuf[SIGNATURE + 1] == 'S' && m_smbbuf[SIGNATURE + 2] == 'M' - && m_smbbuf[SIGNATURE + 3] == 'B') - return true; - - // Not an SMB2 packet - - return false; - } - - /** - * Clear the data byte count - */ - - public final void clearBytes() - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort((short) 0, m_smbbuf, offset); - } - - /** - * Dump the SMB packet to the debug stream - */ - - public final void DumpPacket() - { - DumpPacket(false); - } - - /** - * Dump the SMB packet to the debug stream - * - * @param dumpAll boolean - */ - - public final void DumpPacket(boolean dumpAll) - { - - // Dump the command type - - int pCount = getParameterCount(); - System.out.print("** SMB Packet Type: " + getPacketTypeString()); - - // Check if this is a response packet - - if (isResponse()) - System.out.println(" [Response]"); - else - System.out.println(); - - // Dump flags/secondary flags - - if (true) - { - - // Dump the packet length - - System.out.println("** SMB Packet Dump"); - System.out.println("Packet Length : " + getLength()); - System.out.println("Byte Offset: " + getByteOffset() + ", Byte Count: " + getByteCount()); - - // Dump the flags - - System.out.println("Flags: " + Integer.toBinaryString(getFlags())); - System.out.println("Flags2: " + Integer.toBinaryString(getFlags2())); - - // Dump various ids - - System.out.println("TID: " + getTreeId()); - System.out.println("PID: " + getProcessId()); - System.out.println("UID: " + getUserId()); - System.out.println("MID: " + getMultiplexId()); - - // Dump parameter words/count - - System.out.println("Parameter Words: " + pCount); - StringBuffer str = new StringBuffer(); - - for (int i = 0; i < pCount; i++) - { - str.setLength(0); - str.append(" P"); - str.append(Integer.toString(i + 1)); - str.append(" = "); - str.append(Integer.toString(getParameter(i))); - while (str.length() < 16) - str.append(" "); - str.append("0x"); - str.append(Integer.toHexString(getParameter(i))); - System.out.println(str.toString()); - } - - // Response packet fields - - if (isResponse()) - { - - // Dump the error code - - System.out.println("Error: 0x" + Integer.toHexString(getErrorCode())); - System.out.print("Error Class: "); - - switch (getErrorClass()) - { - case SMBStatus.Success: - System.out.println("SUCCESS"); - break; - case SMBStatus.ErrDos: - System.out.println("ERRDOS"); - break; - case SMBStatus.ErrSrv: - System.out.println("ERRSRV"); - break; - case SMBStatus.ErrHrd: - System.out.println("ERRHRD"); - break; - case SMBStatus.ErrCmd: - System.out.println("ERRCMD"); - break; - default: - System.out.println("0x" + Integer.toHexString(getErrorClass())); - break; - } - - // Display the SMB error text - - System.out.print("Error Text: "); - System.out.println(SMBErrorText.ErrorString(getErrorClass(), getErrorCode())); - } - } - - // Dump the raw data - - if (true) - { - System.out.println("********** Raw SMB Data Dump **********"); - if (dumpAll) - HexDump.Dump(m_smbbuf, getLength(), 4); - else - HexDump.Dump(m_smbbuf, getLength() < 100 ? getLength() : 100, 4); - } - - System.out.println(); - System.out.flush(); - } - - /** - * Get the data byte count for the SMB AndX command. - * - * @param off Offset to the AndX command. - * @return Data byte count - */ - - public final int getAndXByteCount(int off) - { - - // Calculate the offset of the byte count - - int pos = off + 1 + (2 * getParameterCount()); - return (int) DataPacker.getIntelShort(m_smbbuf, pos); - } - - /** - * Get the AndX data byte area offset within the SMB packet - * - * @param off Offset to the AndX command. - * @return Data byte offset within the SMB packet. - */ - - public final int getAndXByteOffset(int off) - { - - // Calculate the offset of the byte buffer - - int pCnt = getAndXParameterCount(off); - int pos = off + (2 * pCnt) + 3; // parameter words + paramter count byte + byte data length - // word - return pos; - } - - /** - * Get the secondary command code - * - * @return Secondary command code - */ - - public final int getAndXCommand() - { - return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF); - } - - /** - * Get an AndX parameter word from the SMB packet. - * - * @param off Offset to the AndX command. - * @param idx Parameter index (zero based). - * @return Parameter word value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - - public final int getAndXParameter(int off, int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getAndXParameterCount(off)) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = off + (2 * idx) + 1; - return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); - } - - /** - * Get an AndX parameter integer from the SMB packet. - * - * @param off Offset to the AndX command. - * @param idx Parameter index (zero based). - * @return Parameter integer value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - - public final int getAndXParameterLong(int off, int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getAndXParameterCount(off)) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = off + (2 * idx) + 1; - return DataPacker.getIntelInt(m_smbbuf, pos); - } - - /** - * Get the AndX command parameter count. - * - * @param off Offset to the AndX command. - * @return Parameter word count. - */ - - public final int getAndXParameterCount(int off) - { - return (int) m_smbbuf[off]; - } - - /** - * Return the byte array used for the SMB packet - * - * @return Byte array used for the SMB packet. - */ - - public final byte[] getBuffer() - { - return m_smbbuf; - } - - /** - * Return the total buffer size available to the SMB request - * - * @return Total SMB buffer length available. - */ - - public final int getBufferLength() - { - return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Get the data byte count for the SMB packet - * - * @return Data byte count - */ - - public final int getByteCount() - { - - // Calculate the offset of the byte count - - int pos = PARAMWORDS + (2 * getParameterCount()); - return (int) DataPacker.getIntelShort(m_smbbuf, pos); - } - - /** - * Get the data byte area offset within the SMB packet - * - * @return Data byte offset within the SMB packet. - */ - - public final int getByteOffset() - { - - // Calculate the offset of the byte buffer - - int pCnt = getParameterCount(); - int pos = WORDCNT + (2 * pCnt) + 3; - return pos; - } - - /** - * Get the SMB command - * - * @return SMB command code. - */ - - public final int getCommand() - { - return (int) (m_smbbuf[COMMAND] & 0xFF); - } - - /** - * Get the SMB error class - * - * @return SMB error class. - */ - - public final int getErrorClass() - { - return (int) m_smbbuf[ERRORCLASS] & 0xFF; - } - - /** - * Get the SMB error code - * - * @return SMB error code. - */ - - public final int getErrorCode() - { - return (int) m_smbbuf[ERROR] & 0xFF; - } - - /** - * Get the SMB flags value. - * - * @return SMB flags value. - */ - - public final int getFlags() - { - return (int) m_smbbuf[FLAGS] & 0xFF; - } - - /** - * Get the SMB flags2 value. - * - * @return SMB flags2 value. - */ - public final int getFlags2() - { - return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2); - } - - /** - * Calculate the total used packet length. - * - * @return Total used packet length. - */ - public final int getLength() - { - - // Get the length of the first command in the packet - - return (getByteOffset() + getByteCount()) - SIGNATURE; - } - - /** - * Calculate the total packet length, including header - * - * @return Total packet length. - */ - public final int getPacketLength() - { - - // Get the length of the first command in the packet - - return getByteOffset() + getByteCount(); - } - - /** - * Return the available buffer space for data bytes - * - * @return int - */ - public final int getAvailableLength() - { - return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset()); - } - - /** - * Return the available buffer space for data bytes for the specified buffer length - * - * @param len int - * @return int - */ - public final int getAvailableLength(int len) - { - return len - DataPacker.longwordAlign(getByteOffset()); - } - - /** - * Get the long SMB error code - * - * @return Long SMB error code. - */ - public final int getLongErrorCode() - { - return DataPacker.getIntelInt(m_smbbuf, ERRORCODE); - } - - /** - * Get the multiplex identifier. - * - * @return Multiplex identifier. - */ - public final int getMultiplexId() - { - return DataPacker.getIntelShort(m_smbbuf, MID); - } - - /** - * Dump the packet type - * - * @return String - */ - public final String getPacketTypeString() - { - - String pktType = ""; - - switch (getCommand()) - { - case PacketType.Negotiate: - pktType = "NEGOTIATE"; - break; - case PacketType.SessionSetupAndX: - pktType = "SESSION_SETUP"; - break; - case PacketType.TreeConnect: - pktType = "TREE_CONNECT"; - break; - case PacketType.TreeConnectAndX: - pktType = "TREE_CONNECT_ANDX"; - break; - case PacketType.TreeDisconnect: - pktType = "TREE_DISCONNECT"; - break; - case PacketType.Search: - pktType = "SEARCH"; - break; - case PacketType.OpenFile: - pktType = "OPEN_FILE"; - break; - case PacketType.OpenAndX: - pktType = "OPEN_ANDX"; - break; - case PacketType.ReadFile: - pktType = "READ_FILE"; - break; - case PacketType.WriteFile: - pktType = "WRITE_FILE"; - break; - case PacketType.CloseFile: - pktType = "CLOSE_FILE"; - break; - case PacketType.CreateFile: - pktType = "CREATE_FILE"; - break; - case PacketType.GetFileAttributes: - pktType = "GET_FILE_INFO"; - break; - case PacketType.DiskInformation: - pktType = "GET_DISK_INFO"; - break; - case PacketType.CheckDirectory: - pktType = "CHECK_DIRECTORY"; - break; - case PacketType.RenameFile: - pktType = "RENAME_FILE"; - break; - case PacketType.DeleteDirectory: - pktType = "DELETE_DIRECTORY"; - break; - case PacketType.GetPrintQueue: - pktType = "GET_PRINT_QUEUE"; - break; - case PacketType.Transaction2: - pktType = "TRANSACTION2"; - break; - case PacketType.Transaction: - pktType = "TRANSACTION"; - break; - case PacketType.Transaction2Second: - pktType = "TRANSACTION2_SECONDARY"; - break; - case PacketType.TransactionSecond: - pktType = "TRANSACTION_SECONDARY"; - break; - case PacketType.Echo: - pktType = "ECHO"; - break; - case PacketType.QueryInformation2: - pktType = "QUERY_INFORMATION_2"; - break; - case PacketType.WriteAndClose: - pktType = "WRITE_AND_CLOSE"; - break; - case PacketType.SetInformation2: - pktType = "SET_INFORMATION_2"; - break; - case PacketType.FindClose2: - pktType = "FIND_CLOSE2"; - break; - case PacketType.LogoffAndX: - pktType = "LOGOFF_ANDX"; - break; - case PacketType.NTCancel: - pktType = "NTCANCEL"; - break; - case PacketType.NTCreateAndX: - pktType = "NTCREATE_ANDX"; - break; - case PacketType.NTTransact: - pktType = "NTTRANSACT"; - break; - case PacketType.NTTransactSecond: - pktType = "NTTRANSACT_SECONDARY"; - break; - case PacketType.ReadAndX: - pktType = "READ_ANDX"; - break; - default: - pktType = "0x" + Integer.toHexString(getCommand()); - break; - } - - // Return the packet type string - - return pktType; - } - - /** - * Get a parameter word from the SMB packet. - * - * @param idx Parameter index (zero based). - * @return Parameter word value. - * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range. - */ - - public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException - { - - // Range check the parameter index - - if (idx > getParameterCount()) - throw new java.lang.IndexOutOfBoundsException(); - - // Calculate the parameter word offset - - int pos = WORDCNT + (2 * idx) + 1; - return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); - } - - /** - * Get the parameter count - * - * @return Parameter word count. - */ - - public final int getParameterCount() - { - return (int) m_smbbuf[WORDCNT]; - } - - /** - * Get the specified parameter words, as an int value. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final int getParameterLong(int idx) - { - int pos = WORDCNT + (2 * idx) + 1; - return DataPacker.getIntelInt(m_smbbuf, pos); - } - - /** - * Get the process indentifier (PID) - * - * @return Process identifier value. - */ - public final int getProcessId() - { - return DataPacker.getIntelShort(m_smbbuf, PID); - } - - /** - * Get the actual received data length. - * - * @return int - */ - public final int getReceivedLength() - { - return m_rxLen; - } - - /** - * Get the session identifier (SID) - * - * @return Session identifier (SID) - */ - - public final int getSID() - { - return DataPacker.getIntelShort(m_smbbuf, SID); - } - - /** - * Get the tree identifier (TID) - * - * @return Tree identifier (TID) - */ - - public final int getTreeId() - { - return DataPacker.getIntelShort(m_smbbuf, TID); - } - - /** - * Get the user identifier (UID) - * - * @return User identifier (UID) - */ - - public final int getUserId() - { - return DataPacker.getIntelShort(m_smbbuf, UID); - } - - /** - * Determine if there is a secondary command in this packet. - * - * @return Secondary command code - */ - - public final boolean hasAndXCommand() - { - - // Check if there is a secondary command - - int andxCmd = getAndXCommand(); - - if (andxCmd != 0xFF && andxCmd != 0) - return true; - return false; - } - - /** - * Initialize the SMB packet buffer. - */ - - private final void InitializeBuffer() - { - - // Set the packet signature - - m_smbbuf[SIGNATURE] = (byte) 0xFF; - m_smbbuf[SIGNATURE + 1] = (byte) 'S'; - m_smbbuf[SIGNATURE + 2] = (byte) 'M'; - m_smbbuf[SIGNATURE + 3] = (byte) 'B'; - } - - /** - * Determine if this packet is an SMB response, or command packet - * - * @return true if this SMB packet is a response, else false - */ - - public final boolean isResponse() - { - int resp = getFlags(); - if ((resp & FLG_RESPONSE) != 0) - return true; - return false; - } - - /** - * Check if the response packet is valid, ie. type and flags - * - * @return true if the SMB packet is a response packet and the response is valid, else false. - */ - - public final boolean isValidResponse() - { - - // Check if this is a response packet, and the correct type of packet - - if (isResponse() && getCommand() == m_pkttype && this.getErrorClass() == SMBStatus.Success) - return true; - return false; - } - - /** - * Check if the packet contains ASCII or Unicode strings - * - * @return boolean - */ - public final boolean isUnicode() - { - return (getFlags2() & FLG2_UNICODE) != 0 ? true : false; - } - - /** - * Check if the packet is using caseless filenames - * - * @return boolean - */ - public final boolean isCaseless() - { - return (getFlags() & FLG_CASELESS) != 0 ? true : false; - } - - /** - * Check if long file names are being used - * - * @return boolean - */ - public final boolean isLongFileNames() - { - return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false; - } - - /** - * Check if long error codes are being used - * - * @return boolean - */ - public final boolean isLongErrorCode() - { - return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val byte - */ - public final void packByte(byte val) - { - m_smbbuf[m_pos++] = val; - } - - /** - * Pack a byte (8 bit) value into the byte area - * - * @param val int - */ - public final void packByte(int val) - { - m_smbbuf[m_pos++] = (byte) val; - } - - /** - * Pack the specified bytes into the byte area - * - * @param byts byte[] - * @param len int - */ - public final void packBytes(byte[] byts, int len) - { - for (int i = 0; i < len; i++) - m_smbbuf[m_pos++] = byts[i]; - } - - /** - * Pack a string using either ASCII or Unicode into the byte area - * - * @param str String - * @param uni boolean - */ - public final void packString(String str, boolean uni) - { - - // Check for Unicode or ASCII - - if (uni) - { - - // Word align the buffer position, pack the Unicode string - - m_pos = DataPacker.wordAlign(m_pos); - DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true); - m_pos += (str.length() * 2) + 2; - } - else - { - - // Pack the ASCII string - - DataPacker.putString(str, m_smbbuf, m_pos, true); - m_pos += str.length() + 1; - } - } - - /** - * Pack a string using either ASCII or Unicode into the byte area - * - * @param str String - * @param uni boolean - * @param nul boolean - */ - public final void packString(String str, boolean uni, boolean nul) - { - - // Check for Unicode or ASCII - - if (uni) - { - - // Word align the buffer position, pack the Unicode string - - m_pos = DataPacker.wordAlign(m_pos); - DataPacker.putUnicodeString(str, m_smbbuf, m_pos, nul); - m_pos += (str.length() * 2); - if (nul == true) - m_pos += 2; - } - else - { - - // Pack the ASCII string - - DataPacker.putString(str, m_smbbuf, m_pos, true); - m_pos += str.length(); - if (nul == true) - m_pos++; - } - } - - /** - * Pack a word (16 bit) value into the byte area - * - * @param val int - */ - public final void packWord(int val) - { - DataPacker.putIntelShort(val, m_smbbuf, m_pos); - m_pos += 2; - } - - /** - * Pack an integer (32 bit) value into the byte area - * - * @param val int - */ - public final void packInt(int val) - { - DataPacker.putIntelInt(val, m_smbbuf, m_pos); - m_pos += 4; - } - - /** - * Pack a long integer (64 bit) value into the byte area - * - * @param val long - */ - public final void packLong(long val) - { - DataPacker.putIntelLong(val, m_smbbuf, m_pos); - m_pos += 8; - } - - /** - * Return the current byte area buffer position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Unpack a byte value from the byte area - * - * @return int - */ - public final int unpackByte() - { - return (int) m_smbbuf[m_pos++]; - } - - /** - * Unpack a block of bytes from the byte area - * - * @param len int - * @return byte[] - */ - public final byte[] unpackBytes(int len) - { - if (len <= 0) - return null; - - byte[] buf = new byte[len]; - System.arraycopy(m_smbbuf, m_pos, buf, 0, len); - m_pos += len; - return buf; - } - - /** - * Unpack a word (16 bit) value from the byte area - * - * @return int - */ - public final int unpackWord() - { - int val = DataPacker.getIntelShort(m_smbbuf, m_pos); - m_pos += 2; - return val; - } - - /** - * Unpack an integer (32 bit) value from the byte area - * - * @return int - */ - public final int unpackInt() - { - int val = DataPacker.getIntelInt(m_smbbuf, m_pos); - m_pos += 4; - return val; - } - - /** - * Unpack a long integer (64 bit) value from the byte area - * - * @return long - */ - public final long unpackLong() - { - long val = DataPacker.getIntelLong(m_smbbuf, m_pos); - m_pos += 8; - return val; - } - - /** - * Unpack a string from the byte area - * - * @param uni boolean - * @return String - */ - public final String unpackString(boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - - if (uni) - { - - // Word align the current buffer position - - m_pos = DataPacker.wordAlign(m_pos); - ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += (ret.length() * 2) + 2; - } - else - { - - // Unpack the ASCII string - - ret = DataPacker.getString(m_smbbuf, m_pos, 255); - if (ret != null) - m_pos += ret.length() + 1; - } - - // Return the string - - return ret; - } - - /** - * Check if there is more data in the byte area - * - * @return boolean - */ - public final boolean hasMoreData() - { - if (m_pos < m_endpos) - return true; - return false; - } - - /** - * Send the SMB response packet. - * - * @param out Output stream associated with the session socket. - * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP - * @exception java.io.IOException If an I/O error occurs. - */ - public final void SendResponseSMB(DataOutputStream out, int proto) throws java.io.IOException - { - - // Use the packet length - - int siz = getLength(); - SendResponseSMB(out, proto, siz); - } - - /** - * Send the SMB response packet. - * - * @param out Output stream associated with the session socket. - * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP - * @param len Packet length - * @exception java.io.IOException If an I/O error occurs. - */ - public final void SendResponseSMB(DataOutputStream out, int proto, int len) throws java.io.IOException - { - - // Make sure the response flag is set - - int flg = getFlags(); - if ((flg & FLG_RESPONSE) == 0) - setFlags(flg + FLG_RESPONSE); - - // NetBIOS SMB protocol - - if (proto == PROTOCOL_NETBIOS) - { - - // Fill in the NetBIOS message header, this is already allocated as - // part of the users buffer. - - m_smbbuf[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; - m_smbbuf[1] = (byte) 0; - - DataPacker.putShort((short) len, m_smbbuf, 2); - } - else - { - - // TCP/IP native SMB - - DataPacker.putInt(len, m_smbbuf, 0); - } - - // Output the data packet - - len += RFCNetBIOSProtocol.HEADER_LEN; - out.write(m_smbbuf, 0, len); - } - - /** - * Send a success SMB response packet. - * - * @param out Output stream associated with the session socket. - * @param proto Protocol type, either PROTOCOL_NETBIOS or PROTOCOL_TCPIP - * @exception java.io.IOException If an I/O error occurs. - */ - - public final void SendSuccessSMB(DataOutputStream out, int proto) throws java.io.IOException - { - - // Clear the parameter and byte counts - - setParameterCount(0); - setByteCount(0); - - // Send the success response - - SendResponseSMB(out, proto); - } - - /** - * Set the AndX data byte count for this SMB packet. - * - * @param off AndX command offset. - * @param cnt Data byte count. - */ - - public final void setAndXByteCount(int off, int cnt) - { - int offset = getAndXByteOffset(off) - 2; - DataPacker.putIntelShort(cnt, m_smbbuf, offset); - } - - /** - * Set the AndX data byte area in the SMB packet - * - * @param off Offset to the AndX command. - * @param byts Byte array containing the data to be copied to the SMB packet. - */ - - public final void setAndXBytes(int off, byte[] byts) - { - int offset = getAndXByteOffset(off) - 2; - DataPacker.putIntelShort(byts.length, m_smbbuf, offset); - - offset += 2; - - for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) - ; - } - - /** - * Set the secondary SMB command - * - * @param cmd Secondary SMB command code. - */ - - public final void setAndXCommand(int cmd) - { - m_smbbuf[ANDXCOMMAND] = (byte) cmd; - m_smbbuf[ANDXRESERVED] = (byte) 0; - } - - /** - * Set the AndX command for an AndX command block. - * - * @param off Offset to the current AndX command. - * @param cmd Secondary SMB command code. - */ - - public final void setAndXCommand(int off, int cmd) - { - m_smbbuf[off + 1] = (byte) cmd; - m_smbbuf[off + 2] = (byte) 0; - } - - /** - * Set the specified AndX parameter word. - * - * @param off Offset to the AndX command. - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final void setAndXParameter(int off, int idx, int val) - { - int pos = off + (2 * idx) + 1; - DataPacker.putIntelShort(val, m_smbbuf, pos); - } - - /** - * Set the AndX parameter count - * - * @param off Offset to the AndX command. - * @param cnt Parameter word count. - */ - - public final void setAndXParameterCount(int off, int cnt) - { - m_smbbuf[off] = (byte) cnt; - } - - /** - * Set the data byte count for this SMB packet - * - * @param cnt Data byte count. - */ - - public final void setByteCount(int cnt) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(cnt, m_smbbuf, offset); - } - - /** - * Set the data byte count for this SMB packet - */ - - public final void setByteCount() - { - int offset = getByteOffset() - 2; - int len = m_pos - getByteOffset(); - DataPacker.putIntelShort(len, m_smbbuf, offset); - } - - /** - * Set the data byte area in the SMB packet - * - * @param byts Byte array containing the data to be copied to the SMB packet. - */ - - public final void setBytes(byte[] byts) - { - int offset = getByteOffset() - 2; - DataPacker.putIntelShort(byts.length, m_smbbuf, offset); - - offset += 2; - - for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) - ; - } - - /** - * Set the SMB command - * - * @param cmd SMB command code - */ - - public final void setCommand(int cmd) - { - m_pkttype = cmd; - m_smbbuf[COMMAND] = (byte) cmd; - } - - /** - * Set the error class and code. - * - * @param errCode int - * @param errClass int - */ - public final void setError(int errCode, int errClass) - { - - // Set the error class and code - - setErrorClass(errClass); - setErrorCode(errCode); - } - - /** - * Set the error class/code. - * - * @param longError boolean - * @param ntErr int - * @param errCode int - * @param errClass int - */ - public final void setError(boolean longError, int ntErr, int errCode, int errClass) - { - - // Check if the error code is a long/NT status code - - if (longError) - { - - // Set the NT status code - - setLongErrorCode(ntErr); - - // Set the NT status code flag - - if (isLongErrorCode() == false) - setFlags2(getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE); - } - else - { - - // Set the error class and code - - setErrorClass(errClass); - setErrorCode(errCode); - } - } - - /** - * Set the SMB error class. - * - * @param cl SMB error class. - */ - - public final void setErrorClass(int cl) - { - m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF); - } - - /** - * Set the SMB error code - * - * @param sts SMB error code. - */ - - public final void setErrorCode(int sts) - { - m_smbbuf[ERROR] = (byte) (sts & 0xFF); - } - - /** - * Set the long SMB error code - * - * @param err Long SMB error code. - */ - - public final void setLongErrorCode(int err) - { - DataPacker.putIntelInt(err, m_smbbuf, ERRORCODE); - } - - /** - * Set the SMB flags value. - * - * @param flg SMB flags value. - */ - - public final void setFlags(int flg) - { - m_smbbuf[FLAGS] = (byte) flg; - } - - /** - * Set the SMB flags2 value. - * - * @param flg SMB flags2 value. - */ - - public final void setFlags2(int flg) - { - DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2); - } - - /** - * Set the multiplex identifier. - * - * @param mid Multiplex identifier - */ - - public final void setMultiplexId(int mid) - { - DataPacker.putIntelShort(mid, m_smbbuf, MID); - } - - /** - * Set the specified parameter word. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final void setParameter(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelShort(val, m_smbbuf, pos); - } - - /** - * Set the parameter count - * - * @param cnt Parameter word count. - */ - - public final void setParameterCount(int cnt) - { - - // Set the parameter count - - m_smbbuf[WORDCNT] = (byte) cnt; - - // Reset the byte area pointer - - resetBytePointer(); - } - - /** - * Set the specified parameter words. - * - * @param idx Parameter index (zero based). - * @param val Parameter value. - */ - - public final void setParameterLong(int idx, int val) - { - int pos = WORDCNT + (2 * idx) + 1; - DataPacker.putIntelInt(val, m_smbbuf, pos); - } - - /** - * Set the pack/unpack position - * - * @param pos int - */ - public final void setPosition(int pos) - { - m_pos = pos; - } - - /** - * Set the process identifier value (PID). - * - * @param pid Process identifier value. - */ - - public final void setProcessId(int pid) - { - DataPacker.putIntelShort(pid, m_smbbuf, PID); - } - - /** - * Set the actual received data length. - * - * @param len int - */ - public final void setReceivedLength(int len) - { - m_rxLen = len; - } - - /** - * Set the packet sequence number, for connectionless commands. - * - * @param seq Sequence number. - */ - - public final void setSeqNo(int seq) - { - DataPacker.putIntelShort(seq, m_smbbuf, SEQNO); - } - - /** - * Set the session id. - * - * @param sid Session id. - */ - public final void setSID(int sid) - { - DataPacker.putIntelShort(sid, m_smbbuf, SID); - } - - /** - * Set the tree identifier (TID) - * - * @param tid Tree identifier value. - */ - - public final void setTreeId(int tid) - { - DataPacker.putIntelShort(tid, m_smbbuf, TID); - } - - /** - * Set the user identifier (UID) - * - * @param uid User identifier value. - */ - - public final void setUserId(int uid) - { - DataPacker.putIntelShort(uid, m_smbbuf, UID); - } - - /** - * Reset the byte pointer area for packing/unpacking data items from the packet - */ - public final void resetBytePointer() - { - m_pos = getByteOffset(); - m_endpos = m_pos + getByteCount(); - } - - /** - * Set the unpack pointer to the specified offset, for AndX processing - * - * @param off int - * @param len int - */ - public final void setBytePointer(int off, int len) - { - m_pos = off; - m_endpos = m_pos + len; - } - - /** - * Align the byte area pointer on an int (32bit) boundary - */ - public final void alignBytePointer() - { - m_pos = DataPacker.longwordAlign(m_pos); - } - - /** - * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and - * align the buffer on an int (32bit) boundary - */ - public final void resetBytePointerAlign() - { - m_pos = DataPacker.longwordAlign(getByteOffset()); - m_endpos = m_pos + getByteCount(); - } - - /** - * Skip a number of bytes in the parameter/byte area - * - * @param cnt int - */ - public final void skipBytes(int cnt) - { - m_pos += cnt; - } - - /** - * Set the data buffer - * - * @param buf byte[] - */ - public final void setBuffer(byte[] buf) - { - m_smbbuf = buf; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java deleted file mode 100644 index 53aa5a6cbd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvSession.java +++ /dev/null @@ -1,1875 +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.smb.server; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.SocketException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.alfresco.filesys.netbios.NetBIOSException; -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.NetBIOSPacket; -import org.alfresco.filesys.netbios.NetBIOSSession; -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.AuthenticatorException; -import org.alfresco.filesys.server.auth.CifsAuthenticator; -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.smb.Capability; -import org.alfresco.filesys.smb.DataType; -import org.alfresco.filesys.smb.Dialect; -import org.alfresco.filesys.smb.DialectSelector; -import org.alfresco.filesys.smb.NTTime; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.SMBDate; -import org.alfresco.filesys.smb.SMBErrorText; -import org.alfresco.filesys.smb.SMBStatus; -import org.alfresco.filesys.smb.server.notify.NotifyRequest; -import org.alfresco.filesys.smb.server.notify.NotifyRequestList; -import org.alfresco.filesys.util.DataPacker; -import org.alfresco.filesys.util.StringList; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * SMB Session Class - * - *

- * The SMB server creates a server session object for each incoming session request. - *

- * The server session holds the context of a particular session, including the list of open files - * and active searches. - */ -public class SMBSrvSession extends SrvSession implements Runnable -{ - // Debug logging - - private static Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Define the default receive buffer size to allocate. - - public static final int DefaultBufferSize = 0x010000 + RFCNetBIOSProtocol.HEADER_LEN; - public static final int LanManBufferSize = 8192; - - // Default and maximum number of connection slots - - public static final int DefaultConnections = 4; - public static final int MaxConnections = 16; - - // Maximum multiplexed packets allowed (client can send up to this many SMBs before waiting for - // a response) - // - // Setting NTMaxMultiplexed to one will disable asynchronous notifications on the client - - public static final int LanManMaxMultiplexed = 1; - public static final int NTMaxMultiplexed = 4; - - // Maximum number of virtual circuits - - public static final int MaxVirtualCircuits = 0; - - // Packet handler used to send/receive SMB packets over a particular protocol - - private PacketHandler m_pktHandler; - - // Packet buffer for received data and received data length. - - private byte[] m_buf; - private int m_rxlen; - - // SMB packet used for response - - private SMBSrvPacket m_smbPkt; - - // Protocol handler for this session, depends upon the negotiated SMB dialect - - private ProtocolHandler m_handler; - - // SMB session state. - - private int m_state = SMBSrvSessionState.NBSESSREQ; - - // SMB dialect that this session has negotiated to use. - - private int m_dialect = Dialect.Unknown; - - // Callers NetBIOS name and target name - - private String m_callerNBName; - private String m_targetNBName; - - // Notify change requests and notifications pending flag - - private NotifyRequestList m_notifyList; - private boolean m_notifyPending; - - // Default SMB/CIFS flags and flags2, ORed with the SMB packet flags/flags2 before sending a - // response to the client. - - private int m_defFlags; - private int m_defFlags2; - - // Asynchrnous response packet queue - // - // Contains SMB response packets that could not be sent due to SMB requests being processed. The - // asynchronous responses must be sent after any pending requests have been processed as the client may - // disconnect the session. - - private Vector m_asynchQueue; - - // Maximum client buffer size and multiplex count - - private int m_maxBufSize; - private int m_maxMultiplex; - - // Client capabilities - - private int m_clientCaps; - - // Virtual circuit list - - private VirtualCircuitList m_vcircuits; - - // Setup objects used during two stage session setup before the virtual circuit is allocated - - private Hashtable m_setupObjects; - - // Debug flag values - - public static final int DBG_NETBIOS = 0x00000001; // NetBIOS layer - public static final int DBG_STATE = 0x00000002; // Session state changes - public static final int DBG_NEGOTIATE = 0x00000004; // Protocol negotiate phase - public static final int DBG_TREE = 0x00000008; // Tree connection/disconnection - public static final int DBG_SEARCH = 0x00000010; // File/directory search - public static final int DBG_INFO = 0x00000020; // Information requests - public static final int DBG_FILE = 0x00000040; // File open/close/info - public static final int DBG_FILEIO = 0x00000080; // File read/write - public static final int DBG_TRAN = 0x00000100; // Transactions - public static final int DBG_ECHO = 0x00000200; // Echo requests - public static final int DBG_ERROR = 0x00000400; // Errors - public static final int DBG_IPC = 0x00000800; // IPC$ requests - public static final int DBG_LOCK = 0x00001000; // Lock/unlock requests - public static final int DBG_PKTTYPE = 0x00002000; // Received packet type - public static final int DBG_DCERPC = 0x00004000; // DCE/RPC - public static final int DBG_STATECACHE =0x00008000; // File state cache - public static final int DBG_NOTIFY = 0x00010000; // Asynchronous change notification - public static final int DBG_STREAMS = 0x00020000; // NTFS streams - public static final int DBG_SOCKET = 0x00040000; // NetBIOS/native SMB socket connections - - /** - * Class constructor. - * - * @param handler Packet handler used to send/receive SMBs - * @param srv Server that this session is associated with. - */ - public SMBSrvSession(PacketHandler handler, SMBServer srv) - { - super(-1, srv, handler.isProtocolName(), null); - - // Set the packet handler - - m_pktHandler = handler; - - // Allocate a receive buffer - - m_buf = new byte[DefaultBufferSize]; - m_smbPkt = new SMBSrvPacket(m_buf); - - // If this is a TCPIP SMB or Win32 NetBIOS session then bypass the NetBIOS session setup - // phase. - - if (isProtocol() == SMBSrvPacket.PROTOCOL_TCPIP || isProtocol() == SMBSrvPacket.PROTOCOL_WIN32NETBIOS) - { - - // Advance to the SMB negotiate dialect phase - - setState(SMBSrvSessionState.SMBNEGOTIATE); - - // Check if the client name is available - - if (handler.hasClientName()) - m_callerNBName = handler.getClientName(); - } - - // Allocate the virtual circuit list - - m_vcircuits = new VirtualCircuitList(); - } - - /** - * Return the session protocol type - * - * @return int - */ - public final int isProtocol() - { - return m_pktHandler.isProtocol(); - } - - /** - * Find the tree connection for the request - * - * @param smbPkt SMBSrvPacket - * @return TreeConnection - */ - public final TreeConnection findTreeConnection(SMBSrvPacket smbPkt) { - - // Find the virtual circuit for the request - - TreeConnection tree = null; - VirtualCircuit vc = findVirtualCircuit( smbPkt.getUserId()); - - if (vc != null) { - - // Find the tree connection - - tree = vc.findConnection(smbPkt.getTreeId()); - } - - // Return the tree connection, or null if invalid UID or TID - - return tree; - } - - /** - * Add a new virtual circuit, return the allocated UID - * - * @param vc - * VirtualCircuit - * @return int - */ - public final int addVirtualCircuit( VirtualCircuit vc) { - - // Add the new virtual circuit - - return m_vcircuits.addCircuit( vc); - } - - /** - * Find a virtual circuit with the allocated UID - * - * @param uid int - * @return VirtualCircuit - */ - public final VirtualCircuit findVirtualCircuit(int uid) { - - // Find the virtual circuit with the specified UID - - VirtualCircuit vc = m_vcircuits.findCircuit(uid); - if (vc != null) { - - // Set the session client information from the virtual circuit - - setClientInformation(vc.getClientInformation()); - - // Set the current authenticated user for this request - - getSMBServer().getAuthenticator().setCurrentUser( vc.getClientInformation()); - } - - // Return the virtual circuit - - return vc; - } - - /** - * Remove a virtual circuit - * - * @param uid - * int - */ - public final void removeVirtualCircuit(int uid) { - - // Remove the virtual circuit with the specified UID - - m_vcircuits.removeCircuit(uid, this); - } - - /** - * Return the count of virtual circuits on this session - * - * @return int - */ - public final int getVirtualCircuitCount() - { - return m_vcircuits != null ? m_vcircuits.getCircuitCount() : 0; - } - - /** - * Cleanup any resources owned by this session, close files, searches and - * change notification requests. - */ - protected final void cleanupSession() - { - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Cleanup session, vcircuits=" + m_vcircuits.getCircuitCount() + ", changeNotify=" + getNotifyChangeCount()); - - // Close the virtual circuits - - if ( m_vcircuits.getCircuitCount() > 0) { - - // Enumerate the virtual circuits and close all circuits - - Enumeration uidEnum = m_vcircuits.enumerateUIDs(); - - while ( uidEnum.hasMoreElements()) { - - // Get the UID for the current circuit - - Integer uid = (Integer) uidEnum.nextElement(); - - // Close the virtual circuit - - VirtualCircuit vc = m_vcircuits.findCircuit( uid); - if ( vc != null) { - - // DEBUG - - if ( logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug(" Cleanup vc=" + vc); - - vc.closeCircuit( this); - } - } - - // Clear the virtual circuit list - - m_vcircuits.clearCircuitList(); - } - - // 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); - } - - // Check if there are active change notification requests - - if (m_notifyList != null && m_notifyList.numberOfRequests() > 0) - { - - // Remove the notify requests from the associated device context notify list - - for (int i = 0; i < m_notifyList.numberOfRequests(); i++) - { - - // Get the current change notification request and remove from the global notify - // list - - NotifyRequest curReq = m_notifyList.getRequest(i); - curReq.getDiskContext().getChangeHandler().removeNotifyRequests(this); - } - } - - // Delete any temporary shares that were created for this session - - getSMBServer().deleteTemporaryShares(this); - } - - /** - * Close the session socket - */ - protected final void closeSocket() - { - - // Indicate that the session is being shutdown - - setShutdown(true); - - // Close the packet handler - - try - { - m_pktHandler.closeHandler(); - } - catch (Exception ex) - { - } - } - - /** - * Close the session - */ - public final void closeSession() - { - - // Call the base class - - super.closeSession(); - - try - { - - // Set the session into a hangup state and indicate that we have shutdown the session - - setState(SMBSrvSessionState.NBHANGUP); - setShutdown(true); - - // Close the packet handler - - m_pktHandler.closeHandler(); - } - catch (Exception ex) - { - } - - } - - /** - * Finalize, object is about to be garbage collected. Make sure resources are released. - */ - public void finalize() - { - - // Check if there are any active resources - - cleanupSession(); - - // Make sure the socket is closed and deallocated - - closeSocket(); - } - - /** - * Return the input/output metwork buffer for this session. - * - * @return byte[] - */ - protected final byte[] getBuffer() - { - return m_buf; - } - - /** - * Return the default flags SMB header value - * - * @return int - */ - public final int getDefaultFlags() - { - return m_defFlags; - } - - /** - * Return the default flags2 SMB header value - * - * @return int - */ - public final int getDefaultFlags2() - { - return m_defFlags2; - } - - /** - * Return the count of active change notification requests - * - * @return int - */ - public final int getNotifyChangeCount() - { - if (m_notifyList == null) - return 0; - return m_notifyList.numberOfRequests(); - } - - /** - * Return the client maximum buffer size - * - * @return int - */ - public final int getClientMaximumBufferSize() - { - return m_maxBufSize; - } - - /** - * Return the client maximum muliplexed requests - * - * @return int - */ - public final int getClientMaximumMultiplex() - { - return m_maxMultiplex; - } - - /** - * Return the client capability flags - * - * @return int - */ - public final int getClientCapabilities() - { - return m_clientCaps; - } - - /** - * Determine if the client has the specified capability enabled - * - * @param cap int - * @return boolean - */ - public final boolean hasClientCapability(int cap) - { - if ((m_clientCaps & cap) != 0) - return true; - return false; - } - - /** - * Return the SMB dialect type that the server/client have negotiated. - * - * @return int - */ - public final int getNegotiatedSMBDialect() - { - return m_dialect; - } - - /** - * Return the packet handler used by the session - * - * @return PacketHandler - */ - public final PacketHandler getPacketHandler() - { - return m_pktHandler; - } - - /** - * Return the receiver SMB packet. - * - * @return SMBSrvPacket - */ - public final SMBSrvPacket getReceivePacket() - { - return m_smbPkt; - } - - /** - * Return the remote NetBIOS name that was used to create the session. - * - * @return java.lang.String - */ - public final String getRemoteNetBIOSName() - { - return m_callerNBName; - } - - /** - * Check if the session has a target NetBIOS name - * - * @return boolean - */ - public final boolean hasTargetNetBIOSName() - { - return m_targetNBName != null ? true : false; - } - - /** - * Return the target NetBIOS name that was used to create the session - * - * @return String - */ - public final String getTargetNetBIOSName() - { - return m_targetNBName; - } - - /** - * Cehck if the clients remote address is available - * - * @return boolean - */ - public final boolean hasRemoteAddress() - { - return m_pktHandler.hasRemoteAddress(); - } - - /** - * Return the client network address - * - * @return InetAddress - */ - public final InetAddress getRemoteAddress() - { - return m_pktHandler.getRemoteAddress(); - } - - /** - * Return the server that this session is associated with. - * - * @return SMBServer - */ - public final SMBServer getSMBServer() - { - return (SMBServer) getServer(); - } - - /** - * Return the server name that this session is associated with. - * - * @return java.lang.String - */ - public final String getServerName() - { - return getSMBServer().getServerName(); - } - - /** - * Return the session state - * - * @return int - */ - public final int isState() - { - return m_state; - } - - /** - * Hangup the session. - * - * @param reason java.lang.String Reason the session is being closed. - */ - private void hangupSession(String reason) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) - logger.debug("## Session closing - " + reason); - - // Set the session into a NetBIOS hangup state - - setState(SMBSrvSessionState.NBHANGUP); - } - - /** - * Check if the Macintosh exteniosn SMBs are enabled - * - * @return boolean - */ - public final boolean hasMacintoshExtensions() - { - return getSMBServer().getConfiguration().hasMacintoshExtensions(); - } - - /** - * Determine if the session has a setup object for the specified PID - * - * @param pid int - * @return boolean - */ - public final boolean hasSetupObject(int pid) { - if (m_setupObjects == null) - return false; - return m_setupObjects.get(new Integer(pid)) != null ? true : false; - } - - /** - * Return the session setup object for the specified PID - * - * @param pid int - * @return Object - */ - public final Object getSetupObject(int pid) { - if (m_setupObjects == null) - return null; - return m_setupObjects.get(new Integer(pid)); - } - - /** - * Store the setup object for the specified PID - * - * @param pid int - * @param obj Object - */ - public final void setSetupObject(int pid, Object obj) { - if (m_setupObjects == null) - m_setupObjects = new Hashtable(); - m_setupObjects.put(new Integer(pid), obj); - } - - /** - * Remove the session setup object for the specified PID - * - * @param pid - * int - * @return Object - */ - public final Object removeSetupObject(int pid) { - if (m_setupObjects == null) - return null; - return m_setupObjects.remove(new Integer(pid)); - } - - /** - * Check if there is a change notification update pending - * - * @return boolean - */ - public final boolean hasNotifyPending() - { - return m_notifyPending; - } - - /** - * Set the change notify pending flag - * - * @param pend boolean - */ - public final void setNotifyPending(boolean pend) - { - m_notifyPending = pend; - } - - /** - * Set the client maximum buffer size - * - * @param maxBuf int - */ - public final void setClientMaximumBufferSize(int maxBuf) - { - m_maxBufSize = maxBuf; - } - - /** - * Set the client maximum multiplexed - * - * @param maxMpx int - */ - public final void setClientMaximumMultiplex(int maxMpx) - { - m_maxMultiplex = maxMpx; - } - - /** - * Set the client capability flags - * - * @param flags int - */ - public final void setClientCapabilities(int flags) - { - m_clientCaps = flags; - } - - /** - * Set the default flags value to be ORed with outgoing response packet flags - * - * @param flags int - */ - public final void setDefaultFlags(int flags) - { - m_defFlags = flags; - } - - /** - * Set the default flags2 value to be ORed with outgoing response packet flags2 field - * - * @param flags int - */ - public final void setDefaultFlags2(int flags) - { - m_defFlags2 = flags; - } - - /** - * Set the SMB packet - * - * @param pkt SMBSrvPacket - */ - public final void setReceivePacket(SMBSrvPacket pkt) - { - m_smbPkt = pkt; - m_buf = pkt.getBuffer(); - } - - /** - * Set the session state. - * - * @param state int - */ - protected void setState(int state) - { - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("State changed to " + SMBSrvSessionState.getStateAsString(state)); - - // Change the session state - - m_state = state; - } - - /** - * Process the NetBIOS session request message, either accept the session request and send back - * a NetBIOS accept or reject the session and send back a NetBIOS reject and hangup the session. - */ - protected void procNetBIOSSessionRequest() throws IOException, NetBIOSException - { - - // Check if the received packet contains enough data for a NetBIOS session request packet. - - NetBIOSPacket nbPkt = new NetBIOSPacket(m_buf); - - if (m_rxlen < RFCNetBIOSProtocol.SESSREQ_LEN || nbPkt.getHeaderType() != RFCNetBIOSProtocol.SESSION_REQUEST) - throw new NetBIOSException("NBREQ Invalid packet"); - - // Do a few sanity checks on the received packet - - if (m_buf[4] != (byte) 32 || m_buf[38] != (byte) 32) - throw new NetBIOSException("NBREQ Invalid NetBIOS name data"); - - // Extract the from/to NetBIOS encoded names, and convert to normal strings. - - StringBuffer nbName = new StringBuffer(32); - for (int i = 0; i < 32; i++) - nbName.append((char) m_buf[5 + i]); - String toName = NetBIOSSession.DecodeName(nbName.toString()); - toName = toName.trim(); - - nbName.setLength(0); - for (int i = 0; i < 32; i++) - nbName.append((char) m_buf[39 + i]); - String fromName = NetBIOSSession.DecodeName(nbName.toString()); - fromName = fromName.trim(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) - logger.debug("NetBIOS CALL From " + fromName + " to " + toName); - - // Check that the request is for this server - - boolean forThisServer = false; - - if (toName.compareTo(getServerName()) == 0 || toName.compareTo(NetBIOSName.SMBServer) == 0 - || toName.compareTo(NetBIOSName.SMBServer2) == 0 || toName.compareTo("*") == 0) - { - - // Request is for this server - - forThisServer = true; - } - else - { - - // Check if the caller is using an IP address - - InetAddress[] srvAddr = getSMBServer().getServerAddresses(); - if (srvAddr != null) - { - - // Check for an address match - - int idx = 0; - - while (idx < srvAddr.length && forThisServer == false) - { - - // Check the current IP address - - if (srvAddr[idx++].getHostAddress().compareTo(toName) == 0) - forThisServer = true; - } - } - } - - // If we did not find an address match then reject the session request - - if (forThisServer == false) - throw new NetBIOSException("NBREQ Called name is not this server (" + toName + ")"); - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_NETBIOS)) - logger.debug("NetBIOS session request from " + fromName); - - // Save the callers name and target name - - m_callerNBName = fromName; - m_targetNBName = toName; - - // Set the remote client name - - setRemoteName(fromName); - - // Build a NetBIOS session accept message - - nbPkt.setHeaderType(RFCNetBIOSProtocol.SESSION_ACK); - nbPkt.setHeaderFlags(0); - nbPkt.setHeaderLength(0); - - // Output the NetBIOS session accept packet - - m_pktHandler.writePacket(m_buf, 0, 4); - - // Move the session to the SMB negotiate state - - setState(SMBSrvSessionState.SMBNEGOTIATE); - } - - /** - * Process an SMB dialect negotiate request. - */ - protected void procSMBNegotiate() throws SMBSrvException, IOException - { - - // Create an SMB server packet using the receive buffer - - m_smbPkt = new SMBSrvPacket(m_buf); - - // Initialize the NetBIOS header - - m_buf[0] = (byte) RFCNetBIOSProtocol.SESSION_MESSAGE; - - // Check if the received packet looks like a valid SMB - - if (m_smbPkt.getCommand() != PacketType.Negotiate || m_smbPkt.checkPacketIsValid(0, 2) == false) - { - sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv); - return; - } - - // Decode the data block into a list of requested SMB dialects - - int dataPos = m_smbPkt.getByteOffset(); - int dataLen = m_smbPkt.getByteCount(); - - String diaStr = null; - StringList dialects = new StringList(); - - while (dataLen > 0) - { - - // Decode an SMB dialect string from the data block, always ASCII strings - - diaStr = DataPacker.getDataString(DataType.Dialect, m_buf, dataPos, dataLen, false); - if (diaStr != null) - { - - // Add the dialect string to the list of requested dialects - - dialects.addString(diaStr); - } - else - { - - // Invalid dialect block in the negotiate packet, send an error response and hangup - // the session. - - sendErrorResponseSMB(SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv); - setState(SMBSrvSessionState.NBHANGUP); - return; - } - - // Update the remaining data position and count - - dataPos += diaStr.length() + 2; // data type and null - dataLen -= diaStr.length() + 2; - } - - // Find the highest level SMB dialect that the server and client both support - - DialectSelector dia = getSMBServer().getConfiguration().getAuthenticator().getEnabledDialects(); - int diaIdx = -1; - - for (int i = 0; i < Dialect.Max; i++) - { - - // Check if the current dialect is supported by the server - - if (dia.hasDialect(i)) - { - - // Check if the client supports the current dialect. If the current dialect is a - // higher level dialect than the currently nominated dialect, update the nominated - // dialect index. - - for (int j = 0; j < Dialect.SMB_PROT_MAXSTRING; j++) - { - - // Check if the dialect string maps to the current dialect index - - if (Dialect.DialectType(j) == i && dialects.containsString(Dialect.DialectString(j))) - { - - // Update the selected dialect type, if the current dialect is a newer - // dialect - - if (i > diaIdx) - diaIdx = i; - } - } - } - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_NEGOTIATE)) - { - if (diaIdx == -1) - logger.debug("Failed to negotiate SMB dialect"); - else - logger.debug("Negotiated SMB dialect - " + Dialect.DialectTypeString(diaIdx)); - } - - // Check if we successfully negotiated an SMB dialect with the client - - if (diaIdx != -1) - { - - // Store the negotiated SMB diialect type - - m_dialect = diaIdx; - - // Convert the dialect type to an index within the clients SMB dialect list - - diaIdx = dialects.findString(Dialect.DialectTypeString(diaIdx)); - - // Allocate a protocol handler for the negotiated dialect, if we cannot get a protocol - // handler then bounce the request. - - m_handler = ProtocolFactory.getHandler(m_dialect); - if (m_handler != null) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_NEGOTIATE)) - logger.debug("Assigned protocol handler - " + m_handler.getClass().getName()); - - // Set the protocol handlers associated session - - m_handler.setSession(this); - } - else - { - - // Could not get a protocol handler for the selected SMB dialect, indicate to the - // client that no suitable dialect available. - - diaIdx = -1; - } - } - - // Check if the extended security flag has been set by the client - - boolean extendedSecurity = (m_smbPkt.getFlags2() & SMBSrvPacket.FLG2_EXTENDEDSECURITY) != 0 ? true : false; - - // Build the negotiate response SMB for Core dialect - - if (m_dialect == -1 || m_dialect <= Dialect.CorePlus) - { - - // Core dialect negotiate response, or no valid dialect response - - m_smbPkt.setParameterCount(1); - m_smbPkt.setParameter(0, diaIdx); - m_smbPkt.setByteCount(0); - - m_smbPkt.setTreeId(0); - m_smbPkt.setUserId(0); - } - else if (m_dialect <= Dialect.LanMan2_1) - { - - // We are using case sensitive pathnames and long file names - - m_smbPkt.setFlags(SMBSrvPacket.FLG_CASELESS); - m_smbPkt.setFlags2(SMBSrvPacket.FLG2_LONGFILENAMES); - - // Access the authenticator for this server and determine if the server is in share or - // user level security mode. - - CifsAuthenticator auth = getServer().getConfiguration().getAuthenticator(); - - // LanMan dialect negotiate response - - m_smbPkt.setParameterCount(13); - m_smbPkt.setParameter(0, diaIdx); - m_smbPkt.setParameter(1, auth.getSecurityMode()); - m_smbPkt.setParameter(2, LanManBufferSize); - m_smbPkt.setParameter(3, LanManMaxMultiplexed); // maximum multiplexed requests - m_smbPkt.setParameter(4, MaxVirtualCircuits); // maximum number of virtual circuits - m_smbPkt.setParameter(5, 0); // read/write raw mode support - - // Create a session token, using the system clock - - m_smbPkt.setParameterLong(6, (int) (System.currentTimeMillis() & 0xFFFFFFFF)); - - // Return the current server date/time - - SMBDate srvDate = new SMBDate(System.currentTimeMillis()); - m_smbPkt.setParameter(8, srvDate.asSMBTime()); - m_smbPkt.setParameter(9, srvDate.asSMBDate()); - - // Server timezone offset from UTC - - m_smbPkt.setParameter(10, getServer().getConfiguration().getTimeZoneOffset()); - - // Encryption key length - - m_smbPkt.setParameter(11, auth.getEncryptionKeyLength()); - m_smbPkt.setParameter(12, 0); - - m_smbPkt.setTreeId(0); - m_smbPkt.setUserId(0); - - // Let the authenticator pack any remaining fields in the negotiate response - - try - { - // Pack the remaining negotiate response fields - - auth.generateNegotiateResponse( this, m_smbPkt, extendedSecurity); - } - catch ( AuthenticatorException ex) - { - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Negotiate error", ex); - - // Close the session - - setState(SMBSrvSessionState.NBHANGUP); - return; - } - } - else if (m_dialect == Dialect.NT) - { - - // We are using case sensitive pathnames and long file names - - setDefaultFlags(SMBSrvPacket.FLG_CASELESS); - setDefaultFlags2(SMBSrvPacket.FLG2_LONGFILENAMES + SMBSrvPacket.FLG2_UNICODE); - - // Access the authenticator for this server and determine if the server is in share or - // user level security mode. - - CifsAuthenticator auth = getServer().getConfiguration().getAuthenticator(); - - // NT dialect negotiate response - - NTParameterPacker nt = new NTParameterPacker(m_smbPkt.getBuffer()); - - m_smbPkt.setParameterCount(17); - nt.packWord(diaIdx); // selected dialect index - nt.packByte(auth.getSecurityMode()); - nt.packWord(NTMaxMultiplexed); // maximum multiplexed requests - // setting to 1 will disable change notify requests from the client - nt.packWord(MaxVirtualCircuits); // maximum number of virtual circuits - - int maxBufSize = m_smbPkt.getBuffer().length - RFCNetBIOSProtocol.HEADER_LEN; - nt.packInt(maxBufSize); - - nt.packInt(0); // maximum raw size - - // Create a session token, using the system clock - - nt.packInt((int) (System.currentTimeMillis() & 0xFFFFFFFFL)); - - // Set server capabilities, switch off extended security if the client does not support it - - int srvCapabs = auth.getServerCapabilities(); - if ( extendedSecurity == false) - srvCapabs &= ~Capability.ExtendedSecurity; - - nt.packInt(srvCapabs); - - // Return the current server date/time, and timezone offset - - long srvTime = NTTime.toNTTime(new java.util.Date(System.currentTimeMillis())); - - nt.packLong(srvTime); - nt.packWord(getServer().getConfiguration().getTimeZoneOffset()); - - // Encryption key length - - nt.packByte( auth.getEncryptionKeyLength()); - - m_smbPkt.setFlags( getDefaultFlags()); - m_smbPkt.setFlags2( getDefaultFlags2()); - - m_smbPkt.setTreeId(0); - m_smbPkt.setUserId(0); - - // Let the authenticator pack any remaining fields in the negotiate response - - try - { - // Pack the remaining negotiate response fields - - auth.generateNegotiateResponse( this, m_smbPkt, extendedSecurity); - } - catch ( AuthenticatorException ex) - { - // Log the error - - if ( logger.isErrorEnabled()) - logger.error("Negotiate error", ex); - - // Close the session - - setState(SMBSrvSessionState.NBHANGUP); - return; - } - } - - // Make sure the response flag is set - - if (m_smbPkt.isResponse() == false) - m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBPacket.FLG_RESPONSE); - - // Send the negotiate response - - m_pktHandler.writePacket(m_smbPkt, m_smbPkt.getLength()); - - // Check if the negotiated SMB dialect supports the session setup command, if not then - // bypass the session setup phase. - - if (m_dialect == -1) - setState(SMBSrvSessionState.NBHANGUP); - else if (Dialect.DialectSupportsCommand(m_dialect, PacketType.SessionSetupAndX)) - setState(SMBSrvSessionState.SMBSESSSETUP); - else - setState(SMBSrvSessionState.SMBSESSION); - - // If a dialect was selected inform the server that the session has been opened - - if (m_dialect != -1) - getSMBServer().sessionOpened(this); - } - - /** - * Start the SMB server session in a seperate thread. - */ - public void run() - { - try - { - // Debug - - if (logger.isDebugEnabled() && hasDebug(SMBSrvSession.DBG_NEGOTIATE)) - logger.debug("Server session started"); - - // The server session loops until the NetBIOS hangup state is set. - - while (m_state != SMBSrvSessionState.NBHANGUP) - { - - // Set the current receive length to -1 to indicate that the session thread is not - // currently processing an SMB packet. This is used by the asynchronous response code - // to determine when it can send the response. - - m_rxlen = -1; - - // Wait for a data packet - - m_rxlen = m_pktHandler.readPacket(m_smbPkt); - - // Check for an empty packet - - if (m_rxlen == 0) - continue; - - // Check if there is no more data, the other side has dropped the connection - - if (m_rxlen == -1) - { - hangupSession("Remote disconnect"); - continue; - } - - // Check the packet signature if we are in an SMB state - - if ( m_state > SMBSrvSessionState.NBSESSREQ) - { - // Check for an SMB2 packet signature - - if ( m_smbPkt.isSMB2()) - { - // Debug - - if ( logger.isDebugEnabled() && hasDebug(DBG_PKTTYPE)) - logger.debug("SMB2 request received, ignoring"); - - continue; - } - - // Check the packet signature - - if ( m_smbPkt.checkPacketSignature() == false) - { - // Debug - - if ( logger.isDebugEnabled() && hasDebug(DBG_PKTTYPE)) - logger.debug("Invalid SMB packet signature received, packet ignored"); - - continue; - } - } - - // Store the received data length - - m_smbPkt.setReceivedLength(m_rxlen); - - // Update the request count - - m_reqCount++; - - // Process the received packet - - switch (m_state) - { - - // NetBIOS session request pending - - case SMBSrvSessionState.NBSESSREQ: - procNetBIOSSessionRequest(); - break; - - // SMB dialect negotiate - - case SMBSrvSessionState.SMBNEGOTIATE: - procSMBNegotiate(); - break; - - // SMB session setup - - case SMBSrvSessionState.SMBSESSSETUP: - m_handler.runProtocol(); - break; - - // SMB session main request processing - - case SMBSrvSessionState.SMBSESSION: - - // Run the main protocol handler - - runHandler(); - break; - - } // end switch session state - - // 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); - } - - // Give up the CPU - - Thread.yield(); - - } // end while state - } - catch (SocketException ex) - { - - // DEBUG - - logger.error("Socket closed by remote client"); - } - catch (Exception ex) - { - - // Output the exception details - - if (isShutdown() == false) - logger.error("Closing session due to exception", ex); - } - catch (Throwable ex) - { - logger.error("Closing session due to throwable", ex); - } - finally - { - // If there is an active transaction then roll it back - - if ( hasUserTransaction()) - { - try - { - getUserTransaction().rollback(); - } - catch (Exception ex) - { - logger.warn("Failed to rollback transaction", ex); - } - } - } - - // Cleanup the session, make sure all resources are released - - cleanupSession(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_STATE)) - logger.debug("Server session closed"); - - // Close the session - - closeSocket(); - - // Notify the server that the session has closed - - getSMBServer().sessionClosed(this); - } - - /** - * Handle a session message, receive all data and run the SMB protocol handler. - */ - protected final void runHandler() throws IOException, SMBSrvException, TooManyConnectionsException - { - - // Make sure we received at least a NetBIOS header - - if (m_rxlen < NetBIOSPacket.MIN_RXLEN) - return; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_PKTTYPE)) - logger.debug("Rx packet type - " + m_smbPkt.getPacketTypeString() + ", SID=" + m_smbPkt.getSID()); - - // Call the protocol handler - - if (m_handler.runProtocol() == false) - { - - // The sessions protocol handler did not process the request, return an unsupported - // SMB error status. - - sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); - } - - // Check if there are any pending asynchronous response packets - - while (hasAsynchResponse()) - { - - // Remove the current asynchronous response SMB packet and send to the client - - SMBSrvPacket asynchPkt = removeFirstAsynchResponse(); - sendResponseSMB(asynchPkt, asynchPkt.getLength()); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug(DBG_NOTIFY)) - logger.debug("Sent queued asynch response type=" + asynchPkt.getPacketTypeString() + ", mid=" - + asynchPkt.getMultiplexId() + ", pid=" + asynchPkt.getProcessId()); - } - } - - /** - * Send an SMB response - * - * @param pkt SMBSrvPacket - * @exception IOException - */ - public final void sendResponseSMB(SMBSrvPacket pkt) throws IOException - { - sendResponseSMB(pkt, pkt.getLength()); - } - - /** - * Send an SMB response - * - * @param pkt SMBSrvPacket - * @param len int - * @exception IOException - */ - public synchronized final void sendResponseSMB(SMBSrvPacket pkt, int len) throws IOException - { - - // Make sure the response flag is set - - if (pkt.isResponse() == false) - pkt.setFlags(pkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); - - // Add default flags/flags2 values - - pkt.setFlags(pkt.getFlags() | getDefaultFlags()); - - // Mask out certain flags that the client may have sent - - int flags2 = pkt.getFlags2() | getDefaultFlags2(); - flags2 &= ~(SMBPacket.FLG2_EXTENDEDATTRIB + SMBPacket.FLG2_DFSRESOLVE + SMBPacket.FLG2_SECURITYSIGS); - - pkt.setFlags2(flags2); - - // Send the response packet - - m_pktHandler.writePacket(pkt, len); - m_pktHandler.flushPacket(); - } - - /** - * Send a success response SMB - * - * @exception IOException If a network error occurs - */ - public final void sendSuccessResponseSMB() throws IOException - { - - // Make sure the response flag is set - - if (m_smbPkt.isResponse() == false) - m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); - - // Add default flags/flags2 values - - m_smbPkt.setFlags(m_smbPkt.getFlags() | getDefaultFlags()); - m_smbPkt.setFlags2(m_smbPkt.getFlags2() | getDefaultFlags2()); - - // Clear the parameter and byte counts - - m_smbPkt.setParameterCount(0); - m_smbPkt.setByteCount(0); - - if (m_smbPkt.isLongErrorCode()) - m_smbPkt.setLongErrorCode(SMBStatus.NTSuccess); - else - { - m_smbPkt.setErrorClass(SMBStatus.Success); - m_smbPkt.setErrorCode(SMBStatus.Success); - } - - // Return the success response to the client - - sendResponseSMB(m_smbPkt, m_smbPkt.getLength()); - } - - /** - * Send an error response SMB. The returned code depends on the client long error code flag - * setting. - * - * @param ntCode 32bit error code - * @param stdCode Standard error code - * @param StdClass Standard error class - */ - public final void sendErrorResponseSMB(int ntCode, int stdCode, int stdClass) throws java.io.IOException - { - - // Check if long error codes are required by the client - - if (m_smbPkt.isLongErrorCode()) - { - // Return the long/NT status code - - if ( ntCode != -1) { - - // Use the 32bit NT error code - - sendErrorResponseSMB( ntCode, SMBStatus.NTErr); - } - else { - - // Use the DOS error code - - sendErrorResponseSMB( stdCode, stdClass); - } - } - else - { - - // Return the standard/DOS error code - - sendErrorResponseSMB(stdCode, stdClass); - } - } - - /** - * Send an error response SMB. - * - * @param errCode int Error code. - * @param errClass int Error class. - */ - public final void sendErrorResponseSMB(int errCode, int errClass) throws java.io.IOException - { - - // Make sure the response flag is set - - if (m_smbPkt.isResponse() == false) - m_smbPkt.setFlags(m_smbPkt.getFlags() + SMBSrvPacket.FLG_RESPONSE); - - // Set the error code and error class in the response packet - - m_smbPkt.setParameterCount(0); - m_smbPkt.setByteCount(0); - - // Add default flags/flags2 values - - m_smbPkt.setFlags(m_smbPkt.getFlags() | getDefaultFlags()); - m_smbPkt.setFlags2(m_smbPkt.getFlags2() | getDefaultFlags2()); - - // Check if the error is a NT 32bit error status - - if (errClass == SMBStatus.NTErr) - { - - // Enable the long error status flag - - if (m_smbPkt.isLongErrorCode() == false) - m_smbPkt.setFlags2(m_smbPkt.getFlags2() + SMBSrvPacket.FLG2_LONGERRORCODE); - - // Set the NT status code - - m_smbPkt.setLongErrorCode(errCode); - } - else - { - - // Disable the long error status flag - - if (m_smbPkt.isLongErrorCode() == true) - m_smbPkt.setFlags2(m_smbPkt.getFlags2() - SMBSrvPacket.FLG2_LONGERRORCODE); - - // Set the error status/class - - m_smbPkt.setErrorCode(errCode); - m_smbPkt.setErrorClass(errClass); - } - - // Return the error response to the client - - sendResponseSMB(m_smbPkt, m_smbPkt.getLength()); - - // Debug - - if (logger.isDebugEnabled() && hasDebug(DBG_ERROR)) - logger.debug("Error : Cmd = " + m_smbPkt.getPacketTypeString() + " - " - + SMBErrorText.ErrorString(errClass, errCode)); - } - - /** - * Send, or queue, an asynchronous response SMB - * - * @param pkt SMBSrvPacket - * @param len int - * @return true if the packet was sent, or false if it was queued - * @exception IOException If an I/O error occurs - */ - public final boolean sendAsynchResponseSMB(SMBSrvPacket pkt, int len) throws IOException - { - - // Check if there is an SMB currently being processed or pending data from the client - - boolean sts = false; - - if (m_rxlen == -1 && m_pktHandler.availableBytes() == 0) - { - - // Send the asynchronous response immediately - - sendResponseSMB(pkt, len); - m_pktHandler.flushPacket(); - - // Indicate that the SMB response has been sent - - sts = true; - } - else - { - - // Queue the packet to send out when current SMB requests have been processed - - queueAsynchResponseSMB(pkt); - } - - // Return the sent/queued status - - return sts; - } - - /** - * Queue an asynchronous response SMB for sending when current SMB requests have been processed. - * - * @param pkt SMBSrvPacket - */ - protected final synchronized void queueAsynchResponseSMB(SMBSrvPacket pkt) - { - - // Check if the asynchronous response queue has been allocated - - if (m_asynchQueue == null) - { - - // Allocate the asynchronous response queue - - m_asynchQueue = new Vector(); - } - - // Add the SMB response packet to the queue - - m_asynchQueue.addElement(pkt); - } - - /** - * Check if there are any asynchronous requests queued - * - * @return boolean - */ - protected final synchronized boolean hasAsynchResponse() - { - - // Check if the queue is valid - - if (m_asynchQueue != null && m_asynchQueue.size() > 0) - return true; - return false; - } - - /** - * Remove an asynchronous response packet from the head of the list - * - * @return SMBSrvPacket - */ - protected final synchronized SMBSrvPacket removeFirstAsynchResponse() - { - - // Check if there are asynchronous response packets queued - - if (m_asynchQueue == null || m_asynchQueue.size() == 0) - return null; - - // Return the SMB packet from the head of the queue - - return m_asynchQueue.remove(0); - } - - /** - * Find the notify request with the specified ids - * - * @param mid int - * @param tid int - * @param uid int - * @param pid int - * @return NotifyRequest - */ - public final NotifyRequest findNotifyRequest(int mid, int tid, int uid, int pid) - { - - // Check if the local notify list is valid - - if (m_notifyList == null) - return null; - - // Find the matching notify request - - return m_notifyList.findRequest(mid, tid, uid, pid); - } - - /** - * Find an existing notify request for the specified directory and filter - * - * @param dir NetworkFile - * @param filter int - * @param watchTree boolean - * @return NotifyRequest - */ - public final NotifyRequest findNotifyRequest(NetworkFile dir, int filter, boolean watchTree) - { - - // Check if the local notify list is valid - - if (m_notifyList == null) - return null; - - // Find the matching notify request - - return m_notifyList.findRequest(dir, filter, watchTree); - } - - /** - * Add a change notification request - * - * @param req NotifyRequest - * @param ctx DiskDeviceContext - */ - public final void addNotifyRequest(NotifyRequest req, DiskDeviceContext ctx) - { - - // Check if the local notify list has been allocated - - if (m_notifyList == null) - m_notifyList = new NotifyRequestList(); - - // Add the request to the local list and the shares global list - - m_notifyList.addRequest(req); - ctx.addNotifyRequest(req); - } - - /** - * Remove a change notification request - * - * @param req NotifyRequest - */ - public final void removeNotifyRequest(NotifyRequest req) - { - - // Check if the local notify list has been allocated - - if (m_notifyList == null) - return; - - // Remove the request from the local list and the shares global list - - m_notifyList.removeRequest(req); - if (req.getDiskContext() != null) - req.getDiskContext().removeNotifyRequest(req); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvSessionState.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvSessionState.java deleted file mode 100644 index b0c958f216..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvSessionState.java +++ /dev/null @@ -1,78 +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.smb.server; - -/** - *

- * Contains the various states that an SMB server session will go through during the session - * lifetime. - */ -public class SMBSrvSessionState -{ - - // NetBIOS session has been closed. - - public static final int NBHANGUP = 5; - - // NetBIOS session request state. - - public static final int NBSESSREQ = 0; - - // SMB session closed down. - - public static final int SMBCLOSED = 4; - - // Negotiate SMB dialect. - - public static final int SMBNEGOTIATE = 1; - - // SMB session is initialized, ready to receive/handle standard SMB requests. - - public static final int SMBSESSION = 3; - - // SMB session setup. - - public static final int SMBSESSSETUP = 2; - - // State name strings - - private static final String _stateName[] = { - "NBSESSREQ", - "SMBNEGOTIATE", - "SMBSESSSETUP", - "SMBSESSION", - "SMBCLOSED", - "NBHANGUP" }; - - /** - * Return the specified SMB state as a string. - */ - public static String getStateAsString(int state) - { - if (state < _stateName.length) - return _stateName[state]; - return "[UNKNOWN]"; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBSrvTransPacket.java b/source/java/org/alfresco/filesys/smb/server/SMBSrvTransPacket.java deleted file mode 100644 index 14f6a5cbcd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBSrvTransPacket.java +++ /dev/null @@ -1,846 +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.smb.server; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.TransactBuffer; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; - -/** - * SMB server transact packet class - */ -class SMBSrvTransPacket extends SMBTransPacket -{ - - // Define the number of standard parameters for a server response - - private static final int StandardParamsResponse = 10; - - // Offset to the setup response paramaters - - protected static final int SetupOffsetResponse = PARAMWORDS + (StandardParamsResponse * 2); - - /** - * Construct an SMB transaction packet - * - * @param buf Buffer that contains the SMB transaction packet. - */ - - public SMBSrvTransPacket(byte[] buf) - { - super(buf); - } - - /** - * Construct an SMB transaction packet - * - * @param siz Size of packet to allocate. - */ - - public SMBSrvTransPacket(int siz) - { - super(siz); - - // Set the multiplex id for this transaction - - setMultiplexId(getNextMultiplexId()); - } - - /** - * Initialize the transact reply parameters. - * - * @param pkt Reply SMB packet. - * @param prmCnt Count of returned parameter bytes. - * @param prmPos Starting offset to the parameter block. - * @param dataCnt Count of returned data bytes. - * @param dataPos Starting offset to the data block. - */ - public final static void initTransactReply(SMBSrvPacket pkt, int prmCnt, int prmPos, int dataCnt, int dataPos) - { - - // Set the total parameter words - - pkt.setParameterCount(10); - - // Set the total parameter/data bytes - - pkt.setParameter(0, prmCnt); - pkt.setParameter(1, dataCnt); - - // Clear the reserved parameter - - pkt.setParameter(2, 0); - - // Set the parameter byte count/offset for this packet - - pkt.setParameter(3, prmCnt); - pkt.setParameter(4, prmPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the parameter displacement - - pkt.setParameter(5, 0); - - // Set the data byte count/offset for this packet - - pkt.setParameter(6, dataCnt); - pkt.setParameter(7, dataPos - RFCNetBIOSProtocol.HEADER_LEN); - - // Set the data displacement - - pkt.setParameter(8, 0); - - // Set up word count - - pkt.setParameter(9, 0); - } - - /** - * Calculate the data item size from the data descriptor string. - * - * @param desc java.lang.String - * @return int - */ - protected final static int CalculateDataItemSize(String desc) - { - - // Scan the data descriptor string and calculate the data item size - - int len = 0; - int pos = 0; - - while (pos < desc.length()) - { - - // Get the current data item type - - char dtype = desc.charAt(pos++); - int dlen = 1; - - // Check if a data length has been specified - - if (pos < desc.length() && Character.isDigit(desc.charAt(pos))) - { - - // Convert the data length string - - int numlen = 1; - int numpos = pos + 1; - while (numpos < desc.length() && Character.isDigit(desc.charAt(numpos++))) - numlen++; - - // Set the data length - - dlen = Integer.parseInt(desc.substring(pos, pos + numlen)); - - // Update the descriptor string position - - pos = numpos - 1; - } - - // Convert the current data item - - switch (dtype) - { - - // Word (16 bit) data type - - case 'W': - len += 2; - break; - - // Integer (32 bit) data type - - case 'D': - len += 4; - break; - - // Byte data type, may be multiple bytes if 'B' - - case 'B': - len += dlen; - break; - - // Null terminated string data type, offset into buffer only - - case 'z': - len += 4; - break; - - // Skip 'n' bytes in the buffer - - case '.': - len += dlen; - break; - - // Integer (32 bit) data type converted to a date/time value - - case 'T': - len += 4; - break; - - } // end switch data type - - } // end while descriptor string - - // Return the data length of each item - - return len; - } - - /** - * Return the offset to the data block within the SMB packet. The data block is word aligned - * within the byte buffer area of the SMB packet. This method must be called after the parameter - * count has been set. - * - * @param prmLen Parameter block length, in bytes. - * @return int Offset to the data block area. - */ - public final int getDataBlockOffset(int prmLen) - { - - // Get the position of the parameter block - - int pos = getParameterBlockOffset() + prmLen; - if ((pos & 0x01) != 0) - pos++; - return pos; - } - - /** - * Return the data block offset. - * - * @return int Offset to data block within packet. - */ - public final int getRxDataBlock() - { - return getParameter(12) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the received transaction data block length. - * - * @return int - */ - public final int getRxDataBlockLength() - { - return getParameter(11); - } - - /** - * Get the required transact parameter word (16 bit). - * - * @param prmIdx int - * @return int - */ - public final int getRxParameter(int prmIdx) - { - - // Get the parameter block offset - - int pos = getRxParameterBlock(); - - // Get the required transact parameter word. - - pos += prmIdx * 2; // 16 bit words - return DataPacker.getIntelShort(getBuffer(), pos); - } - - /** - * Return the position of the parameter block within the received packet. - * - * @param prmblk Array to unpack the parameter block words into. - */ - - public final int getRxParameterBlock() - { - - // Get the offset to the parameter words, add the NetBIOS header length - // to the offset. - - return getParameter(10) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the received transaction parameter block length. - * - * @return int - */ - public final int getRxParameterBlockLength() - { - return getParameter(9); - } - - /** - * Return the received transaction setup parameter count. - * - * @return int - */ - public final int getRxParameterCount() - { - return getParameterCount() - STD_PARAMS; - } - - /** - * Get the required transact parameter int value (32-bit). - * - * @param prmIdx int - * @return int - */ - public final int getRxParameterInt(int prmIdx) - { - - // Get the parameter block offset - - int pos = getRxParameterBlock(); - - // Get the required transact parameter word. - - pos += prmIdx * 2; // 16 bit words - return DataPacker.getIntelInt(getBuffer(), pos); - } - - /** - * Get the required transact parameter string. - * - * @param pos Offset to the string within the parameter block. - * @param uni Unicode if true, else ASCII - * @return int - */ - public final String getRxParameterString(int pos, boolean uni) - { - - // Get the parameter block offset - - pos += getRxParameterBlock(); - - // Get the transact parameter string - - byte[] buf = getBuffer(); - int len = (buf[pos++] & 0x00FF); - return DataPacker.getString(buf, pos, len, uni); - } - - /** - * Get the required transact parameter string. - * - * @param pos Offset to the string within the parameter block. - * @param len Length of the string. - * @param uni Unicode if true, else ASCII - * @return int - */ - public final String getRxParameterString(int pos, int len, boolean uni) - { - - // Get the parameter block offset - - pos += getRxParameterBlock(); - - // Get the transact parameter string - - byte[] buf = getBuffer(); - return DataPacker.getString(buf, pos, len, uni); - } - - /** - * Return the received transaction name. - * - * @return java.lang.String - */ - public final String getRxTransactName() - { - - // Check if the transaction has a name - - if (getCommand() == PacketType.Transaction2) - return ""; - - // Unpack the transaction name string - - int pos = getByteOffset(); - return DataPacker.getString(getBuffer(), pos, getByteCount()); - } - - /** - * Return the setup parameter count - * - * @return int - */ - public final int getSetupCount() - { - return getParameter(13) & 0xFF; - } - - /** - * Return the buffer offset to the setup parameters - * - * @return int - */ - public final int getSetupOffset() - { - return WORDCNT + 29; // 14 setup words + word count byte - } - - /** - * Return the specified transaction setup parameter. - * - * @param idx Setup parameter index. - * @return int - */ - - public final int getSetupParameter(int idx) - { - - // Check if the setup parameter index is valid - - if (idx >= getRxParameterCount()) - throw new java.lang.ArrayIndexOutOfBoundsException(); - - // Get the setup parameter - - return getParameter(idx + STD_PARAMS); - } - - /** - * Return the maximum return paramater byte count - * - * @return int - */ - public final int getMaximumReturnParameterCount() - { - return getParameter(2); - } - - /** - * Return the maximum return data byte count - * - * @return int - */ - public final int getMaximumReturnDataCount() - { - return getParameter(3); - } - - /** - * Return the maximum return setup count - * - * @return int - */ - public final int getMaximumReturnSetupCount() - { - return getParameter(4); - } - - /** - * Return the specified transaction setup parameter 32bit value. - * - * @param idx Setup parameter index. - * @return int - */ - - public final int getSetupParameterInt(int idx) - { - - // Check if the setup parameter index is valid - - if (idx >= getRxParameterCount()) - throw new java.lang.ArrayIndexOutOfBoundsException(); - - // Get the setup parameter - - return getParameterLong(idx + STD_PARAMS); - } - - /** - * Set the total parameter block length, in bytes - * - * @param cnt int - */ - public final void setTotalParameterCount(int cnt) - { - setParameter(0, cnt); - } - - /** - * Set the total data block length, in bytes - * - * @param cnt int - */ - public final void setTotalDataCount(int cnt) - { - setParameter(1, cnt); - } - - /** - * Set the parameter block count for this packet - * - * @param len int - */ - public final void setParameterBlockCount(int len) - { - setParameter(3, len); - } - - /** - * Set the parameter block offset - * - * @param off int - */ - public final void setParameterBlockOffset(int off) - { - setParameter(4, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); - } - - /** - * Set the parameter block displacement within the total parameter block - * - * @param disp int - */ - public final void setParameterBlockDisplacement(int disp) - { - setParameter(5, disp); - } - - /** - * Set the data block count for this packet - * - * @param len int - */ - public final void setDataBlockCount(int len) - { - setParameter(6, len); - } - - /** - * Set the data block offset, from the start of the packet - * - * @param off int - */ - public final void setDataBlockOffset(int off) - { - setParameter(7, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); - } - - /** - * Set the data block displacement within the total data block - * - * @param disp int - */ - public final void setDataBlockDisplacement(int disp) - { - setParameter(8, disp); - } - - /** - * Send one or more transaction response SMBs to the client - * - * @param sess SMBSrvSession - * @param tbuf TransactBuffer - * @exception java.io.IOException If an I/O error occurs. - */ - protected final void doTransactionResponse(SMBSrvSession sess, TransactBuffer tbuf) throws IOException - { - - // Initialize the transaction response packet - - setCommand(tbuf.isType()); - - // Get the individual buffers from the transact buffer - - tbuf.setEndOfBuffer(); - - DataBuffer setupBuf = tbuf.getSetupBuffer(); - DataBuffer paramBuf = tbuf.getParameterBuffer(); - DataBuffer dataBuf = tbuf.getDataBuffer(); - - // Set the parameter count - - if (tbuf.hasSetupBuffer()) - setParameterCount(StandardParamsResponse + setupBuf.getLengthInWords()); - else - setParameterCount(StandardParamsResponse); - - // Clear the parameters - - for (int i = 0; i < getParameterCount(); i++) - setParameter(i, 0); - - // Get the total parameter/data block lengths - - int totParamLen = paramBuf != null ? paramBuf.getLength() : 0; - int totDataLen = dataBuf != null ? dataBuf.getLength() : 0; - - // Initialize the parameters - - setTotalParameterCount(totParamLen); - setTotalDataCount(totDataLen); - - // Get the available data space within the packet - - int availBuf = getAvailableLength(); - int clientLen = getAvailableLength(sess.getClientMaximumBufferSize()); - if (availBuf > clientLen) - availBuf = clientLen; - - // Check if the transaction parameter block and data block will fit within a single request - // packet - - int plen = totParamLen; - int dlen = totDataLen; - - if ((plen + dlen) > availBuf) - { - - // Calculate the parameter/data block sizes to send in the first request packet - - if (plen > 0) - { - - // Check if the parameter block can fit into the packet - - if (plen <= availBuf) - { - - // Pack all of the parameter block and fill the remaining buffer with the data - // block - - if (dlen > 0) - dlen = availBuf - plen; - } - else - { - - // Split the parameter/data space in the packet - - plen = availBuf / 2; - dlen = plen; - } - } - else if (dlen > availBuf) - { - - // Fill the packet with the first section of the data block - - dlen = availBuf; - } - } - - // Set the parameter/data block counts for this packet - - setParameterBlockCount(plen); - setDataBlockCount(dlen); - - // Pack the setup bytes - - if (setupBuf != null) - setupBuf.copyData(getBuffer(), SetupOffsetResponse); - - // Pack the parameter block - - int pos = DataPacker.wordAlign(getByteOffset()); - setPosition(pos); - - // Set the parameter block offset, from the start of the SMB packet - - setParameterBlockCount(plen); - setParameterBlockOffset(pos); - - int packLen = -1; - - if (paramBuf != null) - { - - // Pack the parameter block - - packLen = paramBuf.copyData(getBuffer(), pos, plen); - - // Update the buffer position for the data block - - pos = DataPacker.longwordAlign(pos + packLen); - setPosition(pos); - } - - // Set the data block offset - - setDataBlockCount(dlen); - setDataBlockOffset(pos); - - // Pack the data block - - if (dataBuf != null) - { - - // Pack the data block - - packLen = dataBuf.copyData(getBuffer(), pos, dlen); - - // Update the end of buffer position - - setPosition(pos + packLen); - } - - // Set the byte count for the SMB packet - - setByteCount(); - - // Send the start of the transaction request - - sess.sendResponseSMB(this); - - // Get the available parameter/data block buffer space for the secondary packet - - availBuf = getAvailableLength(); - if (availBuf > clientLen) - availBuf = clientLen; - - // Loop until all parameter/data block data has been sent to the server - - TransactBuffer rxBuf = null; - - while ((paramBuf != null && paramBuf.getAvailableLength() > 0) - || (dataBuf != null && dataBuf.getAvailableLength() > 0)) - { - - // Setup the NT transaction secondary packet to send the remaining parameter/data blocks - - setCommand(tbuf.isType()); - - // Get the remaining parameter/data block lengths - - plen = paramBuf != null ? paramBuf.getAvailableLength() : 0; - dlen = dataBuf != null ? dataBuf.getAvailableLength() : 0; - - if ((plen + dlen) > availBuf) - { - - // Calculate the parameter/data block sizes to send in the first request packet - - if (plen > 0) - { - - // Check if the remaining parameter block can fit into the packet - - if (plen <= availBuf) - { - - // Pack all of the parameter block and fill the remaining buffer with the - // data block - - if (dlen > 0) - dlen = availBuf - plen; - } - else - { - - // Split the parameter/data space in the packet - - plen = availBuf / 2; - dlen = plen; - } - } - else if (dlen > availBuf) - { - - // Fill the packet with the first section of the data block - - dlen = availBuf; - } - } - - // Pack the parameter block data, if any - - resetBytePointerAlign(); - - packLen = -1; - pos = getPosition(); - - if (plen > 0 && paramBuf != null) - { - - // Set the parameter block offset, from the start of the SMB packet - - setParameterBlockOffset(pos); - setParameterBlockCount(plen); - setParameterBlockDisplacement(paramBuf.getDisplacement()); - - // Pack the parameter block - - packLen = paramBuf.copyData(getBuffer(), pos, plen); - - // Update the buffer position for the data block - - pos = DataPacker.wordAlign(pos + packLen); - setPosition(pos); - } - else - { - - // No parameter data, clear the count/offset - - setParameterBlockCount(0); - setParameterBlockOffset(pos); - } - - // Pack the data block, if any - - if (dlen > 0 && dataBuf != null) - { - - // Set the data block offset - - setDataBlockOffset(pos); - setDataBlockCount(dlen); - setDataBlockDisplacement(dataBuf.getDisplacement()); - - // Pack the data block - - packLen = dataBuf.copyData(getBuffer(), pos, dlen); - - // Update the end of buffer position - - setPosition(pos + packLen); - } - else - { - - // No data, clear the count/offset - - setDataBlockCount(0); - setDataBlockOffset(pos); - } - - // Set the byte count for the SMB packet to set the overall length - - setByteCount(); - - // Send the transaction response packet - - sess.sendResponseSMB(this); - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SMBTransPacket.java b/source/java/org/alfresco/filesys/smb/server/SMBTransPacket.java deleted file mode 100644 index 53890e9065..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SMBTransPacket.java +++ /dev/null @@ -1,399 +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.smb.server; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.util.DataPacker; - -/** - * SMB transact packet class - */ - -public class SMBTransPacket extends SMBSrvPacket -{ - - // Define the number of standard parameters - - protected static final int STD_PARAMS = 14; - - // Transaction status that indicates that this transaction has more data - // to be returned. - - public static final int IsContinued = 234; - - // Transact name, not used for transact 2 - - protected String m_transName; - - // Parameter count for this transaction - - protected int m_paramCnt; - - // Multiplex identifier, to identify each transaction request - - private static int m_nextMID = 1; - - /** - * Construct an SMB transaction packet - * - * @param buf Buffer that contains the SMB transaction packet. - */ - public SMBTransPacket(byte[] buf) - { - super(buf); - } - - /** - * Construct an SMB transaction packet - * - * @param siz Size of packet to allocate. - */ - public SMBTransPacket(int siz) - { - super(siz); - - // Set the multiplex id for this transaction - - setMultiplexId(getNextMultiplexId()); - } - - /** - * Get the next multiplex id to uniquely identify this transaction - * - * @return Unique multiplex id for this transaction - */ - public final static int getNextMultiplexId() - { - return m_nextMID++; - } - - /** - * Return the total parameter byte count - * - * @return int - */ - public final int getTotalParameterCount() - { - return getParameter(0); - } - - /** - * Return the total data byte count - * - * @return int - */ - public final int getTotalDataCount() - { - return getParameter(1); - } - - /** - * Return the parameter count size in bytes for this section - * - * @return int - */ - public final int getParameterBlockCount() - { - return getParameter(9); - } - - /** - * Return the parameter block offset - * - * @return Paramter block offset within the SMB packet - */ - public final int getParameterBlockOffset() - { - return getParameter(10) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the data block size in bytes for this section - * - * @return int - */ - public final int getDataBlockCount() - { - return getParameter(11); - } - - /** - * Return the data block offset - * - * @return Data block offset within the SMB packet. - */ - public final int getDataBlockOffset() - { - return getParameter(12) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the secondary parameter block size in bytes - * - * @return int - */ - public final int getSecondaryParameterBlockCount() - { - return getParameter(2); - } - - /** - * Return the secondary parameter block offset - * - * @return int - */ - public final int getSecondaryParameterBlockOffset() - { - return getParameter(3) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the secondary parameter block displacement - * - * @return int - */ - public final int getParameterBlockDisplacement() - { - return getParameter(4); - } - - /** - * Return the secondary data block size in bytes - * - * @return int - */ - public final int getSecondaryDataBlockCount() - { - return getParameter(5); - } - - /** - * Return the secondary data block offset - * - * @return int - */ - public final int getSecondaryDataBlockOffset() - { - return getParameter(6) + RFCNetBIOSProtocol.HEADER_LEN; - } - - /** - * Return the secondary data block displacement - * - * @return int - */ - public final int getDataBlockDisplacement() - { - return getParameter(7); - } - - /** - * Return the transaction sub-command - * - * @return int - */ - public final int getSubFunction() - { - return getParameter(14); - } - - /** - * Unpack the parameter block into the supplied array. - * - * @param prmblk Array to unpack the parameter block words into. - */ - public final void getParameterBlock(short[] prmblk) throws java.lang.ArrayIndexOutOfBoundsException - { - - // Determine how many parameters are to be unpacked, check if the user - // buffer is long enough - - int prmcnt = getParameter(3) / 2; // convert to number of words - if (prmblk.length < prmcnt) - throw new java.lang.ArrayIndexOutOfBoundsException(); - - // Get the offset to the parameter words, add the NetBIOS header length - // to the offset. - - int pos = getParameter(4) + RFCNetBIOSProtocol.HEADER_LEN; - - // Unpack the parameter words - - byte[] buf = getBuffer(); - - for (int idx = 0; idx < prmcnt; idx++) - { - - // Unpack the current parameter word - - prmblk[idx] = (short) DataPacker.getIntelShort(buf, pos); - pos += 2; - } - } - - /** - * Initialize the transact SMB packet - * - * @param pcnt Total parameter count for this transaction - * @param paramblk Parameter block data bytes - * @param plen Parameter block data length - * @param datablk Data block data bytes - * @param dlen Data block data length - */ - public final void InitializeTransact(int pcnt, byte[] paramblk, int plen, byte[] datablk, int dlen) - { - - // Set the SMB command code - - if (m_transName == null) - setCommand(PacketType.Transaction2); - else - setCommand(PacketType.Transaction); - - // Set the parameter count - - setParameterCount(pcnt); - - // Save the parameter count, add an extra parameter for the data byte count - - m_paramCnt = pcnt; - - // Initialize the parameters - - setParameter(0, plen); // total parameter bytes being sent - setParameter(1, dlen); // total data bytes being sent - - for (int i = 2; i < 9; setParameter(i++, 0)) - ; - - setParameter(9, plen); // parameter bytes sent in this packet - setParameter(11, dlen); // data bytes sent in this packet - - setParameter(13, pcnt - STD_PARAMS); // number of setup words - - // Get the data byte offset - - int pos = getByteOffset(); - int startPos = pos; - - // Check if this is a named transaction, if so then store the name - - int idx; - byte[] buf = getBuffer(); - - if (m_transName != null) - { - - // Store the transaction name - - byte[] nam = m_transName.getBytes(); - - for (idx = 0; idx < nam.length; idx++) - buf[pos++] = nam[idx]; - } - - // Word align the buffer offset - - if ((pos % 2) > 0) - pos++; - - // Store the parameter block - - if (paramblk != null) - { - - // Set the parameter block offset - - setParameter(10, pos - RFCNetBIOSProtocol.HEADER_LEN); - - // Store the parameter block - - for (idx = 0; idx < plen; idx++) - buf[pos++] = paramblk[idx]; - } - else - { - - // Clear the parameter block offset - - setParameter(10, 0); - } - - // Word align the data block - - if ((pos % 2) > 0) - pos++; - - // Store the data block - - if (datablk != null) - { - - // Set the data block offset - - setParameter(12, pos - RFCNetBIOSProtocol.HEADER_LEN); - - // Store the data block - - for (idx = 0; idx < dlen; idx++) - buf[pos++] = datablk[idx]; - } - else - { - - // Zero the data block offset - - setParameter(12, 0); - } - - // Set the byte count for the SMB packet - - setByteCount(pos - startPos); - } - - /** - * Set the specifiec setup parameter within the SMB packet. - * - * @param idx Setup parameter index. - * @param val Setup parameter value. - */ - - public final void setSetupParameter(int idx, int val) - { - setParameter(STD_PARAMS + idx, val); - } - - /** - * Set the transaction name for normal transactions - * - * @param tname Transaction name string - */ - - public final void setTransactionName(String tname) - { - m_transName = tname; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/SecurityMode.java b/source/java/org/alfresco/filesys/smb/server/SecurityMode.java deleted file mode 100644 index ca902536de..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SecurityMode.java +++ /dev/null @@ -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.smb.server; - -/** - * Security Mode Class - * - *

CIFS security mode constants. - * - * @author gkspencer - */ -public class SecurityMode -{ - // Security mode flags returned in the SMB negotiate response - - public static final int UserMode = 0x0001; - public static final int EncryptedPasswords = 0x0002; - public static final int SignaturesEnabled = 0x0004; - public static final int SignaturesRequired = 0x0008; -} diff --git a/source/java/org/alfresco/filesys/smb/server/SessionSocketHandler.java b/source/java/org/alfresco/filesys/smb/server/SessionSocketHandler.java deleted file mode 100644 index 2b909fe026..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SessionSocketHandler.java +++ /dev/null @@ -1,293 +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.smb.server; - -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.SocketException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Session Socket Handler Abstract Class - * - * @author GKSpencer - */ -public abstract class SessionSocketHandler implements Runnable -{ - // Debug logging - - protected static Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Define the listen backlog for the server socket - - protected static final int LISTEN_BACKLOG = 10; - - // Server that the socket handler is associated with - - private SMBServer m_server; - - // Address/post to use - - private int m_port; - private InetAddress m_bindAddr; - - // Server socket - - private ServerSocket m_srvSock; - - // Debug output enable - - private boolean m_debug; - - // Socket handler thread shutdown flag - - private boolean m_shutdown; - - // Session socket handler name - - private String m_name; - - // Session id - - private static int m_sessId; - - /** - * Class constructor - * - * @param name String - * @param srv SMBServer - * @param port int - * @param bindAddr InetAddress - * @param debug boolean - */ - public SessionSocketHandler(String name, SMBServer srv, int port, InetAddress bindAddr, boolean debug) - { - m_name = name; - m_server = srv; - m_port = port; - m_bindAddr = bindAddr; - m_debug = debug; - } - - /** - * Class constructor - * - * @param name String - * @param srv SMBServer - * @param debug boolean - */ - public SessionSocketHandler(String name, SMBServer srv, boolean debug) - { - m_name = name; - m_server = srv; - m_debug = debug; - } - - /** - * Return the handler name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the server - * - * @return SMBServer - */ - protected final SMBServer getServer() - { - return m_server; - } - - /** - * Return the port - * - * @return int - */ - protected final int getPort() - { - return m_port; - } - - /** - * Determine if the socket handler should bind to a particular address - * - * @return boolean - */ - protected final boolean hasBindAddress() - { - return m_bindAddr != null ? true : false; - } - - /** - * Return the bind address return InetAddress - */ - protected final InetAddress getBindAddress() - { - return m_bindAddr; - } - - /** - * Return the next session id - * - * @return int - */ - protected final synchronized int getNextSessionId() - { - return m_sessId++; - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - protected final boolean hasDebug() - { - return m_debug; - } - - /** - * Return the server socket - * - * @return ServerSocket - */ - protected final ServerSocket getSocket() - { - return m_srvSock; - } - - /** - * Set the server socket - * - * @param sock ServerSocket - */ - protected final void setSocket(ServerSocket sock) - { - m_srvSock = sock; - } - - /** - * Determine if the shutdown flag is set - * - * @return boolean - */ - protected final boolean hasShutdown() - { - return m_shutdown; - } - - /** - * Clear the shutdown request flag - */ - protected final void clearShutdown() - { - m_shutdown = false; - } - - /** - * Request the socket handler to shutdown - */ - public void shutdownRequest() - { - - // Indicate that the server is closing - - m_shutdown = true; - - try - { - - // Close the server socket so that any pending receive is cancelled - - if (m_srvSock != null) - m_srvSock.close(); - } - catch (SocketException ex) - { - } - catch (Exception ex) - { - } - } - - /** - * Initialize the session socket handler - * - * @exception Exception - */ - public void initialize() throws Exception - { - - // Check if the server should bind to a particular local address, or all local addresses - - ServerSocket srvSock = null; - - if (hasBindAddress()) - srvSock = new ServerSocket(getPort(), LISTEN_BACKLOG, getBindAddress()); - else - srvSock = new ServerSocket(getPort(), LISTEN_BACKLOG); - setSocket(srvSock); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Binding " + getName() + " session handler to local address : " - + (hasBindAddress() ? getBindAddress().getHostAddress() : "ALL")); - } - - /** - * @see Runnable#run() - */ - public abstract void run(); - - /** - * Return the session socket handler as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getName()); - str.append(","); - str.append(getServer().getServerName()); - str.append(","); - str.append(getBindAddress() != null ? getBindAddress().getHostAddress() : ""); - str.append(":"); - str.append(getPort()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/SrvSessionFactory.java b/source/java/org/alfresco/filesys/smb/server/SrvSessionFactory.java deleted file mode 100644 index dbedd8851d..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SrvSessionFactory.java +++ /dev/null @@ -1,41 +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.smb.server; - -/** - * Server Session Factory Interface - */ -public interface SrvSessionFactory -{ - - /** - * Create a new server session object - * - * @param handler PacketHandler - * @param server SMBServer - * @return SMBSrvSession - */ - public SMBSrvSession createSession(PacketHandler handler, SMBServer server); -} diff --git a/source/java/org/alfresco/filesys/smb/server/SrvTransactBuffer.java b/source/java/org/alfresco/filesys/smb/server/SrvTransactBuffer.java deleted file mode 100644 index bb5fca0b35..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/SrvTransactBuffer.java +++ /dev/null @@ -1,197 +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.smb.server; - -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.TransactBuffer; -import org.alfresco.filesys.util.DataBuffer; -import org.alfresco.filesys.util.DataPacker; - -/** - * Transact Buffer Class - *

- * Contains the parameters and data for a transaction, transaction2 or NT transaction request. - */ -class SrvTransactBuffer extends TransactBuffer -{ - - /** - * Class constructor - * - * @param slen int - * @param plen int - * @param dlen int - */ - public SrvTransactBuffer(int slen, int plen, int dlen) - { - super(slen, plen, dlen); - } - - /** - * Class constructor - *

- * Construct a TransactBuffer using the maximum size settings from the specified transaction - * buffer - * - * @param tbuf SrvTransactBuffer - */ - public SrvTransactBuffer(SrvTransactBuffer tbuf) - { - super(tbuf.getReturnSetupLimit(), tbuf.getReturnParameterLimit(), tbuf.getReturnDataLimit()); - - // Save the return limits for this transaction buffer - - setReturnLimits(tbuf.getReturnSetupLimit(), tbuf.getReturnParameterLimit(), tbuf.getReturnDataLimit()); - - // Set the transaction reply type - - setType(tbuf.isType()); - - // Copy the tree id - - setTreeId(tbuf.getTreeId()); - } - - /** - * Class constructor - * - * @param ntpkt NTTransPacket - */ - public SrvTransactBuffer(NTTransPacket ntpkt) - { - - // Call the base constructor so that it does not allocate any buffers - - super(0, 0, 0); - - // Set the tree id - - setTreeId(ntpkt.getTreeId()); - - // Set the setup block and size - - int slen = ntpkt.getSetupCount() * 2; - if (slen > 0) - m_setupBuf = new DataBuffer(ntpkt.getBuffer(), ntpkt.getSetupOffset(), slen); - - // Set the parameter block and size - - int plen = ntpkt.getTotalParameterCount(); - if (plen > 0) - m_paramBuf = new DataBuffer(ntpkt.getBuffer(), ntpkt.getParameterBlockOffset(), plen); - - // Set the data block and size - - int dlen = ntpkt.getDataBlockCount(); - if (dlen > 0) - m_dataBuf = new DataBuffer(ntpkt.getBuffer(), ntpkt.getDataBlockOffset(), dlen); - - // Set the transaction type and sub-function - - setType(ntpkt.getCommand()); - setFunction(ntpkt.getNTFunction()); - - // Set the maximum parameter and data block lengths to be returned - - setReturnParameterLimit(ntpkt.getMaximumParameterReturn()); - setReturnDataLimit(ntpkt.getMaximumDataReturn()); - - // Set the Unicode flag - - setUnicode(ntpkt.isUnicode()); - - // Indicate that this is a not a multi-packet transaction - - m_multi = false; - } - - /** - * Class constructor - * - * @param tpkt SMBSrvTransPacket - */ - public SrvTransactBuffer(SMBSrvTransPacket tpkt) - { - - // Call the base constructor so that it does not allocate any buffers - - super(0, 0, 0); - - // Set the tree id - - setTreeId(tpkt.getTreeId()); - - // Set the setup block and size - - int slen = tpkt.getSetupCount() * 2; - if (slen > 0) - m_setupBuf = new DataBuffer(tpkt.getBuffer(), tpkt.getSetupOffset(), slen); - - // Set the parameter block and size - - int plen = tpkt.getTotalParameterCount(); - if (plen > 0) - m_paramBuf = new DataBuffer(tpkt.getBuffer(), tpkt.getRxParameterBlock(), plen); - - // Set the data block and size - - int dlen = tpkt.getRxDataBlockLength(); - if (dlen > 0) - m_dataBuf = new DataBuffer(tpkt.getBuffer(), tpkt.getRxDataBlock(), dlen); - - // Set the transaction type and sub-function - - setType(tpkt.getCommand()); - - if (tpkt.getSetupCount() > 0) - setFunction(tpkt.getSetupParameter(0)); - - // Set the Unicode flag - - setUnicode(tpkt.isUnicode()); - - // Get the transaction name, if used - - if (isType() == PacketType.Transaction) - { - - // Unpack the transaction name string - - int pos = tpkt.getByteOffset(); - byte[] buf = tpkt.getBuffer(); - - if (isUnicode()) - pos = DataPacker.wordAlign(pos); - - setName(DataPacker.getString(buf, pos, 64, isUnicode())); - } - else - setName(""); - - // Indicate that this is a not a multi-packet transaction - - m_multi = false; - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/TcpipSMBPacketHandler.java b/source/java/org/alfresco/filesys/smb/server/TcpipSMBPacketHandler.java deleted file mode 100644 index 9e645268bd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/TcpipSMBPacketHandler.java +++ /dev/null @@ -1,164 +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.smb.server; - -import java.io.IOException; -import java.net.Socket; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.util.DataPacker; - -/** - * Tcpip SMB Packet Handler Class - */ -public class TcpipSMBPacketHandler extends PacketHandler -{ - - /** - * Class constructor - * - * @param sock Socket - * @exception IOException If a network error occurs - */ - public TcpipSMBPacketHandler(Socket sock) throws IOException - { - super(sock, SMBSrvPacket.PROTOCOL_TCPIP, "TCP-SMB", "T"); - } - - /** - * Read a packet from the input stream - * - * @param pkt SMBSrvPacket - * @return int - * @exception IOexception If a network error occurs - */ - public int readPacket(SMBSrvPacket pkt) throws IOException - { - - // Read the packet header - - byte[] buf = pkt.getBuffer(); - int len = 0; - - while (len < RFCNetBIOSProtocol.HEADER_LEN && len != -1) - len = readPacket(buf, len, RFCNetBIOSProtocol.HEADER_LEN - len); - - // Check if the connection has been closed, read length equals -1 - - if (len == -1) - return len; - - // Check if we received a valid header - - if (len < RFCNetBIOSProtocol.HEADER_LEN) - throw new IOException("Invalid header, len=" + len); - - // Get the packet type from the header - - int typ = (int) (buf[0] & 0xFF); - int dlen = (int) DataPacker.getShort(buf, 2); - - // Check for a large packet, add to the data length - - if (buf[1] != 0) - { - int llen = (int) buf[1]; - dlen += (llen << 16); - } - - // Check if the packet buffer is large enough to hold the data + header - - if (buf.length < (dlen + RFCNetBIOSProtocol.HEADER_LEN)) - { - - // Allocate a new buffer to hold the data and copy the existing header - - byte[] newBuf = new byte[dlen + RFCNetBIOSProtocol.HEADER_LEN]; - for (int i = 0; i < 4; i++) - newBuf[i] = buf[i]; - - // Attach the new buffer to the SMB packet - - pkt.setBuffer(newBuf); - buf = newBuf; - } - - // Read the data part of the packet into the users buffer, this may take - // several reads - - int offset = RFCNetBIOSProtocol.HEADER_LEN; - int totlen = offset; - - while (dlen > 0) - { - - // Read the data - - len = readPacket(buf, offset, dlen); - - // Check if the connection has been closed - - if (len == -1) - return -1; - - // Update the received length and remaining data length - - totlen += len; - dlen -= len; - - // Update the user buffer offset as more reads will be required - // to complete the data read - - offset += len; - - } // end while reading data - - // Return the received packet length - - return totlen; - } - - /** - * Send a packet to the output stream - * - * @param pkt SMBSrvPacket - * @param len int - * @exception IOexception If a network error occurs - */ - public void writePacket(SMBSrvPacket pkt, int len) throws IOException - { - - // Fill in the TCP SMB message header, this is already allocated as - // part of the users buffer. - - byte[] buf = pkt.getBuffer(); - DataPacker.putInt(len, buf, 0); - - // Output the data packet - - int bufSiz = len + RFCNetBIOSProtocol.HEADER_LEN; - writePacket(buf, 0, bufSiz); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/TcpipSMBSessionSocketHandler.java b/source/java/org/alfresco/filesys/smb/server/TcpipSMBSessionSocketHandler.java deleted file mode 100644 index b389ca4b3d..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/TcpipSMBSessionSocketHandler.java +++ /dev/null @@ -1,179 +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.smb.server; - -import java.net.InetAddress; -import java.net.Socket; -import java.net.SocketException; - -import org.alfresco.filesys.server.config.ServerConfiguration; - -/** - * Native SMB Session Socket Handler Class - */ -public class TcpipSMBSessionSocketHandler extends SessionSocketHandler -{ - // Session Thread group - private static final ThreadGroup THREAD_GROUP_SESSION = new ThreadGroup("SMB_SESSION_GROUP"); - - /** - * Class constructor - * - * @param srv SMBServer - * @param port int - * @param bindAddr InetAddress - * @param debug boolean - */ - public TcpipSMBSessionSocketHandler(SMBServer srv, int port, InetAddress bindAddr, boolean debug) - { - super("TCP-SMB", srv, port, bindAddr, debug); - } - - /** - * Run the native SMB session socket handler - */ - public void run() - { - - try - { - - // Clear the shutdown flag - - clearShutdown(); - - // Wait for incoming connection requests - - while (hasShutdown() == false) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Waiting for TCP-SMB session request ..."); - - // Wait for a connection - - Socket sessSock = getSocket().accept(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("TCP-SMB session request received from " - + sessSock.getInetAddress().getHostAddress()); - - try - { - - // Create a packet handler for the session - - PacketHandler pktHandler = new TcpipSMBPacketHandler(sessSock); - - // Create a server session for the new request, and set the session id. - - SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); - srvSess.setSessionId(getNextSessionId()); - srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); - - // Add the session to the active session list - - getServer().addSession(srvSess); - - // Start the new session in a seperate thread - - Thread srvThread = new Thread(THREAD_GROUP_SESSION, srvSess); - srvThread.setDaemon(true); - srvThread.setName("Sess_T" + srvSess.getSessionId() + "_" - + sessSock.getInetAddress().getHostAddress()); - srvThread.start(); - } - catch (Exception ex) - { - - // Debug - - logger.error("TCP-SMB Failed to create session, ", 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("TCP-SMB Socket error : ", ex); - } - 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("TCP-SMB Server error : ", ex); - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("TCP-SMB session handler closed"); - } - - /** - * Create the TCP/IP native SMB/CIFS session socket handlers for the main SMB/CIFS server - * - * @param server SMBServer - * @param sockDbg boolean - * @exception Exception - */ - public final static void createSessionHandlers(SMBServer server, boolean sockDbg) throws Exception - { - - // Access the server configuration - - ServerConfiguration config = server.getConfiguration(); - - // Create the NetBIOS SMB handler - - SessionSocketHandler sessHandler = new TcpipSMBSessionSocketHandler(server, config.getTcpipSMBPort(), config - .getSMBBindAddress(), sockDbg); - - sessHandler.initialize(); - server.addSessionHandler(sessHandler); - - // Run the TCP/IP SMB session handler in a seperate thread - - Thread tcpThread = new Thread(sessHandler); - tcpThread.setName("TcpipSMB_Handler"); - tcpThread.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("Native SMB TCP session handler created on port " + config.getTcpipSMBPort()); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java b/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java deleted file mode 100644 index cd05c2a2a5..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/VirtualCircuit.java +++ /dev/null @@ -1,531 +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.smb.server; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.auth.ClientInfo; -import org.alfresco.filesys.server.core.DeviceInterface; -import org.alfresco.filesys.server.core.SharedDevice; -import org.alfresco.filesys.server.filesys.DiskInterface; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.SearchContext; -import org.alfresco.filesys.server.filesys.TooManyConnectionsException; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Virtual Circuit Class - * - *

- * Represents an authenticated circuit on an SMB/CIFS session. There may be - * multiple virtual circuits opened on a single session/socket connection. - */ -public class VirtualCircuit { - - // Debug logging - - private static Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Default and maximum number of connection slots - - public static final int DefaultConnections = 4; - public static final int MaxConnections = 16; - - // Tree ids are 16bit values - - private static final int TreeIdMask = 0x0000FFFF; - - // Default and maximum number of search slots - - private static final int DefaultSearches = 8; - private static final int MaxSearches = 256; - - // Invalid UID value - - public static final int InvalidUID = -1; - - // Virtual circuit UID value - // - // Allocated by the server and sent by the client to identify the virtual circuit - - private int m_uid = -1; - - // Virtual circuit number - - private int m_vcNum; - - // Client information for this virtual circuit - - private ClientInfo m_clientInfo; - - // Active tree connections - - private Hashtable m_connections; - - private int m_treeId; - - // List of active searches - - private SearchContext[] m_search; - - private int m_searchCount; - - // Active transaction details - - private SrvTransactBuffer m_transact; - - /** - * Class constructor - * - * @param vcNum - * int - * @param cInfo - * ClientInfo - */ - public VirtualCircuit(int vcNum, ClientInfo cInfo) { - m_vcNum = vcNum; - m_clientInfo = cInfo; - } - - /** - * Return the virtual circuit UID - * - * @return int - */ - public final int getUID() { - return m_uid; - } - - /** - * Return the virtual circuit number - * - * @return int - */ - public final int getVCNumber() { - return m_vcNum; - } - - /** - * Return the client information - * - * @return ClientInfo - */ - public final ClientInfo getClientInformation() { - return m_clientInfo; - } - - /** - * Add a new connection to this virtual circuit. Return the allocated tree - * id for the new connection. - * - * @param shrDev SharedDevice - * @return int Allocated tree id (connection id). - */ - public int addConnection(SharedDevice shrDev) - throws TooManyConnectionsException { - - // Check if the connection array has been allocated - - if (m_connections == null) - m_connections = new Hashtable(DefaultConnections); - - // Allocate an id for the tree connection - - int treeId = 0; - - synchronized (m_connections) { - - // Check if the tree connection table is full - - if (m_connections.size() == MaxConnections) - throw new TooManyConnectionsException(); - - // Find a free slot in the connection array - - treeId = (m_treeId++ & TreeIdMask); - Integer key = new Integer(treeId); - - while (m_connections.contains(key)) { - - // Try another tree id for the new connection - - treeId = (m_treeId++ & TreeIdMask); - key = new Integer(treeId); - } - - // Store the new tree connection - - m_connections.put(key, new TreeConnection(shrDev)); - } - - // Return the allocated tree id - - return treeId; - } - - /** - * Return the tree connection details for the specified tree id. - * - * @return com.starla.smbsrv.TreeConnection - * @param treeId - * int - */ - public final TreeConnection findConnection(int treeId) { - - // Check if the tree id and connection array are valid - - if (m_connections == null) - return null; - - // Get the required tree connection details - - return m_connections.get(new Integer(treeId)); - } - - /** - * Remove the specified tree connection from the active connection list. - * - * @param treeId - * int - * @param srvSession - * SrvSession - */ - protected void removeConnection(int treeId, SrvSession sess) { - - // Check if the tree id is valid - - if (m_connections == null) - return; - - // Close the connection and remove from the connection list - - synchronized (m_connections) { - - // Get the connection - - Integer key = new Integer(treeId); - TreeConnection tree = m_connections.get(key); - - // Close the connection, release resources - - if (tree != null) { - - // Close the connection - - tree.closeConnection(sess); - - // Remove the connection from the connection list - - m_connections.remove(key); - } - } - } - - /** - * Return the active tree connection count - * - * @return int - */ - public final int getConnectionCount() { - return m_connections != null ? m_connections.size() : 0; - } - - /** - * Allocate a slot in the active searches list for a new search. - * - * @return int Search slot index, or -1 if there are no more search slots - * available. - */ - public final int allocateSearchSlot() { - - // Check if the search array has been allocated - - if (m_search == null) - m_search = new SearchContext[DefaultSearches]; - - // Find a free slot for the new search - - int idx = 0; - - while (idx < m_search.length && m_search[idx] != null) - idx++; - - // Check if we found a free slot - - if (idx == m_search.length) { - - // The search array needs to be extended, check if we reached the - // limit. - - if (m_search.length >= MaxSearches) - return -1; - - // Extend the search array - - SearchContext[] newSearch = new SearchContext[m_search.length * 2]; - System.arraycopy(m_search, 0, newSearch, 0, m_search.length); - m_search = newSearch; - } - - // Return the allocated search slot index - - m_searchCount++; - return idx; - } - - /** - * Deallocate the specified search context/slot. - * - * @param ctxId - * int - */ - public final void deallocateSearchSlot(int ctxId) { - - // Check if the search array has been allocated and that the index is - // valid - - if (m_search == null || ctxId >= m_search.length) - return; - - // Close the search - - if (m_search[ctxId] != null) - m_search[ctxId].closeSearch(); - - // Free the specified search context slot - - m_searchCount--; - m_search[ctxId] = null; - } - - /** - * Return the search context for the specified search id. - * - * @return com.starla.smbsrv.SearchContext - * @param srchId - * int - */ - public final SearchContext getSearchContext(int srchId) { - - // Check if the search array is valid and the search index is valid - - if (m_search == null || srchId >= m_search.length) - return null; - - // Return the required search context - - return m_search[srchId]; - } - - /** - * Store the seach context in the specified slot. - * - * @param slot - * Slot to store the search context. - * @param srch - * com.starla.smbsrv.SearchContext - */ - public final void setSearchContext(int slot, SearchContext srch) { - - // Check if the search slot id is valid - - if (m_search == null || slot > m_search.length) - return; - - // Store the context - - m_search[slot] = srch; - } - - /** - * Return the number of active tree searches. - * - * @return int - */ - public final int getSearchCount() { - return m_searchCount; - } - - /** - * Check if there is an active transaction - * - * @return boolean - */ - public final boolean hasTransaction() { - return m_transact != null ? true : false; - } - - /** - * Return the active transaction buffer - * - * @return TransactBuffer - */ - public final SrvTransactBuffer getTransaction() { - return m_transact; - } - - /** - * Set the active transaction buffer - * - * @param buf - * TransactBuffer - */ - public final void setTransaction(SrvTransactBuffer buf) { - m_transact = buf; - } - - /** - * Set the UID for the circuit - * - * @param uid - * int - */ - public final void setUID(int uid) { - m_uid = uid; - } - - /** - * Close the virtual circuit, close active tree connections - * - * @param sess - * SrvSession - */ - public final void closeCircuit(SrvSession sess) { - - // Debug - - if (logger.isDebugEnabled() && sess.hasDebug(SMBSrvSession.DBG_STATE)) - logger.debug("Cleanup vc=" + getVCNumber() + ", UID=" + getUID() + ", searches=" + getSearchCount() - + ", treeConns=" + getConnectionCount()); - - // Check if there are any active searches - - if (m_search != null) { - - // Close all active searches - - for (int idx = 0; idx < m_search.length; idx++) { - - // Check if the current search slot is active - - if (m_search[idx] != null) - deallocateSearchSlot(idx); - } - - // Release the search context list, clear the search count - - m_search = null; - m_searchCount = 0; - } - - // Check if there are open tree connections - - if (m_connections != null) { - - synchronized (m_connections) { - - // Close all active tree connections - - Enumeration enm = m_connections.elements(); - - while (enm.hasMoreElements()) { - - // Get the current tree connection - - TreeConnection tree = (TreeConnection) enm.nextElement(); - DeviceInterface devIface = tree.getInterface(); - - // Check if there are open files on the share - - if (tree.openFileCount() > 0) { - - // Close the open files, release locks - - for (int i = 0; i < tree.getFileTableLength(); i++) { - - // Get an open file - - NetworkFile curFile = tree.findFile(i); - if (curFile != null && devIface instanceof DiskInterface) { - - // Access the disk share interface - - DiskInterface diskIface = (DiskInterface) devIface; - - try { - - // Remove the file from the tree connection list - - tree.removeFile(i, sess); - - // Close the file - - diskIface.closeFile(sess, tree, curFile); - } - catch (Exception ex) { - } - } - } - } - - // Inform the driver that the connection has been closed - - if (devIface != null) - devIface.treeClosed(sess, tree); - } - - // Clear the tree connection list - - m_connections.clear(); - } - } - } - - /** - * Return the virtual circuit details as a string - * - * @return String - */ - public String toString() { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getVCNumber()); - str.append(":"); - str.append(getUID()); - str.append(","); - str.append(getClientInformation()); - str.append(",Tree="); - str.append(getConnectionCount()); - str.append(",Searches="); - str.append(getSearchCount()); - str.append("]"); - - return str.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java b/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java deleted file mode 100644 index a8aa2683dd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/VirtualCircuitList.java +++ /dev/null @@ -1,227 +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.smb.server; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.alfresco.filesys.server.SrvSession; - -/** - * Virtual Circuit List Class - * - *

- * Contains a list of virtual circuits that belong to a session. - */ -public class VirtualCircuitList { - - // Default and maximum number of virtual circuits - - public static final int DefaultCircuits = 4; - public static final int MaxCircuits = 16; - - // UIDs are 16bit values - - private static final int UIDMask = 0x0000FFFF; - - // Active virtual circuits - - private Hashtable m_vcircuits; - - // Next available UID - - private int m_UID; - - /** - * Default constructor - */ - public VirtualCircuitList() { - - } - - /** - * Add a new virtual circuit to this session. Return the allocated UID for - * the new circuit. - * - * @param vcircuit - * VirtualCircuit - * @return int Allocated UID. - */ - public int addCircuit(VirtualCircuit vcircuit) { - - // Check if the circuit table has been allocated - - if (m_vcircuits == null) - m_vcircuits = new Hashtable(DefaultCircuits); - - // Allocate an id for the tree connection - - int uid = 0; - - synchronized (m_vcircuits) { - - // Check if the virtual circuit table is full - - if (m_vcircuits.size() == MaxCircuits) - return VirtualCircuit.InvalidUID; - - // Find a free slot in the circuit table - - uid = (m_UID++ & UIDMask); - Integer key = new Integer(uid); - - while (m_vcircuits.contains(key)) { - - // Try another user id for the new virtual circuit - - uid = (m_UID++ & UIDMask); - key = new Integer(uid); - } - - // Store the new virtual circuit - - vcircuit.setUID(uid); - m_vcircuits.put(key, vcircuit); - } - - // Return the allocated UID - - return uid; - } - - /** - * Return the virtual circuit details for the specified UID. - * - * @param uid - * int - * @return VirtualCircuit - */ - public final VirtualCircuit findCircuit(int uid) { - - // Check if the circuit table is valid - - if (m_vcircuits == null) - return null; - - // Get the required tree connection details - - return m_vcircuits.get(new Integer(uid)); - } - - /** - * Return the virtual circuit details for the specified UID. - * - * @param uid - * Integer - * @return VirtualCircuit - */ - public final VirtualCircuit findCircuit(Integer uid) { - - // Check if the circuit table is valid - - if (m_vcircuits == null) - return null; - - // Get the required tree connection details - - return m_vcircuits.get(uid); - } - - /** - * Enumerate the virtual circiuts - * - * @return Enumeration - */ - public final Enumeration enumerateUIDs() { - return m_vcircuits.keys(); - } - - /** - * Remove the specified virtual circuit from the active circuit list. - * - * @param uid int - * @param srvSession SrvSession - */ - public void removeCircuit(int uid, SrvSession sess) { - - // Check if the circuit table is valid - - if (m_vcircuits == null) - return; - - // Close the circuit and remove from the circuit table - - synchronized (m_vcircuits) { - - // Get the circuit - - Integer key = new Integer(uid); - VirtualCircuit vc = (VirtualCircuit) m_vcircuits.get(key); - - // Close the virtual circuit, release resources - - if (vc != null) { - - // Close the circuit - - vc.closeCircuit(sess); - - // Remove the circuit from the circuit table - - m_vcircuits.remove(key); - } - } - } - - /** - * Return the active tree connection count - * - * @return int - */ - public final int getCircuitCount() { - return m_vcircuits != null ? m_vcircuits.size() : 0; - } - - /** - * Clear the virtual circuit list - */ - public final void clearCircuitList() { - m_vcircuits.clear(); - } - - /** - * Return the virtual circuit list details as a string - * - * @return String - */ - public String toString() { - StringBuffer str = new StringBuffer(); - - str.append("[VCs="); - str.append(getCircuitCount()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEvent.java b/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEvent.java deleted file mode 100644 index 1b331ba4dd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEvent.java +++ /dev/null @@ -1,227 +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.smb.server.notify; - -import org.alfresco.filesys.server.filesys.NotifyChange; - -/** - * Notify Change Event Class - *

- * Contains the details of a change notification event - */ -public class NotifyChangeEvent -{ - - // Notification event action and filter type - - private int m_action; - private int m_filter; - - // Notification file/directory name - - private String m_fileName; - - // Path is a directory - - private boolean m_dir; - - // Original file name for file/directory rename - - private String m_oldName; - - /** - * Class constructor - * - * @param filter int - * @param action int - * @param fname String - * @param dir boolean - */ - public NotifyChangeEvent(int filter, int action, String fname, boolean dir) - { - m_filter = filter; - m_action = action; - m_fileName = fname; - m_dir = dir; - - // Normalize the path - - if (m_fileName.indexOf('/') != -1) - m_fileName.replace('/', '\\'); - } - - /** - * Class constructor - * - * @param filter int - * @param action int - * @param fname String - * @param oldname String - * @param dir boolean - */ - public NotifyChangeEvent(int filter, int action, String fname, String oldname, boolean dir) - { - m_filter = filter; - m_action = action; - m_fileName = fname; - m_oldName = oldname; - m_dir = dir; - - // Normalize the path - - if (m_fileName.indexOf('/') != -1) - m_fileName.replace('/', '\\'); - - if (m_oldName.indexOf('/') != -1) - m_oldName.replace('/', '\\'); - } - - /** - * Return the event filter type - * - * @return int - */ - public final int getFilter() - { - return m_filter; - } - - /** - * Return the action - * - * @return int - */ - public final int getAction() - { - return m_action; - } - - /** - * Return the file/directory name - * - * @return String - */ - public final String getFileName() - { - return m_fileName; - } - - /** - * Return the file/directory name only by stripping any leading path - * - * @return String - */ - public final String getShortFileName() - { - - // Find the last '\' in the path string - - int pos = m_fileName.lastIndexOf("\\"); - if (pos != -1) - return m_fileName.substring(pos + 1); - return m_fileName; - } - - /** - * Return the old file/directory name, for rename events - * - * @return String - */ - public final String getOldFileName() - { - return m_oldName; - } - - /** - * Return the old file/directory name only by stripping any leading path - * - * @return String - */ - public final String getShortOldFileName() - { - - // Check if the old path string is valid - - if (m_oldName == null) - return null; - - // Find the last '\' in the path string - - int pos = m_oldName.lastIndexOf("\\"); - if (pos != -1) - return m_oldName.substring(pos + 1); - return m_oldName; - } - - /** - * Check if the old file/directory name is valid - * - * @return boolean - */ - public final boolean hasOldFileName() - { - return m_oldName != null ? true : false; - } - - /** - * Check if the path refers to a directory - * - * @return boolean - */ - public final boolean isDirectory() - { - return m_dir; - } - - /** - * Return the notify change event as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(NotifyChange.getFilterAsString(getFilter())); - str.append("-"); - str.append(NotifyChange.getActionAsString(getAction())); - str.append(":"); - str.append(getFileName()); - - if (isDirectory()) - str.append(",DIR"); - - if (hasOldFileName()) - { - str.append(",Old="); - str.append(getOldFileName()); - } - - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEventList.java b/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEventList.java deleted file mode 100644 index 376c927550..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeEventList.java +++ /dev/null @@ -1,112 +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.smb.server.notify; - -import java.util.Vector; - -/** - * Notify Change Event List Class - */ -public class NotifyChangeEventList -{ - - // List of notify events - - private Vector m_list; - - /** - * Default constructor - */ - public NotifyChangeEventList() - { - m_list = new Vector(); - } - - /** - * Return the count of notify events - * - * @return int - */ - public final int numberOfEvents() - { - return m_list.size(); - } - - /** - * Return the specified change event - * - * @param idx int - * @return NotifyChangeEvent - */ - public final NotifyChangeEvent getEventAt(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_list.size()) - return null; - - // Return the required notify event - - return m_list.get(idx); - } - - /** - * Add a change event to the list - * - * @param evt NotifyChangeEvent - */ - public final void addEvent(NotifyChangeEvent evt) - { - m_list.add(evt); - } - - /** - * Remove the specified change event - * - * @param idx int - * @return NotifyChangeEvent - */ - public final NotifyChangeEvent removeEventAt(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_list.size()) - return null; - - // Return the required notify event - - return m_list.remove(idx); - } - - /** - * Remove all events from the list - */ - public final void removeAllEvents() - { - m_list.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeHandler.java b/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeHandler.java deleted file mode 100644 index 7b2b86305a..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/notify/NotifyChangeHandler.java +++ /dev/null @@ -1,1127 +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.smb.server.notify; - -import java.util.Vector; - -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.FileName; -import org.alfresco.filesys.server.filesys.NotifyChange; -import org.alfresco.filesys.smb.PacketType; -import org.alfresco.filesys.smb.server.NTTransPacket; -import org.alfresco.filesys.smb.server.SMBSrvPacket; -import org.alfresco.filesys.smb.server.SMBSrvSession; -import org.alfresco.filesys.util.DataPacker; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Notify Change Handler Class - */ -public class NotifyChangeHandler implements Runnable -{ - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Change notification request list and global filter mask - - private NotifyRequestList m_notifyList; - private int m_globalNotifyMask; - - // Associated disk device context - - private DiskDeviceContext m_diskCtx; - - // Change notification processing thread - - private Thread m_procThread; - - // Change events queue - - private NotifyChangeEventList m_eventList; - - // Debug output enable - - private boolean m_debug = false; - - // Shutdown request flag - - private boolean m_shutdown; - - /** - * Class constructor - * - * @param diskCtx DiskDeviceContext - */ - public NotifyChangeHandler(DiskDeviceContext diskCtx) - { - - // Save the associated disk context details - - m_diskCtx = diskCtx; - - // Allocate the events queue - - m_eventList = new NotifyChangeEventList(); - - // Create the processing thread - - m_procThread = new Thread(this); - - m_procThread.setDaemon(true); - m_procThread.setName("Notify_" + m_diskCtx.getDeviceName()); - - m_procThread.start(); - } - - /** - * Add a request to the change notification list - * - * @param req NotifyRequest - */ - public final void addNotifyRequest(NotifyRequest req) - { - - // Check if the request list has been allocated - - if (m_notifyList == null) - m_notifyList = new NotifyRequestList(); - - // Add the request to the list - - req.setDiskContext(m_diskCtx); - m_notifyList.addRequest(req); - - // Regenerate the global notify change filter mask - - m_globalNotifyMask = m_notifyList.getGlobalFilter(); - } - - /** - * Remove a request from the notify change request list - * - * @param req NotifyRequest - */ - public final void removeNotifyRequest(NotifyRequest req) - { - removeNotifyRequest(req, true); - } - - /** - * Remove a request from the notify change request list - * - * @param req NotifyRequest - * @param updateMask boolean - */ - public final void removeNotifyRequest(NotifyRequest req, boolean updateMask) - { - - // Check if the request list has been allocated - - if (m_notifyList == null) - return; - - // Remove the request from the list - - m_notifyList.removeRequest(req); - - // Regenerate the global notify change filter mask - - if (updateMask == true) - m_globalNotifyMask = m_notifyList.getGlobalFilter(); - } - - /** - * Remove all notification requests owned by the specified session - * - * @param sess SMBSrvSession - */ - public final void removeNotifyRequests(SMBSrvSession sess) - { - - // Remove all requests owned by the session - - m_notifyList.removeAllRequestsForSession(sess); - - // Recalculate the global notify change filter mask - - m_globalNotifyMask = m_notifyList.getGlobalFilter(); - } - - /** - * Determine if the filter has file name change notification, triggered if a file is created, - * renamed or deleted - * - * @return boolean - */ - public final boolean hasFileNameChange() - { - return hasFilterFlag(NotifyChange.FileName); - } - - /** - * Determine if the filter has directory name change notification, triggered if a directory is - * created or deleted. - * - * @return boolean - */ - public final boolean hasDirectoryNameChange() - { - return hasFilterFlag(NotifyChange.DirectoryName); - } - - /** - * Determine if the filter has attribute change notification - * - * @return boolean - */ - public final boolean hasAttributeChange() - { - return hasFilterFlag(NotifyChange.Attributes); - } - - /** - * Determine if the filter has file size change notification - * - * @return boolean - */ - public final boolean hasFileSizeChange() - { - return hasFilterFlag(NotifyChange.Size); - } - - /** - * Determine if the filter has last write time change notification - * - * @return boolean - */ - public final boolean hasFileWriteTimeChange() - { - return hasFilterFlag(NotifyChange.LastWrite); - } - - /** - * Determine if the filter has last access time change notification - * - * @return boolean - */ - public final boolean hasFileAccessTimeChange() - { - return hasFilterFlag(NotifyChange.LastAccess); - } - - /** - * Determine if the filter has creation time change notification - * - * @return boolean - */ - public final boolean hasFileCreateTimeChange() - { - return hasFilterFlag(NotifyChange.Creation); - } - - /** - * Determine if the filter has the security descriptor change notification - * - * @return boolean - */ - public final boolean hasSecurityDescriptorChange() - { - return hasFilterFlag(NotifyChange.Security); - } - - /** - * Check if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Return the global notify filter mask - * - * @return int - */ - public final int getGlobalNotifyMask() - { - return m_globalNotifyMask; - } - - /** - * Return the notify request queue size - * - * @return int - */ - public final int getRequestQueueSize() - { - return m_notifyList != null ? m_notifyList.numberOfRequests() : 0; - } - - /** - * Check if the change filter has the specified flag enabled - * - * @param flag - * @return boolean - */ - private final boolean hasFilterFlag(int flag) - { - return (m_globalNotifyMask & flag) != 0 ? true : false; - } - - /** - * File changed notification - * - * @param action int - * @param path String - */ - public final void notifyFileChanged(int action, String path) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasFileNameChange() == false) - return; - - // Queue the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.FileName, action, path, false)); - } - - /** - * File/directory renamed notification - * - * @param oldName String - * @param newName String - */ - public final void notifyRename(String oldName, String newName) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || (hasFileNameChange() == false && hasDirectoryNameChange() == false)) - return; - - // Queue the change notification event - - queueNotification(new NotifyChangeEvent(NotifyChange.FileName, NotifyChange.ActionRenamedNewName, oldName, - newName, false)); - } - - /** - * Directory changed notification - * - * @param action int - * @param path String - */ - public final void notifyDirectoryChanged(int action, String path) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasDirectoryNameChange() == false) - return; - - // Queue the change notification event - - queueNotification(new NotifyChangeEvent(NotifyChange.DirectoryName, action, path, true)); - } - - /** - * Attributes changed notification - * - * @param path String - * @param isdir boolean - */ - public final void notifyAttributesChanged(String path, boolean isdir) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasAttributeChange() == false) - return; - - // Queue the change notification event - - queueNotification(new NotifyChangeEvent(NotifyChange.Attributes, NotifyChange.ActionModified, path, isdir)); - } - - /** - * File size changed notification - * - * @param path String - */ - public final void notifyFileSizeChanged(String path) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasFileSizeChange() == false) - return; - - // Send the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.Size, NotifyChange.ActionModified, path, false)); - } - - /** - * Last write time changed notification - * - * @param path String - * @param isdir boolean - */ - public final void notifyLastWriteTimeChanged(String path, boolean isdir) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasFileWriteTimeChange() == false) - return; - - // Send the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.LastWrite, NotifyChange.ActionModified, path, isdir)); - } - - /** - * Last access time changed notification - * - * @param path String - * @param isdir boolean - */ - public final void notifyLastAccessTimeChanged(String path, boolean isdir) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasFileAccessTimeChange() == false) - return; - - // Send the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.LastAccess, NotifyChange.ActionModified, path, isdir)); - } - - /** - * Creation time changed notification - * - * @param path String - * @param isdir boolean - */ - public final void notifyCreationTimeChanged(String path, boolean isdir) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasFileCreateTimeChange() == false) - return; - - // Send the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.Creation, NotifyChange.ActionModified, path, isdir)); - } - - /** - * Security descriptor changed notification - * - * @param path String - * @param isdir boolean - */ - public final void notifySecurityDescriptorChanged(String path, boolean isdir) - { - - // Check if file change notifications are enabled - - if (getGlobalNotifyMask() == 0 || hasSecurityDescriptorChange() == false) - return; - - // Send the change notification - - queueNotification(new NotifyChangeEvent(NotifyChange.Security, NotifyChange.ActionModified, path, isdir)); - } - - /** - * Enable debug output - * - * @param ena boolean - */ - public final void setDebug(boolean ena) - { - m_debug = ena; - } - - /** - * Shutdown the change notification processing thread - */ - public final void shutdownRequest() - { - - // Check if the processing thread is valid - - if (m_procThread != null) - { - - // Set the shutdown flag - - m_shutdown = true; - - // Wakeup the processing thread - - synchronized (m_eventList) - { - m_eventList.notifyAll(); - } - } - } - - /** - * Send buffered change notifications for a session - * - * @param req NotifyRequest - * @param evtList NotifyChangeEventList - */ - public final void sendBufferedNotifications(NotifyRequest req, NotifyChangeEventList evtList) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Send buffered notifications, req=" + req + ", evtList=" - + (evtList != null ? "" + evtList.numberOfEvents() : "null")); - - // Initialize the notification request timeout - - long tmo = System.currentTimeMillis() + NotifyRequest.DefaultRequestTimeout; - - // Allocate the NT transaction packet to send the asynchronous notification - - NTTransPacket ntpkt = new NTTransPacket(); - - // Build the change notification response SMB - - ntpkt.setParameterCount(18); - ntpkt.resetBytePointerAlign(); - - int pos = ntpkt.getPosition(); - ntpkt.setNTParameter(1, 0); // total data count - ntpkt.setNTParameter(3, pos - 4); // offset to parameter block - - // Check if the notify enum status is set - - if (req.hasNotifyEnum()) - { - - // Set the parameter block length - - ntpkt.setNTParameter(0, 0); // total parameter block count - ntpkt.setNTParameter(2, 0); // parameter block count for this packet - ntpkt.setNTParameter(6, pos - 4); // data block offset - ntpkt.setByteCount(); - - ntpkt.setCommand(PacketType.NTTransact); - - ntpkt.setFlags(SMBSrvPacket.FLG_CANONICAL + SMBSrvPacket.FLG_CASELESS); - ntpkt.setFlags2(SMBSrvPacket.FLG2_UNICODE + SMBSrvPacket.FLG2_LONGERRORCODE); - - // Set the notification request id to indicate that it has completed - - req.setCompleted(true, tmo); - req.setNotifyEnum(false); - - // Set the response for the current notify request - - ntpkt.setMultiplexId(req.getMultiplexId()); - ntpkt.setTreeId(req.getTreeId()); - ntpkt.setUserId(req.getUserId()); - ntpkt.setProcessId(req.getProcessId()); - - try - { - - // Send the response to the current session - - if (req.getSession().sendAsynchResponseSMB(ntpkt, ntpkt.getLength()) == false) - { - - // Asynchronous request was queued, clone the request packet - - ntpkt = new NTTransPacket(ntpkt); - } - } - catch (Exception ex) - { - } - } - else if (evtList != null) - { - - // Pack the change notification events - - for (int i = 0; i < evtList.numberOfEvents(); i++) - { - - // Get the current event from the list - - NotifyChangeEvent evt = evtList.getEventAt(i); - - // Get the relative file name for the event - - String relName = FileName.makeRelativePath(req.getWatchPath(), evt.getFileName()); - if (relName == null) - relName = evt.getShortFileName(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" Notify evtPath=" + evt.getFileName() + ", reqPath=" + req.getWatchPath() - + ", relative=" + relName); - - // Pack the notification structure - - ntpkt.packInt(0); // offset to next structure - ntpkt.packInt(evt.getAction()); // action - ntpkt.packInt(relName.length() * 2); // file name length - ntpkt.packString(relName, true, false); - - // Check if the event is a file/directory rename, if so then add the old - // file/directory details - - if (evt.getAction() == NotifyChange.ActionRenamedNewName && evt.hasOldFileName()) - { - - // Set the offset from the first structure to this structure - - int newPos = DataPacker.longwordAlign(ntpkt.getPosition()); - DataPacker.putIntelInt(newPos - pos, ntpkt.getBuffer(), pos); - - // Get the old file name - - relName = FileName.makeRelativePath(req.getWatchPath(), evt.getOldFileName()); - if (relName == null) - relName = evt.getOldFileName(); - - // Add the old file/directory name details - - ntpkt.packInt(0); // offset to next structure - ntpkt.packInt(NotifyChange.ActionRenamedOldName); - ntpkt.packInt(relName.length() * 2); // file name length - ntpkt.packString(relName, true, false); - } - - // Calculate the parameter block length, longword align the buffer position - - int prmLen = ntpkt.getPosition() - pos; - ntpkt.alignBytePointer(); - pos = (pos + 3) & 0xFFFFFFFC; - - // Set the parameter block length - - ntpkt.setNTParameter(0, prmLen); // total parameter block count - ntpkt.setNTParameter(2, prmLen); // parameter block count for this packet - ntpkt.setNTParameter(6, ntpkt.getPosition() - 4); - // data block offset - ntpkt.setByteCount(); - - ntpkt.setCommand(PacketType.NTTransact); - - ntpkt.setFlags(SMBSrvPacket.FLG_CANONICAL + SMBSrvPacket.FLG_CASELESS); - ntpkt.setFlags2(SMBSrvPacket.FLG2_UNICODE + SMBSrvPacket.FLG2_LONGERRORCODE); - - // Set the notification request id to indicate that it has completed - - req.setCompleted(true, tmo); - - // Set the response for the current notify request - - ntpkt.setMultiplexId(req.getMultiplexId()); - ntpkt.setTreeId(req.getTreeId()); - ntpkt.setUserId(req.getUserId()); - ntpkt.setProcessId(req.getProcessId()); - - try - { - - // Send the response to the current session - - if (req.getSession().sendAsynchResponseSMB(ntpkt, ntpkt.getLength()) == false) - { - - // Asynchronous request was queued, clone the request packet - - ntpkt = new NTTransPacket(ntpkt); - } - } - catch (Exception ex) - { - } - } - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("sendBufferedNotifications() done"); - } - - /** - * Queue a change notification event for processing - * - * @param evt NotifyChangeEvent - */ - protected final void queueNotification(NotifyChangeEvent evt) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Queue notification event=" + evt.toString()); - - // Queue the notification event to the main notification handler thread - - synchronized (m_eventList) - { - - // Add the event to the list - - m_eventList.addEvent(evt); - - // Notify the processing thread that there are events to process - - m_eventList.notifyAll(); - } - } - - /** - * Send change notifications to sessions with notification enabled that match the change event. - * - * @param evt NotifyChangeEvent - * @return int - */ - protected final int sendChangeNotification(NotifyChangeEvent evt) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("sendChangeNotification event=" + evt); - - // Get a list of notification requests that match the type/path - - Vector reqList = findMatchingRequests(evt.getFilter(), evt.getFileName(), evt.isDirectory()); - if (reqList == null || reqList.size() == 0) - return 0; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" Found " + reqList.size() + " matching change listeners"); - - // Initialize the notification request timeout - - long tmo = System.currentTimeMillis() + NotifyRequest.DefaultRequestTimeout; - - // Allocate the NT transaction packet to send the asynchronous notification - - NTTransPacket ntpkt = new NTTransPacket(); - - // Send the notify response to each client in the list - - for (int i = 0; i < reqList.size(); i++) - { - - // Get the current request - - NotifyRequest req = reqList.get(i); - - // Build the change notification response SMB - - ntpkt.setParameterCount(18); - ntpkt.resetBytePointerAlign(); - - int pos = ntpkt.getPosition(); - ntpkt.setNTParameter(1, 0); // total data count - ntpkt.setNTParameter(3, pos - 4); // offset to parameter block - - // Get the relative file name for the event - - String relName = FileName.makeRelativePath(req.getWatchPath(), evt.getFileName()); - if (relName == null) - relName = evt.getShortFileName(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" Notify evtPath=" + evt.getFileName() + ", reqPath=" + req.getWatchPath() - + ", relative=" + relName); - - // Pack the notification structure - - ntpkt.packInt(0); // offset to next structure - ntpkt.packInt(evt.getAction()); // action - ntpkt.packInt(relName.length() * 2); // file name length - ntpkt.packString(relName, true, false); - - // Check if the event is a file/directory rename, if so then add the old file/directory - // details - - if (evt.getAction() == NotifyChange.ActionRenamedNewName && evt.hasOldFileName()) - { - - // Set the offset from the first structure to this structure - - int newPos = DataPacker.longwordAlign(ntpkt.getPosition()); - DataPacker.putIntelInt(newPos - pos, ntpkt.getBuffer(), pos); - - // Get the old file name - - relName = FileName.makeRelativePath(req.getWatchPath(), evt.getOldFileName()); - if (relName == null) - relName = evt.getOldFileName(); - - // Add the old file/directory name details - - ntpkt.packInt(0); // offset to next structure - ntpkt.packInt(NotifyChange.ActionRenamedOldName); - ntpkt.packInt(relName.length() * 2); // file name length - ntpkt.packString(relName, true, false); - } - - // Calculate the parameter block length, longword align the buffer position - - int prmLen = ntpkt.getPosition() - pos; - ntpkt.alignBytePointer(); - pos = (pos + 3) & 0xFFFFFFFC; - - // Set the parameter block length - - ntpkt.setNTParameter(0, prmLen); // total parameter block count - ntpkt.setNTParameter(2, prmLen); // parameter block count for this packet - ntpkt.setNTParameter(6, ntpkt.getPosition() - 4); - // data block offset - ntpkt.setByteCount(); - - ntpkt.setCommand(PacketType.NTTransact); - - ntpkt.setFlags(SMBSrvPacket.FLG_CANONICAL + SMBSrvPacket.FLG_CASELESS); - ntpkt.setFlags2(SMBSrvPacket.FLG2_UNICODE + SMBSrvPacket.FLG2_LONGERRORCODE); - - // Check if the request is already complete - - if (req.isCompleted() == false) - { - - // Set the notification request id to indicate that it has completed - - req.setCompleted(true, tmo); - - // Set the response for the current notify request - - ntpkt.setMultiplexId(req.getMultiplexId()); - ntpkt.setTreeId(req.getTreeId()); - ntpkt.setUserId(req.getUserId()); - ntpkt.setProcessId(req.getProcessId()); - - // DEBUG - - // ntpkt.DumpPacket(); - - try - { - - // Send the response to the current session - - if (req.getSession().sendAsynchResponseSMB(ntpkt, ntpkt.getLength()) == false) - { - - // Asynchronous request was queued, clone the request packet - - ntpkt = new NTTransPacket(ntpkt); - } - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - else - { - - // Buffer the event so it can be sent when the client resets the notify request - - req.addEvent(evt); - - // DEBUG - - if (logger.isDebugEnabled() && req.getSession().hasDebug(SMBSrvSession.DBG_NOTIFY)) - logger.debug("Buffered notify req=" + req + ", event=" + evt + ", sess=" - + req.getSession().getSessionId()); - } - - // Reset the notification pending flag for the session - - req.getSession().setNotifyPending(false); - - // DEBUG - - if (logger.isDebugEnabled() && req.getSession().hasDebug(SMBSrvSession.DBG_NOTIFY)) - logger - .debug("Asynch notify req=" + req + ", event=" + evt + ", sess=" - + req.getSession().getUniqueId()); - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("sendChangeNotification() done"); - - // Return the count of matching requests - - return reqList.size(); - } - - /** - * Find notify requests that match the type and path - * - * @param typ int - * @param path String - * @param isdir boolean - * @return Vector - */ - protected final synchronized Vector findMatchingRequests(int typ, String path, boolean isdir) - { - - // Create a vector to hold the matching requests - - Vector reqList = new Vector(); - - // Normalise the path string - - String matchPath = path.toUpperCase(); - - // Search for matching requests and remove them from the main request list - - int idx = 0; - long curTime = System.currentTimeMillis(); - - boolean removedReq = false; - - while (idx < m_notifyList.numberOfRequests()) - { - - // Get the current request - - NotifyRequest curReq = m_notifyList.getRequest(idx); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("findMatchingRequests() req=" + curReq.toString()); - - // Check if the request has expired - - if (curReq.hasExpired(curTime)) - { - - // Remove the request from the list - - m_notifyList.removeRequestAt(idx); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - { - logger.debug("Removed expired request req=" + curReq.toString()); - if (curReq.getBufferedEventList() != null) - { - NotifyChangeEventList bufList = curReq.getBufferedEventList(); - logger.debug(" Buffered events = " + bufList.numberOfEvents()); - for (int b = 0; b < bufList.numberOfEvents(); b++) - logger.debug(" " + (b + 1) + ": " + bufList.getEventAt(b)); - } - } - - // Indicate that q request has been removed from the queue, the global filter mask - // will need - // to be recalculated - - removedReq = true; - - // Restart the loop - - continue; - } - - // Check if the request matches the filter - - if (curReq.hasFilter(typ)) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" hasFilter typ=" + typ + ", watchTree=" + curReq.hasWatchTree() + ", watchPath=" - + curReq.getWatchPath() + ", matchPath=" + matchPath + ", isDir=" + isdir); - - // Check if the path matches or is a subdirectory and the whole tree is being - // watched - - boolean wantReq = false; - - if (matchPath.length() == 0 && curReq.hasWatchTree()) - wantReq = true; - else if (curReq.hasWatchTree() == true && matchPath.startsWith(curReq.getWatchPath()) == true) - wantReq = true; - else if (isdir == true && matchPath.compareTo(curReq.getWatchPath()) == 0) - wantReq = true; - else if (isdir == false) - { - - // Strip the file name from the path and compare - - String[] paths = FileName.splitPath(matchPath); - - if (paths != null && paths[0] != null) - { - - // Check if the directory part of the path is the directory being watched - - if (curReq.getWatchPath().equalsIgnoreCase(paths[0])) - wantReq = true; - } - } - - // Check if the request is required - - if (wantReq == true) - { - - // For all notify requests in the matching list we set the 'notify pending' - // state on the associated SMB - // session so that any socket writes on those sessions are synchronized until - // the change notification - // response has been sent. - - curReq.getSession().setNotifyPending(true); - - // Add the request to the matching list - - reqList.add(curReq); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug(" Added request to matching list"); - } - } - - // Move to the next request in the list - - idx++; - } - - // If requests were removed from the queue the global filter mask must be recalculated - - if (removedReq == true) - m_globalNotifyMask = m_notifyList.getGlobalFilter(); - - // Return the matching request list - - return reqList; - } - - /** - * Asynchronous change notification processing thread - */ - public void run() - { - - // Loop until shutdown - - while (m_shutdown == false) - { - - // Wait for some events to process - - synchronized (m_eventList) - { - try - { - m_eventList.wait(); - } - catch (InterruptedException ex) - { - } - } - - // Check if the shutdown flag has been set - - if (m_shutdown == true) - break; - - // Loop until all pending events have been processed - - while (m_eventList.numberOfEvents() > 0) - { - - // Remove the event at the head of the queue - - NotifyChangeEvent evt = null; - - synchronized (m_eventList) - { - evt = m_eventList.removeEventAt(0); - } - - // Check if the event is valid - - if (evt == null) - break; - - try - { - - // Send out change notifications to clients that match the filter/path - - int cnt = sendChangeNotification(evt); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Change notify event=" + evt.toString() + ", clients=" + cnt); - } - catch (Throwable ex) - { - logger.error("NotifyChangeHandler thread", ex); - } - } - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("NotifyChangeHandler thread exit"); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequest.java b/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequest.java deleted file mode 100644 index d6ba47ed74..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequest.java +++ /dev/null @@ -1,603 +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.smb.server.notify; - -import java.util.Date; - -import org.alfresco.filesys.server.filesys.DiskDeviceContext; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.NotifyChange; -import org.alfresco.filesys.smb.server.SMBSrvSession; - -/** - * Notify Change Request Details Class - */ -public class NotifyRequest -{ - - // Constants - - public final static long DefaultRequestTimeout = 10000L; // 10 seconds - - // Notify change filter - - private int m_filter; - - // Flag to indicate if sub-directories of the directory being watched will also trigger - // notifications - - private boolean m_watchTree; - - // Session that posted the notify change request - - private SMBSrvSession m_sess; - - // Directory being watched - - private NetworkFile m_watchDir; - - // Root relative path, normalised to uppercase - - private String m_watchPath; - - // Unique client request id. - // - // If the multiplex id equals -1 the request has completed and we are waiting for the request to - // be reset with a - // new multiplex id. - - private int m_mid; - private int m_tid; - private int m_pid; - private int m_uid; - - // Notifications to buffer whilst waiting for request to be reset - - private int m_maxQueueLen; - - // Disk device context that the request is associated with - - private DiskDeviceContext m_diskCtx; - - // Buffered event list - - private NotifyChangeEventList m_bufferedEvents; - - // Notify request completed flag - - private boolean m_completed; - private long m_expiresAt; - - // Flag to indicate that many file changes have occurred and a notify enum status should be - // returned - // to the client - - private boolean m_notifyEnum; - - /** - * Class constructor - * - * @param filter int - * @param watchTree boolean - * @param sess SMBSrvSession - * @param dir NetworkFile - * @param mid int - * @param tid int - * @param pid int - * @param uid int - * @param qlen int - */ - public NotifyRequest(int filter, boolean watchTree, SMBSrvSession sess, NetworkFile dir, int mid, int tid, int pid, - int uid, int qlen) - { - m_filter = filter; - m_watchTree = watchTree; - m_sess = sess; - m_watchDir = dir; - - m_mid = mid; - m_tid = tid; - m_pid = pid; - m_uid = uid; - - m_maxQueueLen = qlen; - - // Set the normalised watch path - - m_watchPath = m_watchDir.getFullName().toUpperCase(); - if (m_watchPath.length() == 0) - m_watchPath = "\\"; - else if (m_watchPath.indexOf('/') != -1) - m_watchPath.replace('/', '\\'); - } - - /** - * Get the notify change filter - * - * @return int - */ - public final int getFilter() - { - return m_filter; - } - - /** - * Determine if the request has completed - * - * @return boolean - */ - public final boolean isCompleted() - { - return m_completed; - } - - /** - * Determine if the request has expired - * - * @param curTime long - * @return boolean - */ - public final boolean hasExpired(long curTime) - { - if (isCompleted() == false) - return false; - else if (m_expiresAt < curTime) - return true; - return false; - } - - /** - * Determine if the filter has file name change notification, triggered if a file is created, - * renamed or deleted - * - * @return boolean - */ - public final boolean hasFileNameChange() - { - return hasFilter(NotifyChange.FileName); - } - - /** - * Determine if the filter has directory name change notification, triggered if a directory is - * created or deleted. - * - * @return boolean - */ - public final boolean hasDirectoryNameChange() - { - return hasFilter(NotifyChange.DirectoryName); - } - - /** - * Determine if the filter has attribute change notification - * - * @return boolean - */ - public final boolean hasAttributeChange() - { - return hasFilter(NotifyChange.Attributes); - } - - /** - * Determine if the filter has file size change notification - * - * @return boolean - */ - public final boolean hasFileSizeChange() - { - return hasFilter(NotifyChange.Size); - } - - /** - * Determine if the filter has last write time change notification - * - * @return boolean - */ - public final boolean hasFileWriteTimeChange() - { - return hasFilter(NotifyChange.LastWrite); - } - - /** - * Determine if the filter has last access time change notification - * - * @return boolean - */ - public final boolean hasFileAccessTimeChange() - { - return hasFilter(NotifyChange.LastAccess); - } - - /** - * Determine if the filter has creation time change notification - * - * @return boolean - */ - public final boolean hasFileCreateTimeChange() - { - return hasFilter(NotifyChange.Creation); - } - - /** - * Determine if the filter has the security descriptor change notification - * - * @return boolean - */ - public final boolean hasSecurityDescriptorChange() - { - return hasFilter(NotifyChange.Security); - } - - /** - * Check if the change filter has the specified flag enabled - * - * @param flag - * @return boolean - */ - public final boolean hasFilter(int flag) - { - return (m_filter & flag) != 0 ? true : false; - } - - /** - * Check if the notify enum flag is set - * - * @return boolean - */ - public final boolean hasNotifyEnum() - { - return m_notifyEnum; - } - - /** - * Determine if sub-directories of the directory being watched should also trigger notifications - * - * @return boolean - */ - public final boolean hasWatchTree() - { - return m_watchTree; - } - - /** - * Get the session that posted the notify request - * - * @return SMBSrvSession - */ - public final SMBSrvSession getSession() - { - return m_sess; - } - - /** - * Get the directory being watched - * - * @return NetworkFile - */ - public final NetworkFile getDirectory() - { - return m_watchDir; - } - - /** - * Get the normalised watch path - * - * @return String - */ - public final String getWatchPath() - { - return m_watchPath; - } - - /** - * Get the multiplex-id of the request - * - * @return int - */ - public final int getMultiplexId() - { - return m_mid; - } - - /** - * Get the tree id of the request - * - * @return int - */ - public final int getTreeId() - { - return m_tid; - } - - /** - * Get the process id of the request - * - * @return int - */ - public final int getProcessId() - { - return m_pid; - } - - /** - * Get the user id of the request - * - * @return int - */ - public final int getUserId() - { - return m_uid; - } - - /** - * Return the expiry time that a completed request must be reset by before being removed from - * the queue. - * - * @return long - */ - public final long getExpiryTime() - { - return m_expiresAt; - } - - /** - * Get the associated disk context - * - * @return DiskDeviceContext - */ - public final DiskDeviceContext getDiskContext() - { - return m_diskCtx; - } - - /** - * Return the maximum number of notifications to buffer whilst waiting for the request to be - * reset - * - * @return int - */ - public final int getMaximumQueueLength() - { - return m_maxQueueLen; - } - - /** - * Determine if there are buffered events - * - * @return boolean - */ - public final boolean hasBufferedEvents() - { - if (m_bufferedEvents != null && m_bufferedEvents.numberOfEvents() > 0) - return true; - return false; - } - - /** - * Return the buffered notification event list - * - * @return NotifyChangeEventList - */ - public final NotifyChangeEventList getBufferedEventList() - { - return m_bufferedEvents; - } - - /** - * Add a buffered notification event, to be sent when the notify request is reset by the client - * - * @param evt NotifyChangeEvent - */ - public final void addEvent(NotifyChangeEvent evt) - { - - // Check if the notify enum flag is set, if so then do not buffer any events - - if (hasNotifyEnum()) - return; - - // Check if the buffered event list has been allocated - - if (m_bufferedEvents == null) - m_bufferedEvents = new NotifyChangeEventList(); - - // Add the event if the list has not reached the maximum buffered event count - - if (m_bufferedEvents.numberOfEvents() < getMaximumQueueLength()) - { - - // Buffer the event until the client resets the notify filter - - m_bufferedEvents.addEvent(evt); - } - else - { - - // Remove all buffered events and set the notify enum flag to indicate that there - // have been many file changes - - removeAllEvents(); - setNotifyEnum(true); - } - } - - /** - * Remove all buffered events from the request - */ - public final void removeAllEvents() - { - if (m_bufferedEvents != null) - { - m_bufferedEvents.removeAllEvents(); - m_bufferedEvents = null; - } - } - - /** - * Clear the buffered event list, do not destroy the list - */ - public final void clearBufferedEvents() - { - m_bufferedEvents = null; - } - - /** - * Set/clear the notify enum flag that indicates if there have been many file changes - * - * @param ena boolean - */ - public final void setNotifyEnum(boolean ena) - { - m_notifyEnum = ena; - } - - /** - * Set the associated disk device context - * - * @param ctx DiskDeviceContext - */ - protected final void setDiskContext(DiskDeviceContext ctx) - { - m_diskCtx = ctx; - } - - /** - * Set the multiplex id for the notification - * - * @param mid int - */ - public final void setMultiplexId(int mid) - { - m_mid = mid; - } - - /** - * Set the request completed flag - * - * @param comp boolean - */ - public final void setCompleted(boolean comp) - { - m_completed = comp; - - if (comp) - m_expiresAt = System.currentTimeMillis() + DefaultRequestTimeout; - } - - /** - * Set the request completed flag and set an expiry time when the request expires - * - * @param comp boolean - * @param expire long - */ - public final void setCompleted(boolean comp, long expires) - { - m_completed = comp; - m_expiresAt = expires; - } - - /** - * Return the notify request as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - - str.append(getSession().getUniqueId()); - str.append(":"); - - if (getWatchPath().length() == 0) - str.append("Root"); - else - str.append(getWatchPath()); - str.append(":"); - - if (hasFileNameChange()) - str.append("File,"); - - if (hasDirectoryNameChange()) - str.append("Dir,"); - - if (hasAttributeChange()) - str.append("Attr,"); - - if (hasFileSizeChange()) - str.append("Size,"); - - if (hasFileWriteTimeChange()) - str.append("Write,"); - - if (hasFileAccessTimeChange()) - str.append("Access,"); - - if (hasFileCreateTimeChange()) - str.append("Create,"); - - if (hasSecurityDescriptorChange()) - str.append("Security,"); - - if (hasWatchTree()) - str.append("Tree"); - else - str.append("NoTree"); - - str.append(" MID="); - str.append(getMultiplexId()); - - str.append(" PID="); - str.append(getProcessId()); - - str.append(" TID="); - str.append(getTreeId()); - - str.append(" UID="); - str.append(getUserId()); - - if (isCompleted()) - { - str.append(",Completed,TMO="); - str.append(new Date(getExpiryTime()).toString()); - } - - str.append(",Queue="); - str.append(getMaximumQueueLength()); - if (hasBufferedEvents()) - { - str.append("/"); - str.append(getBufferedEventList().numberOfEvents()); - } - - if (hasNotifyEnum()) - str.append(",ENUM"); - - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequestList.java b/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequestList.java deleted file mode 100644 index 3be10e9337..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/notify/NotifyRequestList.java +++ /dev/null @@ -1,305 +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.smb.server.notify; - -import java.util.Vector; - -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.smb.server.SMBSrvSession; - -/** - * Notify Change Request List Class - */ -public class NotifyRequestList -{ - - // List of notify change requests - - private Vector m_requests; - - /** - * Default constructor - */ - public NotifyRequestList() - { - m_requests = new Vector(); - } - - /** - * Return the specified request - * - * @param idx int - * @return NotifyRequest - */ - public final synchronized NotifyRequest getRequest(int idx) - { - - // Range check the index - - if (idx >= m_requests.size()) - return null; - - // Return the notify request - - return (NotifyRequest) m_requests.elementAt(idx); - } - - /** - * Return the global filter mask, generated by combining all of the pending notify request - * filters - * - * @return int - */ - public final synchronized int getGlobalFilter() - { - - // Loop through all the requests - - int filter = 0; - - if (m_requests.size() > 0) - { - - // Build the global filter mask from all pending requests - - for (int i = 0; i < m_requests.size(); i++) - { - NotifyRequest req = m_requests.get(i); - filter |= req.getFilter(); - } - } - - // Return the filter mask - - return filter; - } - - /** - * Add a request to the list - * - * @param req NotifyRequest - */ - public final synchronized void addRequest(NotifyRequest req) - { - m_requests.addElement(req); - } - - /** - * Find the notify request for the matching ids - * - * @param mid int - * @param tid int - * @param uid int - * @param pid int - * @return NotifyRequest - */ - public final synchronized NotifyRequest findRequest(int mid, int tid, int uid, int pid) - { - - // Search for the required request, and remove it from the list - - for (int i = 0; i < m_requests.size(); i++) - { - - // Get the current request - - NotifyRequest curReq = (NotifyRequest) m_requests.elementAt(i); - if (curReq.getMultiplexId() == mid && curReq.getTreeId() == tid && curReq.getUserId() == uid - && curReq.getProcessId() == pid) - { - - // Return the request - - return curReq; - } - } - - // Request not found in the list - - return null; - } - - /** - * Find the notify request for the specified directory and filter - * - * @param dir NetworkFile - * @param filter int - * @param watchTree boolean - */ - public final synchronized NotifyRequest findRequest(NetworkFile dir, int filter, boolean watchTree) - { - - // Search for the required request - - for (int i = 0; i < m_requests.size(); i++) - { - - // Get the current request - - NotifyRequest curReq = (NotifyRequest) m_requests.elementAt(i); - if (curReq.getDirectory() == dir && curReq.getFilter() == filter && curReq.hasWatchTree() == watchTree) - { - - // Return the request - - return curReq; - } - } - - // Request not found in the list - - return null; - } - - /** - * Remove a request from the list - * - * @param req NotifyRequest - */ - public final synchronized NotifyRequest removeRequest(NotifyRequest req) - { - - // Search for the required request, and remove it from the list - - for (int i = 0; i < m_requests.size(); i++) - { - - // Get the current request - - NotifyRequest curReq = (NotifyRequest) m_requests.elementAt(i); - if (curReq == req) - { - - // Remove the request from the list - - m_requests.removeElementAt(i); - return curReq; - } - } - - // Request not found in the list - - return null; - } - - /** - * Remove a request from the list - * - * @param idx int - */ - public final synchronized NotifyRequest removeRequestAt(int idx) - { - - // Check if the request index is valid - - if (idx < 0 || idx >= m_requests.size()) - return null; - - // Remove the specified request - - NotifyRequest req = (NotifyRequest) m_requests.elementAt(idx); - m_requests.removeElementAt(idx); - return req; - } - - /** - * Remove all requests for the specified session - * - * @param sess SMBSrvSession - */ - public final synchronized void removeAllRequestsForSession(SMBSrvSession sess) - { - - // Search for the required requests, and remove from the list - - int idx = 0; - - while (idx < m_requests.size()) - { - - // Get the current request - - NotifyRequest curReq = (NotifyRequest) m_requests.elementAt(idx); - if (curReq.getSession() == sess) - { - - // Remove the request from the list - - m_requests.removeElementAt(idx); - } - else - idx++; - } - } - - /** - * Remove all requests for the specified session and tree connection - * - * @param sess SMBSrvSession - * @param tid int - */ - public final synchronized void removeAllRequestsForSession(SMBSrvSession sess, int tid) - { - - // Search for the required requests, and remove from the list - - int idx = 0; - - while (idx < m_requests.size()) - { - - // Get the current request - - NotifyRequest curReq = (NotifyRequest) m_requests.elementAt(idx); - if (curReq.getSession() == sess && curReq.getTreeId() == tid) - { - - // Remove the request from the list - - m_requests.removeElementAt(idx); - } - else - idx++; - } - } - - /** - * Remove all requests from the list - */ - public final synchronized void clearRequestList() - { - m_requests.removeAllElements(); - } - - /** - * Return the request list size - * - * @return int - */ - public final synchronized int numberOfRequests() - { - return m_requests.size(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/ntfs/NTFSStreamsInterface.java b/source/java/org/alfresco/filesys/smb/server/ntfs/NTFSStreamsInterface.java deleted file mode 100644 index e91e4a82d4..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/ntfs/NTFSStreamsInterface.java +++ /dev/null @@ -1,84 +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.smb.server.ntfs; - -import java.io.IOException; - -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.TreeConnection; - -/** - * NTFS Streams Interface - *

- * Optional interface that a DiskInterface driver can implement to provide file streams support. - */ -public interface NTFSStreamsInterface -{ - - /** - * Determine if NTFS streams are enabled - * - * @param sess SrvSession - * @param tree TreeConnection - * @return boolean - */ - public boolean hasStreamsEnabled(SrvSession sess, TreeConnection tree); - - /** - * Return stream information for the specified stream - * - * @param sess SrvSession - * @param tree TreeConnection - * @param streamInfo StreamInfo - * @return StreamInfo - * @exception IOException I/O error occurred - */ - public StreamInfo getStreamInformation(SrvSession sess, TreeConnection tree, StreamInfo streamInfo) - throws IOException; - - /** - * Return a list of the streams for the specified file - * - * @param sess SrvSession - * @param tree TreeConnection - * @param fileName String - * @return StreamInfoList - * @exception IOException I/O error occurred - */ - public StreamInfoList getStreamList(SrvSession sess, TreeConnection tree, String fileName) throws IOException; - - /** - * Rename a stream - * - * @param sess SrvSession - * @param tree TreeConnection - * @param oldName String - * @param newName String - * @param overWrite boolean - * @exception IOException - */ - public void renameStream(SrvSession sess, TreeConnection tree, String oldName, String newName, boolean overWrite) - throws IOException; -} diff --git a/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfo.java b/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfo.java deleted file mode 100644 index aa137901cb..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfo.java +++ /dev/null @@ -1,423 +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.smb.server.ntfs; - -/** - * File Stream Information Class - *

- * Contains the details of a file stream. - */ -public class StreamInfo -{ - - // Constants - - public static final String StreamSeparator = ":"; - - // Set stream information flags - - public static final int SetStreamSize = 0x0001; - public static final int SetAllocationSize = 0x0002; - public static final int SetModifyDate = 0x0004; - public static final int SetCreationDate = 0x0008; - public static final int SetAccessDate = 0x0010; - - // File path and stream name - - private String m_path; - private String m_name; - - // Parent file id and stream id - - private int m_fid; - private int m_stid; - - // Stream size/allocation size - - private long m_size; - private long m_allocSize; - - // Stream creation, modification and access date/times - - private long m_createDate; - private long m_modifyDate; - private long m_accessDate; - - // Set stream information setter flags - - private int m_setFlags; - - /** - * Default constructor - */ - public StreamInfo() - { - } - - /** - * Constructor - * - * @param path String - */ - public StreamInfo(String path) - { - - // Parse the path to split into path and stream components - - parsePath(path); - } - - /** - * Constructor - * - * @param name String - * @param fid int - * @param stid int - */ - public StreamInfo(String name, int fid, int stid) - { - m_name = name; - m_fid = fid; - m_stid = stid; - } - - /** - * Constructor - * - * @param name String - * @param fid int - * @param stid int - * @param size long - * @param alloc long - */ - public StreamInfo(String name, int fid, int stid, long size, long alloc) - { - m_name = name; - m_fid = fid; - m_stid = stid; - m_size = size; - m_allocSize = alloc; - } - - /** - * Return the file path - * - * @return String - */ - public final String getPath() - { - return m_path; - } - - /** - * Return the stream name - * - * @return String - */ - public final String getName() - { - return m_name; - } - - /** - * Return the stream file id - * - * @return int - */ - public final int getFileId() - { - return m_fid; - } - - /** - * Return the stream id - * - * @return int - */ - public final int getStreamId() - { - return m_stid; - } - - /** - * Return the streams last access date/time. - * - * @return long - */ - public long getAccessDateTime() - { - return m_accessDate; - } - - /** - * Return the stream creation date/time. - * - * @return long - */ - public long getCreationDateTime() - { - return m_createDate; - } - - /** - * Return the modification date/time - * - * @return long - */ - public final long getModifyDateTime() - { - return m_modifyDate; - } - - /** - * Return the stream size - * - * @return long - */ - public final long getSize() - { - return m_size; - } - - /** - * Return the stream allocation size - * - * @return long - */ - public final long getAllocationSize() - { - return m_allocSize; - } - - /** - * Determine if the last access date/time is available. - * - * @return boolean - */ - public boolean hasAccessDateTime() - { - return m_accessDate == 0L ? false : true; - } - - /** - * Determine if the creation date/time details are available. - * - * @return boolean - */ - public boolean hasCreationDateTime() - { - return m_createDate == 0L ? false : true; - } - - /** - * Determine if the modify date/time details are available. - * - * @return boolean - */ - public boolean hasModifyDateTime() - { - return m_modifyDate == 0L ? false : true; - } - - /** - * Determine if the specified set stream information flags is enabled - * - * @param setFlag int - * @return boolean - */ - public final boolean hasSetFlag(int flag) - { - if ((m_setFlags & flag) != 0) - return true; - return false; - } - - /** - * Return the set stream information flags - * - * @return int - */ - public final int getSetStreamInformationFlags() - { - return m_setFlags; - } - - /** - * Set the path, if it contains the stream name the path will be split into file name and stream - * name components. - * - * @param path String - */ - public final void setPath(String path) - { - parsePath(path); - } - - /** - * Set the stream name - * - * @param name String - */ - public final void setName(String name) - { - m_name = name; - } - - /** - * Set the streams last access date/time. - * - * @param timesec long - */ - public void setAccessDateTime(long timesec) - { - - // Create the access date/time - - m_accessDate = timesec; - } - - /** - * Set the creation date/time for the stream. - * - * @param timesec long - */ - public void setCreationDateTime(long timesec) - { - - // Set the creation date/time - - m_createDate = timesec; - } - - /** - * Set the modifucation date/time for the stream. - * - * @param timesec long - */ - public void setModifyDateTime(long timesec) - { - - // Set the date/time - - m_modifyDate = timesec; - } - - /** - * Set the file id - * - * @param id int - */ - public final void setFileId(int id) - { - m_fid = id; - } - - /** - * Set the stream id - * - * @param id int - */ - public final void setStreamId(int id) - { - m_stid = id; - } - - /** - * Set the stream size - * - * @param size long - */ - public final void setSize(long size) - { - m_size = size; - } - - /** - * Set the stream allocation size - * - * @param alloc long - */ - public final void setAllocationSize(long alloc) - { - m_allocSize = alloc; - } - - /** - * Set the set stream information flags to indicated which values are to be set - * - * @param setFlags int - */ - public final void setStreamInformationFlags(int setFlags) - { - m_setFlags = setFlags; - } - - /** - * Parse a path to split into file name and stream name components - * - * @param path String - */ - protected final void parsePath(String path) - { - - // Check if the file name contains a stream name - - int pos = path.indexOf(StreamSeparator); - if (pos == -1) - { - m_path = path; - return; - } - - // Split the main file name and stream name - - m_path = path.substring(0, pos); - m_name = path.substring(pos + 1); - } - - /** - * Return the stream information as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("["); - str.append(getName()); - str.append(","); - str.append(getFileId()); - str.append(":"); - str.append(getStreamId()); - str.append(","); - str.append(getSize()); - str.append("/"); - str.append(getAllocationSize()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfoList.java b/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfoList.java deleted file mode 100644 index 47f3daf882..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/ntfs/StreamInfoList.java +++ /dev/null @@ -1,176 +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.smb.server.ntfs; - -import java.util.Vector; - -/** - * Stream Information List Class - */ -public class StreamInfoList -{ - - // List of stream information objects - - private Vector m_list; - - /** - * Default constructor - */ - public StreamInfoList() - { - m_list = new Vector(); - } - - /** - * Add an item to the list - * - * @param info StreamInfo - */ - public final void addStream(StreamInfo info) - { - m_list.add(info); - } - - /** - * Return the stream details at the specified index - * - * @param idx int - * @return StreamInfo - */ - public final StreamInfo getStreamAt(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_list.size()) - return null; - - // Return the required stream information - - return m_list.get(idx); - } - - /** - * Find a stream by name - * - * @param name String - * @return StreamInfo - */ - public final StreamInfo findStream(String name) - { - - // Search for the required stream - - for (int i = 0; i < m_list.size(); i++) - { - - // Get the current stream information - - StreamInfo sinfo = m_list.get(i); - - // Check if the stream name matches - - if (sinfo.getName().equals(name)) - return sinfo; - } - - // Stream not found - - return null; - } - - /** - * Return the count of streams in the list - * - * @return int - */ - public final int numberOfStreams() - { - return m_list.size(); - } - - /** - * Remove the specified stream from the list - * - * @param idx int - * @return StreamInfo - */ - public final StreamInfo removeStream(int idx) - { - - // Range check the index - - if (idx < 0 || idx >= m_list.size()) - return null; - - // Remove the required stream - - return m_list.remove(idx); - } - - /** - * Remove the specified stream from the list - * - * @param name String - * @return StreamInfo - */ - public final StreamInfo removeStream(String name) - { - - // Search for the required stream - - for (int i = 0; i < m_list.size(); i++) - { - - // Get the current stream information - - StreamInfo sinfo = m_list.get(i); - - // Check if the stream name matches - - if (sinfo.getName().equals(name)) - { - - // Remove the stream from the list - - m_list.removeElementAt(i); - return sinfo; - } - } - - // Stream not found - - return null; - } - - /** - * Remove all streams from the list - */ - public final void removeAllStreams() - { - m_list.removeAllElements(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/win32/LanaListener.java b/source/java/org/alfresco/filesys/smb/server/win32/LanaListener.java deleted file mode 100644 index 6af3843fde..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/win32/LanaListener.java +++ /dev/null @@ -1,44 +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.smb.server.win32; - -/** - * LANA Listener Class - * - *

Receive status change events for a particular NetBIOS LANA. - * - * @author GKSpencer - */ -public interface LanaListener -{ - /** - * LANA status change callback - * - * @param lana int - * @param online boolean - */ - public void lanaStatusChange( int lana, boolean online); -} diff --git a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSLanaMonitor.java b/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSLanaMonitor.java deleted file mode 100644 index 0c2912802f..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSLanaMonitor.java +++ /dev/null @@ -1,418 +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.smb.server.win32; - -import java.util.BitSet; - -import org.alfresco.filesys.netbios.win32.NetBIOSSocket; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.smb.mailslot.Win32NetBIOSHostAnnouncer; -import org.alfresco.filesys.smb.server.SMBServer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Win32 NetBIOS LANA Monitor Class - *

- * Monitors the available NetBIOS LANAs to check for new network interfaces coming online. A session - * socket handler will be created for new LANAs as they appear. - */ -public class Win32NetBIOSLanaMonitor extends Thread -{ - // Constants - // - // Initial LANA listener array size - - private static final int LanaListenerArraySize = 256; - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Global LANA monitor - - private static Win32NetBIOSLanaMonitor _lanaMonitor; - - // Available LANA list and current status - - private BitSet m_lanas; - private BitSet m_lanaSts; - - // LANA status listeners - - private LanaListener[] m_listeners; - - // SMB/CIFS server to add new session handlers to - - private SMBServer m_server; - - // Wakeup interval - - private long m_wakeup; - - // Shutdown request flag - - private boolean m_shutdown; - - // Debug output enable - - private boolean m_debug; - - /** - * Class constructor - * - * @param server SMBServer - * @param lanas int[] - * @param wakeup long - * @param debug boolean - */ - Win32NetBIOSLanaMonitor(SMBServer server, int[] lanas, long wakeup, boolean debug) - { - - // Set the SMB server and wakeup interval - - m_server = server; - m_wakeup = wakeup; - - m_debug = debug; - - // Set the current LANAs in the available LANAs list - - m_lanas = new BitSet(); - m_lanaSts = new BitSet(); - - if (lanas != null) - { - - // Set the currently available LANAs - - for (int i = 0; i < lanas.length; i++) - m_lanas.set(lanas[i]); - } - - // Initialize the online LANA status list - - int[] curLanas = Win32NetBIOS.LanaEnumerate(); - - if ( curLanas != null) - { - for ( int i = 0; i < curLanas.length; i++) - m_lanaSts.set(curLanas[i], true); - } - - // Set the global LANA monitor, if not already set - - if (_lanaMonitor == null) - _lanaMonitor = this; - - // Start the LANA monitor thread - - setDaemon(true); - start(); - } - - /** - * Return the global LANA monitor - * - * @return Win32NetBIOSLanaMonitor - */ - public static Win32NetBIOSLanaMonitor getLanaMonitor() - { - return _lanaMonitor; - } - - /** - * Add a LANA listener - * - * @param lana int - * @param listener LanaListener - */ - public synchronized final void addLanaListener(int lana, LanaListener l) - { - // Range check the LANA id - - if ( lana < 0 || lana > 255) - return; - - // Check if the listener array has been allocated - - if ( m_listeners == null) - m_listeners = new LanaListener[LanaListenerArraySize]; - - // Add the LANA listener - - m_listeners[lana] = l; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS register listener for LANA " + lana); - } - - /** - * Remove a LANA listener - * - * @param lana int - */ - public synchronized final void removeLanaListener(int lana) - { - // Validate the LANA id - - if ( m_listeners == null || lana < 0 || lana >= m_listeners.length) - return; - - m_listeners[lana] = null; - } - - /** - * Thread method - */ - public void run() - { - // Clear the shutdown flag - - m_shutdown = false; - - // If Winsock NetBIOS is not enabled then initialize the sockets interface - - ServerConfiguration config = m_server.getConfiguration(); - - if ( config.useWinsockNetBIOS() == false) - { - try - { - NetBIOSSocket.initializeSockets(); - } - catch (WinsockNetBIOSException ex) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS initialization error", ex); - - // Shutdown the LANA monitor thread - - m_shutdown = true; - } - } - - // Loop until shutdown - - BitSet curLanas = new BitSet(); - - while (m_shutdown == false) - { - - // Wait for a network address change event - - Win32NetBIOS.waitForNetworkAddressChange(); - - // Check if the monitor has been closed - - if ( m_shutdown == true) - continue; - - // Clear the current active LANA bit set - - curLanas.clear(); - - // Get the available LANA list - - int[] lanas = Win32NetBIOS.LanaEnumerate(); - if (lanas != null) - { - - // Check if there are any new LANAs available - - Win32NetBIOSSessionSocketHandler sessHandler = null; - - for (int i = 0; i < lanas.length; i++) - { - - // Get the current LANA id, check if it's a known LANA - - int lana = lanas[i]; - curLanas.set(lana, true); - - if (m_lanas.get(lana) == false) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS found new LANA, " + lana); - - // Create a single Win32 NetBIOS session handler using the specified LANA - - sessHandler = new Win32NetBIOSSessionSocketHandler(m_server, lana, hasDebug()); - - try - { - sessHandler.initialize(); - } - catch (Exception ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS failed to create session handler for LANA " + lana, - ex); - - // Clear the session handler - - sessHandler = null; - } - - // If the session handler was initialized successfully add it to the - // SMB/CIFS server - - if (sessHandler != null) - { - - // Add the session handler to the SMB/CIFS server - - m_server.addSessionHandler(sessHandler); - - // Run the NetBIOS session handler in a seperate thread - - Thread nbThread = new Thread(sessHandler); - nbThread.setName("Win32NB_Handler_" + lana); - nbThread.start(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS created session handler on LANA " + lana); - - // Check if a host announcer should be enabled - - if (config.hasWin32EnableAnnouncer()) - { - - // Create a host announcer - - Win32NetBIOSHostAnnouncer hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, - config.getDomainName(), config.getWin32HostAnnounceInterval()); - - // Add the host announcer to the SMB/CIFS server list - - m_server.addHostAnnouncer(hostAnnouncer); - hostAnnouncer.start(); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS host announcer enabled on LANA " + lana); - } - - // Set the LANA in the available LANA list, and set the current status to online - - m_lanas.set(lana); - m_lanaSts.set(lana, true); - - // Add a listener for the new LANA - - addLanaListener( sessHandler.getLANANumber(), sessHandler); - } - } - else - { - // Check if the LANA has just come back online - - if ( m_lanaSts.get(lana) == false) - { - // Change the LANA status to indicate the LANA is back online - - m_lanaSts.set(lana, true); - - // Inform the listener that the LANA is back online - - if ( m_listeners != null && lana < m_listeners.length && - m_listeners[lana] != null) - m_listeners[lana].lanaStatusChange(lana, true); - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS LANA online - " + lana); - } - } - } - - // Check if there are any LANAs that have gone offline - - for ( int i = 0; i < m_lanaSts.length(); i++) - { - if ( curLanas.get(i) == false && m_lanaSts.get(i) == true) - { - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS LANA offline - " + i); - - // Change the LANA status - - m_lanaSts.set(i, false); - - // Check if there is an associated listener for the LANA - - if ( m_listeners != null && m_listeners[i] != null) - { - // Notify the LANA listener that the LANA is now offline - - m_listeners[i].lanaStatusChange(i, false); - } - } - } - } - } - } - - /** - * Determine if debug output is enabled - * - * @return boolean - */ - public final boolean hasDebug() - { - return m_debug; - } - - /** - * Request the LANA monitor thread to shutdown - */ - public final void shutdownRequest() - { - m_shutdown = true; - - // If Winsock NetBIOS is being used shutdown the Winsock interface - - if ( m_server.getConfiguration().useWinsockNetBIOS()) - NetBIOSSocket.shutdownSockets(); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSPacketHandler.java b/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSPacketHandler.java deleted file mode 100644 index 2d902e66fd..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSPacketHandler.java +++ /dev/null @@ -1,217 +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.smb.server.win32; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.netbios.win32.NetBIOS; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.smb.server.PacketHandler; -import org.alfresco.filesys.smb.server.SMBSrvPacket; - -/** - * Win32 NetBIOS Packet Handler Class - * - *

Uses the Win32 Netbios() call to provide the low level session layer for better integration with - * Windows. - * - * @author GKSpencer - */ -public class Win32NetBIOSPacketHandler extends PacketHandler -{ - - // Constants - // - // Receive error encoding and length masks - - private static final int ReceiveErrorMask = 0xFF000000; - private static final int ReceiveLengthMask = 0x0000FFFF; - - // Network LAN adapter to use - - private int m_lana; - - // NetBIOS session id - - private int m_lsn; - - /** - * Class constructor - * - * @param lana int - * @param lsn int - * @param callerName String - */ - public Win32NetBIOSPacketHandler(int lana, int lsn, String callerName) - { - super(SMBSrvPacket.PROTOCOL_WIN32NETBIOS, "Win32NB", "WNB", callerName); - - m_lana = lana; - m_lsn = lsn; - } - - /** - * Return the LANA number - * - * @return int - */ - public final int getLANA() - { - return m_lana; - } - - /** - * Return the NetBIOS session id - * - * @return int - */ - public final int getLSN() - { - return m_lsn; - } - - /** - * Read a packet from the client - * - * @param pkt SMBSrvPacket - * @return int - * @throws IOException - */ - public int readPacket(SMBSrvPacket pkt) throws IOException - { - - // Wait for a packet on the Win32 NetBIOS session - // - // As Windows is handling the NetBIOS session layer we only receive the SMB packet. In order - // to be compatible with the other packet handlers we allow for the 4 byte header. - - int pktLen = pkt.getBuffer().length; - if (pktLen > NetBIOS.MaxReceiveSize) - pktLen = NetBIOS.MaxReceiveSize; - - int rxLen = Win32NetBIOS.Receive(m_lana, m_lsn, pkt.getBuffer(), 4, pktLen - 4); - - if ((rxLen & ReceiveErrorMask) != 0) - { - - // Check for an incomplete message status code - - int sts = (rxLen & ReceiveErrorMask) >> 24; - - if (sts == NetBIOS.NRC_Incomp) - { - - // Check if the packet buffer is already at the maximum size (we assume the maximum - // size is the maximum that RFC NetBIOS can send which is 17bits) - - if (pkt.getBuffer().length < RFCNetBIOSProtocol.MaxPacketSize) - { - - // Allocate a new buffer - - byte[] newbuf = new byte[RFCNetBIOSProtocol.MaxPacketSize]; - - // Copy the first part of the received data to the new buffer - - System.arraycopy(pkt.getBuffer(), 4, newbuf, 4, pktLen - 4); - - // Move the new buffer in as the main packet buffer - - pkt.setBuffer(newbuf); - - // DEBUG - - // Debug.println("readPacket() extended buffer to " + pkt.getBuffer().length); - } - - // Set the original receive size - - rxLen = (rxLen & ReceiveLengthMask); - - // Receive the remaining data - // - // Note: If the second read request is issued with a size of 64K or 64K-4 it returns - // with another incomplete status and returns no data. - - int rxLen2 = Win32NetBIOS.Receive(m_lana, m_lsn, pkt.getBuffer(), rxLen + 4, 32768); - - if ((rxLen2 & ReceiveErrorMask) != 0) - { - sts = (rxLen2 & ReceiveErrorMask) >> 24; - throw new IOException("Win32 NetBIOS multi-part receive failed, sts=0x" + sts + ", err=" - + NetBIOS.getErrorString(sts)); - } - - // Set the total received data length - - rxLen += rxLen2; - } - else - { - - // Indicate that the session has closed - - return -1; - } - } - - // Return the received data length - - return rxLen; - } - - /** - * Write a packet to the client - * - * @param pkt SMBSrvPacket - * @param len int - * @throws IOException - */ - public void writePacket(SMBSrvPacket pkt, int len) throws IOException - { - - // Output the packet on the Win32 NetBIOS session - // - // As Windows is handling the NetBIOS session layer we do not send the 4 byte header that is - // used by the NetBIOS over TCP/IP and native SMB packet handlers. - - int sts = Win32NetBIOS.Send(m_lana, m_lsn, pkt.getBuffer(), 4, len); - - // Do not check the status, if the session has been closed the next receive will fail - } - - /** - * Close the Win32 NetBIOS packet handler. Hangup the NetBIOS session - */ - public void closeHandler() - { - super.closeHandler(); - - // Hangup the Win32 NetBIOS session - - Win32NetBIOS.Hangup(m_lana, m_lsn); - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSSessionSocketHandler.java b/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSSessionSocketHandler.java deleted file mode 100644 index 238c768d32..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/win32/Win32NetBIOSSessionSocketHandler.java +++ /dev/null @@ -1,1079 +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.smb.server.win32; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.filesys.netbios.NetBIOSName; -import org.alfresco.filesys.netbios.win32.NetBIOS; -import org.alfresco.filesys.netbios.win32.NetBIOSSocket; -import org.alfresco.filesys.netbios.win32.Win32NetBIOS; -import org.alfresco.filesys.netbios.win32.WinsockError; -import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; -import org.alfresco.filesys.server.config.ServerConfiguration; -import org.alfresco.filesys.smb.mailslot.HostAnnouncer; -import org.alfresco.filesys.smb.mailslot.Win32NetBIOSHostAnnouncer; -import org.alfresco.filesys.smb.mailslot.WinsockNetBIOSHostAnnouncer; -import org.alfresco.filesys.smb.server.PacketHandler; -import org.alfresco.filesys.smb.server.SMBServer; -import org.alfresco.filesys.smb.server.SMBSrvSession; -import org.alfresco.filesys.smb.server.SessionSocketHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Win32 NetBIOS Session Socket Handler Class - * - *

Uses the Win32 Netbios() call to provide the low level session layer for better integration with - * Windows. - * - * @author GKSpencer - */ -public class Win32NetBIOSSessionSocketHandler extends SessionSocketHandler implements LanaListener -{ - - // Debug logging - - private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol"); - - // Constants - // - - // Session Thread group - private static final ThreadGroup THREAD_GROUP_SESSION = new ThreadGroup("W32NETBIOS_SESSION_GROUP"); - - // Default LANA offline polling interval - - public static final long LANAPollingInterval = 5000; // 5 seconds - - // File server name - - private String m_srvName; - - // Accept connections from any clients or the named client only - - private byte[] m_acceptClient; - - // Local NetBIOS name to listen for sessions on and assigned name number - - private NetBIOSName m_nbName; - private int m_nameNum; - - // Workstation NetBIOS name and assigned name number - - private NetBIOSName m_wksNbName; - private int m_wksNameNum; - - // NetBIOS LAN adapter to use - - private int m_lana = -1; - - // Flag to indicate if the LANA is valid or the network adapter is currently - // unplugged/offline/disabled - - private boolean m_lanaValid; - - // Polling interval in milliseconds to check if the configured LANA is back online - - private long m_lanaPoll; - - // Flag to indicate if we are using Win32 Netbios() or Winsock calls - - private boolean m_useWinsock; - - // Winsock Netbios socket to listen for incoming connections - - private NetBIOSSocket m_nbSocket; - - // Dummy socket used to register the workstation name that some clients search for, although they connect - // to the file server service - - private NetBIOSSocket m_wksSocket; - - /** - * Class constructor - * - * @param srv SMBServer - * @param debug boolean - */ - public Win32NetBIOSSessionSocketHandler(SMBServer srv, boolean debug) - { - super("Win32 NetBIOS", srv, debug); - - // Get the Win32 NetBIOS file server name - - if (srv.getConfiguration().getWin32ServerName() != null) - m_srvName = srv.getConfiguration().getWin32ServerName(); - else - m_srvName = srv.getConfiguration().getServerName(); - - // Get the accepted client string, defaults to '*' to accept any client connection - - NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); - m_acceptClient = accName.getNetBIOSName(); - - // Set the LANA to use, or -1 to use the first available - - m_lana = srv.getConfiguration().getWin32LANA(); - - // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls - - m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS server " + m_srvName + " (using " + - (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); - - // Set the LANA offline polling interval - - m_lanaPoll = LANAPollingInterval; - } - - /** - * Class constructor - * - * @param srv SMBServer - * @param lana int - * @param debug boolean - */ - public Win32NetBIOSSessionSocketHandler(SMBServer srv, int lana, boolean debug) - { - super("Win32 NetBIOS", srv, debug); - - // Get the Win32 NetBIOS file server name - - if (srv.getConfiguration().getWin32ServerName() != null) - m_srvName = srv.getConfiguration().getWin32ServerName(); - else - m_srvName = srv.getConfiguration().getServerName(); - - // Get the accepted client string, defaults to '*' to accept any client connection - - NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); - m_acceptClient = accName.getNetBIOSName(); - - // Set the LANA to use, or -1 to use the first available - - m_lana = lana; - - // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls - - m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS server " + m_srvName + " (using " + - (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); - - // Set the LANA offline polling interval - - m_lanaPoll = LANAPollingInterval; - } - - /** - * Class constructor - * - * @param srv SMBServer - * @param nbName String - * @param debug boolean - */ - public Win32NetBIOSSessionSocketHandler(SMBServer srv, String nbName, boolean debug) - { - super("Win32 NetBIOS", srv, debug); - - // Set the Win32 NetBIOS file server name - - m_srvName = nbName; - - // Get the accepted client string, defaults to '*' to accept any client connection - - NetBIOSName accName = new NetBIOSName("*", NetBIOSName.WorkStation, false); - m_acceptClient = accName.getNetBIOSName(); - - // Set the LANA to use, or -1 to use the first available - - m_lana = srv.getConfiguration().getWin32LANA(); - - // Set the Win32 NetBIOS code to use either the Netbios() API call or Winsock NetBIOS calls - - m_useWinsock = srv.getConfiguration().useWinsockNetBIOS(); - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS server " + m_srvName + " (using " + - (isUsingWinsock() ? "Winsock" : "Netbios() API") + ")"); - - // Set the LANA offline polling interval - - m_lanaPoll = LANAPollingInterval; - } - - /** - * Return the LANA number that is being used - * - * @return int - */ - public final int getLANANumber() - { - return m_lana; - } - - /** - * Return the LANA offline polling interval to check for the LANA coming back online - * - * @return long - */ - public final long getLANAOfflinePollingInterval() - { - return m_lanaPoll; - } - - /** - * Return the assigned NetBIOS name number - * - * @return int - */ - public final int getNameNumber() - { - return m_nameNum; - } - - /** - * Return the local server name - * - * @return String - */ - public final String getServerName() - { - return m_srvName; - } - - /** - * Determine if Netbios() API calls or Winsock calls are being used - * - * @return boolean - */ - public final boolean isUsingWinsock() - { - return m_useWinsock; - } - - /** - * Initialize the session socket handler. - * - * @throws Exception - */ - public void initialize() throws Exception - { - - // Enumerate the LAN adapters, use the first available if the LANA has not been specified in - // the configuration - - int[] lanas = Win32NetBIOS.LanaEnumerate(); - if (lanas != null && lanas.length > 0) - { - - // Check if the LANA has been specified via the configuration, if not then use the first - // available - - if (m_lana == -1) - m_lana = lanas[0]; - else - { - - // Check if the required LANA is available - - boolean lanaOnline = false; - int idx = 0; - - while (idx < lanas.length && lanaOnline == false) - { - - // Check if the LANA is listed - - if (lanas[idx++] == getLANANumber()) - lanaOnline = true; - } - - // If the LANA is not available the main listener thread will poll the available - // LANAs until the required LANA is available - - if (lanaOnline == false) - { - - // Indicate that the LANA is not offline/unplugged/disabled - - m_lanaValid = false; - return; - } - } - } - else - { - - // If the LANA has not been set throw an exception as no LANAs are available - - if (m_lana == -1) - throw new Exception("No Win32 NetBIOS LANAs available"); - - // The required LANA is offline/unplugged/disabled - - m_lanaValid = false; - return; - } - - // Create the local NetBIOS name to listen for incoming connections on - - m_nbName = new NetBIOSName(m_srvName, NetBIOSName.FileServer, false); - m_wksNbName = new NetBIOSName(m_srvName, NetBIOSName.WorkStation, false); - - // Initialize the Win32 NetBIOS interface, either Winsock or Netbios() API - - if ( isUsingWinsock()) - initializeWinsockNetBIOS(); - else - initializeNetbiosAPI(); - - // Indicate that the LANA is valid - - m_lanaValid = true; - } - - /** - * Initialize the Win32 Netbios() API interface, add the server names - * - * @exception Exception If the NetBIOS add name fails - */ - private final void initializeNetbiosAPI() - throws Exception - { - // Reset the LANA - - Win32NetBIOS.Reset(m_lana); - - // Add the NetBIOS name to the local name table - - m_nameNum = Win32NetBIOS.AddName(m_lana, m_nbName.getNetBIOSName()); - if (m_nameNum < 0) - throw new Exception("Win32 NetBIOS AddName failed (file server), status = 0x" - + Integer.toHexString(-m_nameNum) + ", " + NetBIOS.getErrorString(-m_nameNum)); - - // Register a NetBIOS name for the server name with the workstation name type, some clients - // use this name to find the server - - m_wksNameNum = Win32NetBIOS.AddName(m_lana, m_wksNbName.getNetBIOSName()); - if (m_wksNameNum < 0) - throw new Exception("Win32 NetBIOS AddName failed (workstation), status = 0x" - + Integer.toHexString(-m_wksNameNum) + ", " + NetBIOS.getErrorString(-m_wksNameNum)); - } - - /** - * Initialize the Winsock NetBIOS interface - * - * @exception Exception If a Winsock error occurs - */ - private final void initializeWinsockNetBIOS() - throws Exception - { - // Create the NetBIOS listener socket, this will add the file server name - - m_nbSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_nbName); - - // Create a NetBIOS socket using the workstation name, some clients search for this name - - m_wksSocket = NetBIOSSocket.createListenerSocket( getLANANumber(), m_wksNbName); - } - - /** - * Check if the LANA is valid and accepting incoming sessions or the associated network adapter - * is unplugged/disabled/offline. - * - * @return boolean - */ - public final boolean isLANAValid() - { - return m_lanaValid; - } - - /** - * Shutdown the Win32 NetBIOS interface - */ - public void shutdownRequest() - { - super.shutdownRequest(); - - // Reset the LANA, if valid, to wake the main session listener thread - - if ( isLANAValid()) - Win32NetBIOS.Reset(m_lana); - - // If Winsock calls are being used close the sockets - - if ( isUsingWinsock()) - { - if ( m_nbSocket != null) - { - m_nbSocket.closeSocket(); - m_nbSocket = null; - } - - if ( m_wksSocket != null) - { - m_wksSocket.closeSocket(); - m_wksSocket = null; - } - } - } - - /** - * Run the NetBIOS session socket handler - */ - public void run() - { - - try - { - - // Clear the shutdown flag - - clearShutdown(); - - // Wait for incoming connection requests - - while (hasShutdown() == false) - { - - // Check if the LANA is valid and ready to accept incoming sessions - - if (isLANAValid()) - { - // Wait for an incoming session request - - if ( isUsingWinsock()) - { - // Wait for an incoming session request using the Winsock NetBIOS interface - - runWinsock(); - } - else - { - // Wait for an incoming session request using the Win32 Netbios() API interface - - runNetBIOS(); - } - } - else - { - - // Sleep for a short while ... - - try - { - Thread.sleep(getLANAOfflinePollingInterval()); - } - catch (Exception ex) - { - } - - // Check if the network adapter/LANA is back online, if so then re-initialize - // the LANA to start accepting sessions again - - try - { - initialize(); - } - catch (Exception ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - { - logger.debug("Win32 NetBIOS Failed To ReInitialize LANA"); - logger.debug(" " + ex.getMessage()); - } - } - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug() && isLANAValid()) - logger.debug("Win32 NetBIOS LANA " + getLANANumber() + " Back Online"); - } - } - } - 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.debug("Win32 NetBIOS Server error : " + ex.toString()); - logger.debug(ex); - } - } - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS session handler closed"); - } - - /** - * Run the Win32 Netbios() API listen code - * - * @exception Exception If an unhandled error occurs - */ - private final void runNetBIOS() - throws Exception - { - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Waiting for Win32 NetBIOS session request (Netbios API) ..."); - - // Clear the caller name - - byte[] callerNameBuf = new byte[NetBIOS.NCBNameSize]; - String callerName = null; - - callerNameBuf[0] = '\0'; - callerName = null; - - // Wait for a new NetBIOS session - - int lsn = Win32NetBIOS.Listen(m_lana, m_nbName.getNetBIOSName(), m_acceptClient, callerNameBuf); - - // Check if the session listener has been shutdown - - if ( hasShutdown()) - return; - - // Get the caller name, if available - - if (callerNameBuf[0] != '\0') - callerName = new String(callerNameBuf).trim(); - else - callerName = ""; - - // Create a packet handler and thread for the new session - - if (lsn >= 0) - { - - // Create a new session thread - - try - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS session request received, lsn=" + lsn + ", caller=[" - + callerName + "]"); - - // Create a packet handler for the session - - PacketHandler pktHandler = new Win32NetBIOSPacketHandler(m_lana, lsn, callerName); - - // Create a server session for the new request, and set the session id. - - SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); - srvSess.setSessionId(getNextSessionId()); - srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); - - // Add the session to the active session list - - getServer().addSession(srvSess); - - // Start the new session in a seperate thread - - Thread srvThread = new Thread(THREAD_GROUP_SESSION, srvSess); - srvThread.setDaemon(true); - srvThread.setName("Sess_W" + srvSess.getSessionId() + "_LSN" + lsn); - srvThread.start(); - } - catch (Exception ex) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS Failed to create session, " + ex.toString()); - } - } - else - { - - // Check if the error indicates the network adapter is - // unplugged/offline/disabled - - int sts = -lsn; - - if (sts == NetBIOS.NRC_Bridge) - { - - // Indicate that the LANA is no longer valid - - m_lanaValid = false; - - // DEBUG - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS LANA offline/disabled, LANA=" + getLANANumber()); - } - else if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Win32 NetBIOS Listen error, 0x" + Integer.toHexString(-lsn) + ", " - + NetBIOS.getErrorString(-lsn)); - } - } - - /** - * Run the Winsock NetBIOS listen code - * - * @exception Exception If an unhandled error occurs - */ - private final void runWinsock() - throws Exception - { - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Waiting for Win32 NetBIOS session request (Winsock) ..."); - - // Wait for a new NetBIOS session - - NetBIOSSocket sessSock = null; - - try - { - // Wait for an incoming session connection - - sessSock = m_nbSocket.listen(); - } - catch ( WinsockNetBIOSException ex) - { - // Check if the network is down - - if ( ex.getErrorCode() == WinsockError.WsaENetDown) - { - // Check if the LANA we are listening on is no longer valid - - if ( isLANAOnline(m_lana) == false) - { - // Network/LANA is offline, cleanup the current listening sockets and wait for the - // LANA to come back online - - if ( m_nbSocket != null) - { - m_nbSocket.closeSocket(); - m_nbSocket = null; - } - - if ( m_wksSocket != null) - { - m_wksSocket.closeSocket(); - m_wksSocket = null; - } - - // Indciate that the LANA is no longer valid - - m_lanaValid = false; - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Winsock NetBIOS network down, LANA=" + m_lana); - } - } - else - { - // Debug - - if (hasShutdown() == false && logger.isDebugEnabled() && hasDebug()) - logger.debug("Winsock NetBIOS listen error, " + ex.getMessage()); - } - } - - // Check if the session listener has been shutdown - - if ( hasShutdown()) - return; - - // Create a packet handler and thread for the new session - - if (sessSock != null) - { - - // Create a new session thread - - try - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Winsock NetBIOS session request received, caller=" - + sessSock.getName()); - - // Create a packet handler for the session - - PacketHandler pktHandler = new WinsockNetBIOSPacketHandler(m_lana, sessSock); - - // Create a server session for the new request, and set the session id. - - SMBSrvSession srvSess = new SMBSrvSession(pktHandler, getServer()); - srvSess.setSessionId(getNextSessionId()); - srvSess.setUniqueId(pktHandler.getShortName() + srvSess.getSessionId()); - - // Add the session to the active session list - - getServer().addSession(srvSess); - - // Start the new session in a seperate thread - - Thread srvThread = new Thread(THREAD_GROUP_SESSION, srvSess); - srvThread.setDaemon(true); - srvThread.setName("Sess_WS" + srvSess.getSessionId()); - srvThread.start(); - } - catch (Exception ex) - { - - // Debug - - if (logger.isDebugEnabled() && hasDebug()) - logger.debug("Winsock NetBIOS Failed to create session, " + ex.toString()); - } - } - } - - /** - * Create the Win32 NetBIOS session socket handlers for the main SMB/CIFS server - * - * @param server SMBServer - * @param sockDbg boolean - */ - public final static void createSessionHandlers(SMBServer server, boolean sockDbg) - { - - // Access the server configuration - - ServerConfiguration config = server.getConfiguration(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - { - int[] lanas = Win32NetBIOS.LanaEnumerate(); - - StringBuilder lanaStr = new StringBuilder(); - if (lanas != null && lanas.length > 0) - { - for (int i = 0; i < lanas.length; i++) - { - lanaStr.append(Integer.toString(lanas[i])); - lanaStr.append(" "); - } - } - logger.debug("Win32 NetBIOS Available LANAs: " + lanaStr.toString()); - } - - // Check if the Win32 NetBIOS session handler should use a particular LANA/network adapter - // or should use all available LANAs/network adapters (that have NetBIOS enabled). - - Win32NetBIOSSessionSocketHandler sessHandler = null; - List lanaListeners = new ArrayList(); - - if (config.getWin32LANA() != -1) - { - - // Create a single Win32 NetBIOS session handler using the specified LANA - - sessHandler = new Win32NetBIOSSessionSocketHandler(server, config.getWin32LANA(), sockDbg); - - try - { - sessHandler.initialize(); - } - catch (Exception ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - { - logger.debug("Win32 NetBIOS failed to create session handler for LANA " - + config.getWin32LANA()); - logger.debug(" " + ex.getMessage()); - } - } - - // Add the session handler to the SMB/CIFS server - - server.addSessionHandler(sessHandler); - - // Run the NetBIOS session handler in a seperate thread - - Thread nbThread = new Thread(sessHandler); - nbThread.setName("Win32NB_Handler_" + config.getWin32LANA()); - nbThread.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("Win32 NetBIOS created session handler on LANA " + config.getWin32LANA()); - - // Check if a host announcer should be enabled - - if (config.hasWin32EnableAnnouncer()) - { - - // Create a host announcer - - HostAnnouncer hostAnnouncer = null; - - String domain = config.getDomainName(); - int intvl = config.getWin32HostAnnounceInterval(); - - if ( config.useWinsockNetBIOS()) - { - // Create a Winsock NetBIOS announcer - - hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl); - } - else - { - // Create a Win32 Netbios() API announcer - - hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl); - } - - // Enable announcer debug - - hostAnnouncer.setDebug(sockDbg); - - // Add the host announcer to the SMB/CIFS server list - - server.addHostAnnouncer(hostAnnouncer); - hostAnnouncer.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("Win32 NetBIOS host announcer enabled on LANA " + config.getWin32LANA()); - } - - // Check if the session handler implements the LANA listener interface - - if ( sessHandler instanceof LanaListener) - lanaListeners.add( sessHandler); - } - else - { - - // Get a list of the available LANAs - - int[] lanas = Win32NetBIOS.LanaEnumerate(); - - if (lanas != null && lanas.length > 0) - { - - // Create a session handler for each available LANA - - for (int i = 0; i < lanas.length; i++) - { - - // Get the current LANA - - int lana = lanas[i]; - - // Create a session handler - - sessHandler = new Win32NetBIOSSessionSocketHandler(server, lana, sockDbg); - - try - { - sessHandler.initialize(); - } - catch (Exception ex) - { - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - { - logger.debug("Win32 NetBIOS failed to create session handler for LANA " + lana); - logger.debug(" " + ex.getMessage()); - } - } - - // Add the session handler to the SMB/CIFS server - - server.addSessionHandler(sessHandler); - - // Run the NetBIOS session handler in a seperate thread - - Thread nbThread = new Thread(sessHandler); - nbThread.setName("Win32NB_Handler_" + lana); - nbThread.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("Win32 NetBIOS created session handler on LANA " + lana); - - // Check if a host announcer should be enabled - - if (config.hasWin32EnableAnnouncer()) - { - - // Create a host announcer - - HostAnnouncer hostAnnouncer = null; - - String domain = config.getDomainName(); - int intvl = config.getWin32HostAnnounceInterval(); - - if ( config.useWinsockNetBIOS()) - { - // Create a Winsock NetBIOS announcer - - hostAnnouncer = new WinsockNetBIOSHostAnnouncer(sessHandler, domain, intvl); - } - else - { - // Create a Win32 Netbios() API announcer - - hostAnnouncer = new Win32NetBIOSHostAnnouncer(sessHandler, domain, intvl); - } - - // Enable announcer debug - - hostAnnouncer.setDebug(sockDbg); - - // Add the host announcer to the SMB/CIFS server list - - server.addHostAnnouncer(hostAnnouncer); - hostAnnouncer.start(); - - // DEBUG - - if (logger.isDebugEnabled() && sockDbg) - logger.debug("Win32 NetBIOS host announcer enabled on LANA " + lana); - } - - // Check if the session handler implements the LANA listener interface - - if ( sessHandler instanceof LanaListener) - lanaListeners.add( sessHandler); - } - } - - // Create a LANA monitor to check for new LANAs becoming available - - Win32NetBIOSLanaMonitor lanaMonitor = new Win32NetBIOSLanaMonitor(server, lanas, LANAPollingInterval, sockDbg); - - // Register any session handlers that are LANA listeners - - if ( lanaListeners.size() > 0) - { - for ( Win32NetBIOSSessionSocketHandler handler : lanaListeners) - { - // Register the LANA listener - - lanaMonitor.addLanaListener( handler.getLANANumber(), handler); - } - } - } - } - - /** - * Check if the specified LANA is online - * - * @param lana int - * @return boolean - */ - private final boolean isLANAOnline(int lana) - { - // Get a list of the available LANAs - - int[] lanas = Win32NetBIOS.LanaEnumerate(); - - if (lanas != null && lanas.length > 0) - { - // Check if the specified LANA is available - - for (int i = 0; i < lanas.length; i++) - { - if ( lanas[i] == lana) - return true; - } - } - - // LANA not online - - return false; - } - - /** - * LANA listener status change callback - * - * @param lana int - * @param online boolean - */ - public void lanaStatusChange(int lana, boolean online) - { - // If the LANA has gone offline, close the listening socket and wait for the LANA to - // come back online - - if ( online == false) - { - // Indicate that the LANA is offline - - m_lanaValid = false; - - // Close the listening sockets - - if ( m_nbSocket != null) - { - m_nbSocket.closeSocket(); - m_nbSocket = null; - } - - if ( m_wksSocket != null) - { - m_wksSocket.closeSocket(); - m_wksSocket = null; - } - } - } -} diff --git a/source/java/org/alfresco/filesys/smb/server/win32/WinsockNetBIOSPacketHandler.java b/source/java/org/alfresco/filesys/smb/server/win32/WinsockNetBIOSPacketHandler.java deleted file mode 100644 index c973952ac6..0000000000 --- a/source/java/org/alfresco/filesys/smb/server/win32/WinsockNetBIOSPacketHandler.java +++ /dev/null @@ -1,204 +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.smb.server.win32; - -import java.io.IOException; - -import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; -import org.alfresco.filesys.netbios.win32.NetBIOSSocket; -import org.alfresco.filesys.netbios.win32.WinsockError; -import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException; -import org.alfresco.filesys.smb.server.PacketHandler; -import org.alfresco.filesys.smb.server.SMBSrvPacket; - -/** - * Winsock NetBIOS Packet Handler Class - * - *

Uses a Windows Winsock NetBIOS socket to provide the low level session layer for better integration - * with Windows. - * - * @author GKSpencer - */ -public class WinsockNetBIOSPacketHandler extends PacketHandler -{ - // Constants - // - // Receive error indicating a receive buffer error - - private static final int ReceiveBufferSizeError = 0x80000000; - - // Network LAN adapter to use - - private int m_lana; - - // NetBIOS session socket - - private NetBIOSSocket m_sessSock; - - /** - * Class constructor - * - * @param lana int - * @param sock NetBIOSSocket - */ - public WinsockNetBIOSPacketHandler(int lana, NetBIOSSocket sock) - { - super(SMBSrvPacket.PROTOCOL_WIN32NETBIOS, "WinsockNB", "WSNB", sock.getName().getName()); - - m_lana = lana; - m_sessSock = sock; - } - - /** - * Return the LANA number - * - * @return int - */ - public final int getLANA() - { - return m_lana; - } - - /** - * Return the NetBIOS socket - * - * @return NetBIOSSocket - */ - public final NetBIOSSocket getSocket() - { - return m_sessSock; - } - - /** - * Read a packet from the client - * - * @param pkt SMBSrvPacket - * @return int - * @throws IOException - */ - public int readPacket(SMBSrvPacket pkt) throws IOException - { - // Receive an SMB/CIFS request packet via the Winsock NetBIOS socket - - int rxlen = 0; - - try { - - // Read a pakcet of data - - rxlen = m_sessSock.read(pkt.getBuffer(), 4, pkt.getBufferLength() - 4); - - // Check if the buffer is not big enough to receive the entire packet, extend the buffer - // and read the remaining part of the packet - - if (rxlen == ReceiveBufferSizeError) - { - - // Check if the packet buffer is already at the maximum size (we assume the maximum - // size is the maximum that RFC NetBIOS can send which is 17bits) - - if (pkt.getBuffer().length < RFCNetBIOSProtocol.MaxPacketSize) - { - // Set the initial receive size, assume a full read - - rxlen = pkt.getBufferLength() - 4; - - // Allocate a new buffer, copy the existing data to the new buffer - - byte[] newbuf = new byte[RFCNetBIOSProtocol.MaxPacketSize]; - System.arraycopy(pkt.getBuffer(), 4, newbuf, 4, rxlen); - pkt.setBuffer( newbuf); - - // Receive the packet - - int rxlen2 = m_sessSock.read(pkt.getBuffer(), rxlen + 4, pkt.getBufferLength() - (rxlen + 4)); - - System.out.println("Winsock rx2 len=" + rxlen2); - - if ( rxlen2 == ReceiveBufferSizeError) - throw new WinsockNetBIOSException(WinsockError.WsaEMsgSize); - - rxlen += rxlen2; - } - else - throw new WinsockNetBIOSException(WinsockError.WsaEMsgSize); - } - } - catch ( WinsockNetBIOSException ex) - { - // Check if the remote client has closed the socket - - if ( ex.getErrorCode() == WinsockError.WsaEConnReset || - ex.getErrorCode() == WinsockError.WsaEDiscon) - { - // Indicate that the socket has been closed - - rxlen = -1; - } - else - { - // Rethrow the exception - - throw ex; - } - } - - // Return the received packet length - - return rxlen; - } - - /** - * Write a packet to the client - * - * @param pkt SMBSrvPacket - * @param len int - * @throws IOException - */ - public void writePacket(SMBSrvPacket pkt, int len) throws IOException - { - // Output the packet via the Winsock NetBIOS socket - // - // As Windows is handling the NetBIOS session layer we do not send the 4 byte header that is - // used by the NetBIOS over TCP/IP and native SMB packet handlers. - - int txlen = m_sessSock.write(pkt.getBuffer(), 4, len); - - // Do not check the status, if the session has been closed the next receive will fail - } - - /** - * Close the Winsock NetBIOS packet handler. - */ - public void closeHandler() - { - super.closeHandler(); - - // Close the session socket - - if ( m_sessSock != null) - m_sessSock.closeSocket(); - } -} diff --git a/source/java/org/alfresco/filesys/server/state/FileState.java b/source/java/org/alfresco/filesys/state/FileState.java similarity index 92% rename from source/java/org/alfresco/filesys/server/state/FileState.java rename to source/java/org/alfresco/filesys/state/FileState.java index af130e3339..983bb5425d 100644 --- a/source/java/org/alfresco/filesys/server/state/FileState.java +++ b/source/java/org/alfresco/filesys/state/FileState.java @@ -22,17 +22,17 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.filesys.server.state; +package org.alfresco.filesys.state; -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.locking.FileLockList; -import org.alfresco.filesys.locking.LockConflictException; -import org.alfresco.filesys.locking.NotLockedException; -import org.alfresco.filesys.server.filesys.FileOpenParams; -import org.alfresco.filesys.server.filesys.FileStatus; -import org.alfresco.filesys.server.pseudo.PseudoFile; -import org.alfresco.filesys.server.pseudo.PseudoFileList; -import org.alfresco.filesys.smb.SharingMode; +import org.alfresco.jlan.locking.FileLock; +import org.alfresco.jlan.locking.FileLockList; +import org.alfresco.jlan.locking.LockConflictException; +import org.alfresco.jlan.locking.NotLockedException; +import org.alfresco.jlan.server.filesys.FileOpenParams; +import org.alfresco.jlan.server.filesys.FileStatus; +import org.alfresco.jlan.server.filesys.pseudo.PseudoFile; +import org.alfresco.jlan.server.filesys.pseudo.PseudoFileList; +import org.alfresco.jlan.smb.SharingMode; import org.alfresco.service.cmr.repository.NodeRef; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -361,26 +361,6 @@ public class FileState m_pseudoFiles = new PseudoFileList(); m_pseudoFiles.addFile( pfile); } - - /** - * Return the last updated time - * - * @return long - */ - public final long getLastUpdated() - { - return m_lastUpdate; - } - - /** - * Set the last updated time - * - * @param updateTime long - */ - public final void setLastUpdated(long updateTime) - { - m_lastUpdate = updateTime; - } /** * Set the file status @@ -462,6 +442,26 @@ public class FileState m_path = normalizePath(path); } + /** + * Return the last updated time + * + * @return long + */ + public final long getLastUpdated() + { + return m_lastUpdate; + } + + /** + * Set the last updated time + * + * @param updateTime long + */ + public final void setLastUpdated(long updateTime) + { + m_lastUpdate = updateTime; + } + /** * Return the count of active locks on this file * diff --git a/source/java/org/alfresco/filesys/server/state/FileStateLockManager.java b/source/java/org/alfresco/filesys/state/FileStateLockManager.java similarity index 83% rename from source/java/org/alfresco/filesys/server/state/FileStateLockManager.java rename to source/java/org/alfresco/filesys/state/FileStateLockManager.java index 7c7d329614..159d7a17a1 100644 --- a/source/java/org/alfresco/filesys/server/state/FileStateLockManager.java +++ b/source/java/org/alfresco/filesys/state/FileStateLockManager.java @@ -22,17 +22,18 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.filesys.server.state; +package org.alfresco.filesys.state; import java.io.IOException; -import org.alfresco.filesys.locking.FileLock; -import org.alfresco.filesys.locking.LockConflictException; -import org.alfresco.filesys.locking.NotLockedException; -import org.alfresco.filesys.server.SrvSession; -import org.alfresco.filesys.server.filesys.NetworkFile; -import org.alfresco.filesys.server.filesys.TreeConnection; -import org.alfresco.filesys.server.locking.LockManager; +import org.alfresco.jlan.locking.FileLock; +import org.alfresco.jlan.locking.LockConflictException; +import org.alfresco.jlan.locking.NotLockedException; +import org.alfresco.jlan.server.SrvSession; +import org.alfresco.jlan.server.filesys.NetworkFile; +import org.alfresco.jlan.server.filesys.TreeConnection; +import org.alfresco.jlan.server.locking.LockManager; +import org.alfresco.filesys.alfresco.AlfrescoNetworkFile; /** * File State Lock Manager Class @@ -58,7 +59,12 @@ public class FileStateLockManager implements LockManager { // Get the file state associated with the file - FileState fstate = file.getFileState(); + FileState fstate = null; + + if ( file instanceof AlfrescoNetworkFile) { + AlfrescoNetworkFile alfFile = (AlfrescoNetworkFile) file; + fstate = alfFile.getFileState(); + } if ( fstate == null) throw new IOException("Open file without state (lock)"); @@ -86,7 +92,12 @@ public class FileStateLockManager implements LockManager { // Get the file state associated with the file - FileState fstate = file.getFileState(); + FileState fstate = null; + + if ( file instanceof AlfrescoNetworkFile) { + AlfrescoNetworkFile alfFile = (AlfrescoNetworkFile) file; + fstate = alfFile.getFileState(); + } if ( fstate == null) throw new IOException("Open file without state (unlock)"); diff --git a/source/java/org/alfresco/filesys/server/state/FileStateReaper.java b/source/java/org/alfresco/filesys/state/FileStateReaper.java similarity index 99% rename from source/java/org/alfresco/filesys/server/state/FileStateReaper.java rename to source/java/org/alfresco/filesys/state/FileStateReaper.java index 86f6907386..6a421e0ff9 100644 --- a/source/java/org/alfresco/filesys/server/state/FileStateReaper.java +++ b/source/java/org/alfresco/filesys/state/FileStateReaper.java @@ -21,7 +21,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.filesys.server.state; +package org.alfresco.filesys.state; import java.util.Enumeration; import java.util.Hashtable; diff --git a/source/java/org/alfresco/filesys/server/state/FileStateTable.java b/source/java/org/alfresco/filesys/state/FileStateTable.java similarity index 92% rename from source/java/org/alfresco/filesys/server/state/FileStateTable.java rename to source/java/org/alfresco/filesys/state/FileStateTable.java index c8435e259d..e0b98086fa 100644 --- a/source/java/org/alfresco/filesys/server/state/FileStateTable.java +++ b/source/java/org/alfresco/filesys/state/FileStateTable.java @@ -22,7 +22,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.filesys.server.state; +package org.alfresco.filesys.state; import java.util.*; @@ -196,9 +196,9 @@ public class FileStateTable /** * Enumerate the file state cache * - * @return Enumeration + * @return Enumeration */ - public final Enumeration enumerate() + public final Enumeration enumerate() { return m_stateTable.keys(); } @@ -254,7 +254,7 @@ public class FileStateTable // Enumerate the file state cache and remove expired file state objects - Enumeration enm = m_stateTable.keys(); + Enumeration enm = m_stateTable.keys(); while (enm.hasMoreElements()) { @@ -289,7 +289,7 @@ public class FileStateTable // Enumerate the file state cache and remove expired file state objects - Enumeration enm = m_stateTable.keys(); + Enumeration enm = m_stateTable.keys(); long curTime = System.currentTimeMillis(); int expiredCnt = 0; @@ -346,12 +346,12 @@ public class FileStateTable if (m_stateTable.size() > 0) logger.debug("FileStateCache Entries:"); - Enumeration enm = m_stateTable.keys(); + Enumeration enm = m_stateTable.keys(); long curTime = System.currentTimeMillis(); while (enm.hasMoreElements()) { - String fname = (String) enm.nextElement(); + String fname = enm.nextElement(); FileState state = m_stateTable.get(fname); logger.debug(" " + fname + "(" + state.getSecondsToExpire(curTime) + ") : " + state); diff --git a/source/java/org/alfresco/filesys/util/CifsMounter.java b/source/java/org/alfresco/filesys/util/CifsMounter.java index ab1f8f069e..3e6274da40 100644 --- a/source/java/org/alfresco/filesys/util/CifsMounter.java +++ b/source/java/org/alfresco/filesys/util/CifsMounter.java @@ -28,6 +28,7 @@ package org.alfresco.filesys.util; import java.util.HashMap; import java.util.Map; +import org.alfresco.jlan.util.Platform; import org.alfresco.util.exec.RuntimeExec; import org.alfresco.util.exec.RuntimeExec.ExecutionResult; import org.apache.commons.logging.Log; diff --git a/source/java/org/alfresco/filesys/util/DataBuffer.java b/source/java/org/alfresco/filesys/util/DataBuffer.java deleted file mode 100644 index fd7b2f4b5a..0000000000 --- a/source/java/org/alfresco/filesys/util/DataBuffer.java +++ /dev/null @@ -1,865 +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.util; - -/** - * Data Buffer Class - *

- * Dynamic buffer for getting/setting data blocks. - */ -public class DataBuffer -{ - - // Constants - - private static final int DefaultBufferSize = 256; - - // Data buffer, current position and offset - - private byte[] m_data; - private int m_pos; - private int m_endpos; - private int m_offset; - - /** - * Default constructor - */ - public DataBuffer() - { - m_data = new byte[DefaultBufferSize]; - m_pos = 0; - m_offset = 0; - } - - /** - * Create a data buffer to write data to - * - * @param siz int - */ - public DataBuffer(int siz) - { - m_data = new byte[siz]; - m_pos = 0; - m_offset = 0; - } - - /** - * Create a data buffer to read data from - * - * @param buf byte[] - * @param off int - * @param len int - */ - public DataBuffer(byte[] buf, int off, int len) - { - m_data = buf; - m_offset = off; - m_pos = off; - m_endpos = off + len; - } - - /** - * Return the data buffer - * - * @return byte[] - */ - public final byte[] getBuffer() - { - return m_data; - } - - /** - * Return the data length - * - * @return int - */ - public final int getLength() - { - if (m_endpos != 0) - return m_endpos - m_offset; - return m_pos - m_offset; - } - - /** - * Return the data length in words - * - * @return int - */ - public final int getLengthInWords() - { - return getLength() / 2; - } - - /** - * Return the available data length - * - * @return int - */ - public final int getAvailableLength() - { - if (m_endpos == 0) - return -1; - return m_endpos - m_pos; - } - - /** - * Return the displacement from the start of the buffer to the current buffer position - * - * @return int - */ - public final int getDisplacement() - { - return m_pos - m_offset; - } - - /** - * Return the buffer base offset - * - * @return int - */ - public final int getOffset() - { - return m_offset; - } - - /** - * Get a byte from the buffer - * - * @return int - */ - public final int getByte() - { - - // Check if there is enough data in the buffer - - if (m_data.length - m_pos < 1) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the byte value - - int bval = (int) (m_data[m_pos] & 0xFF); - m_pos++; - return bval; - } - - /** - * Get a short from the buffer - * - * @return int - */ - public final int getShort() - { - - // Check if there is enough data in the buffer - - if (m_data.length - m_pos < 2) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the integer value - - int sval = (int) DataPacker.getIntelShort(m_data, m_pos); - m_pos += 2; - return sval; - } - - /** - * Get an integer from the buffer - * - * @return int - */ - public final int getInt() - { - - // Check if there is enough data in the buffer - - if (m_data.length - m_pos < 4) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the integer value - - int ival = DataPacker.getIntelInt(m_data, m_pos); - m_pos += 4; - return ival; - } - - /** - * Get a long (64 bit) value from the buffer - * - * @return long - */ - public final long getLong() - { - - // Check if there is enough data in the buffer - - if (m_data.length - m_pos < 8) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the long value - - long lval = DataPacker.getIntelLong(m_data, m_pos); - m_pos += 8; - return lval; - } - - /** - * Get a string from the buffer - * - * @param uni boolean - * @return String - */ - public final String getString(boolean uni) - { - return getString(255, uni); - } - - /** - * Get a string from the buffer - * - * @param maxlen int - * @param uni boolean - * @return String - */ - public final String getString(int maxlen, boolean uni) - { - - // Check for Unicode or ASCII - - String ret = null; - int availLen = -1; - - if (uni) - { - - // Word align the current buffer position, calculate the available - // length - - m_pos = DataPacker.wordAlign(m_pos); - availLen = (m_endpos - m_pos) / 2; - if (availLen < maxlen) - maxlen = availLen; - - ret = DataPacker.getUnicodeString(m_data, m_pos, maxlen); - if (ret != null) { - if ( ret.length() < maxlen) - m_pos += (ret.length() * 2) + 2; - else - m_pos += maxlen * 2; - } - } - else - { - - // Calculate the available length - - availLen = m_endpos - m_pos; - if (availLen < maxlen) - maxlen = availLen; - - // Unpack the ASCII string - - ret = DataPacker.getString(m_data, m_pos, maxlen); - if (ret != null) { - if ( ret.length() < maxlen) - m_pos += ret.length() + 1; - else - m_pos += maxlen; - } - } - - // Return the string - - return ret; - } - - /** - * Get a short from the buffer at the specified index - * - * @param idx int - * @return int - */ - public final int getShortAt(int idx) - { - - // Check if there is enough data in the buffer - - int pos = m_offset + (idx * 2); - if (m_data.length - pos < 2) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the integer value - - int sval = (int) DataPacker.getIntelShort(m_data, pos) & 0xFFFF; - return sval; - } - - /** - * Get an integer from the buffer at the specified index - * - * @param idx int - * @return int - */ - public final int getIntAt(int idx) - { - - // Check if there is enough data in the buffer - - int pos = m_offset + (idx * 2); - if (m_data.length - pos < 4) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the integer value - - int ival = DataPacker.getIntelInt(m_data, pos); - return ival; - } - - /** - * Get a long (64 bit) value from the buffer at the specified index - * - * @param idx int - * @return long - */ - public final long getLongAt(int idx) - { - - // Check if there is enough data in the buffer - - int pos = m_offset + (idx * 2); - if (m_data.length - pos < 8) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Unpack the long value - - long lval = DataPacker.getIntelLong(m_data, pos); - return lval; - } - - /** - * Skip over a number of bytes - * - * @param cnt int - */ - public final void skipBytes(int cnt) - { - - // Check if there is enough data in the buffer - - if (m_data.length - m_pos < cnt) - throw new ArrayIndexOutOfBoundsException("End of data buffer"); - - // Skip bytes - - m_pos += cnt; - } - - /** - * Return the data position - * - * @return int - */ - public final int getPosition() - { - return m_pos; - } - - /** - * Set the read/write buffer position - * - * @param pos int - */ - public final void setPosition(int pos) - { - m_pos = pos; - } - - /** - * Set the end of buffer position, and reset the read position to the beginning of the buffer - */ - public final void setEndOfBuffer() - { - m_endpos = m_pos; - m_pos = m_offset; - } - - /** - * Set the data length - * - * @param len int - */ - public final void setLength(int len) - { - m_pos = m_offset + len; - } - - /** - * Append a byte value to the buffer - * - * @param bval int - */ - public final void putByte(int bval) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < 1) - extendBuffer(); - - // Pack the byte value - - m_data[m_pos++] = (byte) (bval & 0xFF); - } - - /** - * Append a short value to the buffer - * - * @param sval int - */ - public final void putShort(int sval) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < 2) - extendBuffer(); - - // Pack the short value - - DataPacker.putIntelShort(sval, m_data, m_pos); - m_pos += 2; - } - - /** - * Append an integer to the buffer - * - * @param ival int - */ - public final void putInt(int ival) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < 4) - extendBuffer(); - - // Pack the integer value - - DataPacker.putIntelInt(ival, m_data, m_pos); - m_pos += 4; - } - - /** - * Append a long to the buffer - * - * @param lval long - */ - public final void putLong(long lval) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < 8) - extendBuffer(); - - // Pack the long value - - DataPacker.putIntelLong(lval, m_data, m_pos); - m_pos += 8; - } - - /** - * Append a short value to the buffer at the specified index - * - * @param idx int - * @param sval int - */ - public final void putShortAt(int idx, int sval) - { - - // Check if there is enough space in the buffer - - int pos = m_offset + (idx * 2); - if (m_data.length - pos < 2) - extendBuffer(); - - // Pack the short value - - DataPacker.putIntelShort(sval, m_data, pos); - } - - /** - * Append an integer to the buffer at the specified index - * - * @param idx int - * @param ival int - */ - public final void putIntAt(int idx, int ival) - { - - // Check if there is enough space in the buffer - - int pos = m_offset = (idx * 2); - if (m_data.length - pos < 4) - extendBuffer(); - - // Pack the integer value - - DataPacker.putIntelInt(ival, m_data, pos); - } - - /** - * Append a long to the buffer at the specified index - * - * @param idx int - * @param lval long - */ - public final void putLongAt(int idx, int lval) - { - - // Check if there is enough space in the buffer - - int pos = m_offset = (idx * 2); - if (m_data.length - pos < 8) - extendBuffer(); - - // Pack the long value - - DataPacker.putIntelLong(lval, m_data, pos); - } - - /** - * Append a string to the buffer - * - * @param str String - * @param uni boolean - */ - public final void putString(String str, boolean uni) - { - putString(str, uni, true); - } - - /** - * Append a string to the buffer - * - * @param str String - * @param uni boolean - * @param nulTerm boolean - */ - public final void putString(String str, boolean uni, boolean nulTerm) - { - - // Check for Unicode or ASCII - - if (uni) - { - - // Check if there is enough space in the buffer - - int bytLen = str.length() * 2; - if ( nulTerm) - bytLen += 2; - if ((m_data.length - m_pos) < (bytLen + 4)) - extendBuffer(bytLen + 4); - - // Word align the buffer position, pack the Unicode string - - m_pos = DataPacker.wordAlign(m_pos); - DataPacker.putUnicodeString(str, m_data, m_pos, nulTerm); - m_pos += (str.length() * 2); - if (nulTerm) - m_pos += 2; - } - else - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < str.length()) - extendBuffer(str.length() + 2); - - // Pack the ASCII string - - DataPacker.putString(str, m_data, m_pos, nulTerm); - m_pos += str.length(); - if (nulTerm) - m_pos++; - } - } - - /** - * Append a fixed length string to the buffer - * - * @param str String - * @param len int - */ - public final void putFixedString(String str, int len) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < str.length()) - extendBuffer(str.length() + 2); - - // Pack the ASCII string - - DataPacker.putString(str, len, m_data, m_pos); - m_pos += len; - } - - /** - * Append a string to the buffer at the specified buffer position - * - * @param str String - * @param pos int - * @param uni boolean - * @param nulTerm boolean - * @return int - */ - public final int putStringAt(String str, int pos, boolean uni, boolean nulTerm) - { - - // Check for Unicode or ASCII - - int retPos = -1; - - if (uni) - { - - // Check if there is enough space in the buffer - - int bytLen = str.length() * 2; - if (m_data.length - pos < bytLen) - extendBuffer(bytLen + 4); - - // Word align the buffer position, pack the Unicode string - - pos = DataPacker.wordAlign(pos); - retPos = DataPacker.putUnicodeString(str, m_data, pos, nulTerm); - } - else - { - - // Check if there is enough space in the buffer - - if (m_data.length - pos < str.length()) - extendBuffer(str.length() + 2); - - // Pack the ASCII string - - retPos = DataPacker.putString(str, m_data, pos, nulTerm); - } - - // Return the end of string buffer position - - return retPos; - } - - /** - * Append a fixed length string to the buffer at the specified position - * - * @param str String - * @param len int - * @param pos int - * @return int - */ - public final int putFixedStringAt(String str, int len, int pos) - { - - // Check if there is enough space in the buffer - - if (m_data.length - pos < str.length()) - extendBuffer(str.length() + 2); - - // Pack the ASCII string - - return DataPacker.putString(str, len, m_data, pos); - } - - /** - * Append a string pointer to the specified buffer offset - * - * @param off int - */ - public final void putStringPointer(int off) - { - - // Calculate the offset from the start of the data buffer to the string - // position - - DataPacker.putIntelInt(off - m_offset, m_data, m_pos); - m_pos += 4; - } - - /** - * Append zero bytes to the buffer - * - * @param cnt int - */ - public final void putZeros(int cnt) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < cnt) - extendBuffer(cnt); - - // Pack the zero bytes - - for (int i = 0; i < cnt; i++) - m_data[m_pos++] = 0; - } - - /** - * Word align the buffer position - */ - public final void wordAlign() - { - m_pos = DataPacker.wordAlign(m_pos); - } - - /** - * Longword align the buffer position - */ - public final void longwordAlign() - { - m_pos = DataPacker.longwordAlign(m_pos); - } - - /** - * Append a raw data block to the data buffer - * - * @param buf byte[] - * @param off int - * @param len int - */ - public final void appendData(byte[] buf, int off, int len) - { - - // Check if there is enough space in the buffer - - if (m_data.length - m_pos < len) - extendBuffer(len); - - // Copy the data to the buffer and update the current write position - - System.arraycopy(buf, off, m_data, m_pos, len); - m_pos += len; - } - - /** - * Copy all data from the data buffer to the user buffer, and update the read position - * - * @param buf byte[] - * @param off int - * @return int - */ - public final int copyData(byte[] buf, int off) - { - return copyData(buf, off, getLength()); - } - - /** - * Copy data from the data buffer to the user buffer, and update the current read position. - * - * @param buf byte[] - * @param off int - * @param cnt int - * @return int - */ - public final int copyData(byte[] buf, int off, int cnt) - { - - // Check if there is any more data to copy - - if (m_pos == m_endpos) - return 0; - - // Calculate the amount of data to copy - - int siz = m_endpos - m_pos; - if (siz > cnt) - siz = cnt; - - // Copy the data to the user buffer and update the current read position - - System.arraycopy(m_data, m_pos, buf, off, siz); - m_pos += siz; - - // Return the amount of data copied - - return siz; - } - - /** - * Extend the data buffer by the specified amount - * - * @param ext int - */ - private final void extendBuffer(int ext) - { - - // Create a new buffer of the required size - - byte[] newBuf = new byte[m_data.length + ext]; - - // Copy the data from the current buffer to the new buffer - - System.arraycopy(m_data, 0, newBuf, 0, m_data.length); - - // Set the new buffer to be the main buffer - - m_data = newBuf; - } - - /** - * Extend the data buffer, double the currently allocated buffer size - */ - private final void extendBuffer() - { - extendBuffer(m_data.length * 2); - } - - /** - * Return the data buffer details as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - - str.append("[data="); - str.append(m_data); - str.append(","); - str.append(m_pos); - str.append("/"); - str.append(m_offset); - str.append("/"); - str.append(getLength()); - str.append("]"); - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/util/DataPacker.java b/source/java/org/alfresco/filesys/util/DataPacker.java deleted file mode 100644 index 1aa6b9186c..0000000000 --- a/source/java/org/alfresco/filesys/util/DataPacker.java +++ /dev/null @@ -1,786 +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.util; - -/** - * The data packing class is a static class that is used to pack and unpack basic data types to/from - * network byte order and Intel byte order. - */ -public final class DataPacker -{ - - // Flag to indicate the byte order of the platform that we are currently - // running on. - - private static boolean bigEndian = false; - - /** - * Return the current endian setting. - * - * @return true if the system is big endian, else false. - */ - public final static boolean isBigEndian() - { - return bigEndian; - } - - /** - * Unpack a null terminated data string from the data buffer. - * - * @param typ Data type, as specified by SMBDataType. - * @param bytarray Byte array to unpack the string value from. - * @param pos Offset to start unpacking the string value. - * @param maxlen Maximum length of data to be searched for a null character. - * @param uni String is Unicode if true, else ASCII - * @return String, else null if the terminating null character was not found. - */ - public final static String getDataString(char typ, byte[] bytarray, int pos, int maxlen, boolean uni) - { - - // Check if the data string has the required data type - - if (bytarray[pos++] == (byte) typ) - { - - // Extract the null terminated string - - if (uni == true) - return getUnicodeString(bytarray, wordAlign(pos), maxlen / 2); - else - return getString(bytarray, pos, maxlen - 1); - } - - // Invalid data type - - return null; - } - - /** - * Unpack a 32-bit integer. - * - * @param buf Byte buffer containing the integer to be unpacked. - * @param pos Position within the buffer that the integer is stored. - * @return The unpacked 32-bit integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static int getInt(byte[] buf, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough - - if (buf.length < pos + 3) - throw new java.lang.IndexOutOfBoundsException(); - - // Unpack the 32-bit value - - int i1 = (int) buf[pos] & 0xFF; - int i2 = (int) buf[pos + 1] & 0xFF; - int i3 = (int) buf[pos + 2] & 0xFF; - int i4 = (int) buf[pos + 3] & 0xFF; - - int iVal = (i1 << 24) + (i2 << 16) + (i3 << 8) + i4; - - // Return the unpacked value - - return iVal; - } - - /** - * Unpack a 32-bit integer that is stored in Intel format. - * - * @param bytarray Byte array containing the Intel integer to be unpacked. - * @param pos Offset that the Intel integer is stored within the byte array. - * @return Unpacked integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static int getIntelInt(byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to restore the int - - if (bytarray.length < pos + 3) - throw new java.lang.IndexOutOfBoundsException(); - - // Determine the byte ordering for this platform, and restore the int - - int iVal = 0; - - // Restore the int value from the byte array - - int i1 = (int) bytarray[pos + 3] & 0xFF; - int i2 = (int) bytarray[pos + 2] & 0xFF; - int i3 = (int) bytarray[pos + 1] & 0xFF; - int i4 = (int) bytarray[pos] & 0xFF; - - iVal = (i1 << 24) + (i2 << 16) + (i3 << 8) + i4; - - // Return the int value - - return iVal; - } - - /** - * Unpack a 64-bit long. - * - * @param buf Byte buffer containing the integer to be unpacked. - * @param pos Position within the buffer that the integer is stored. - * @return The unpacked 64-bit long value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static long getLong(byte[] buf, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to restore the long - - if (buf.length < pos + 7) - throw new java.lang.IndexOutOfBoundsException(); - - // Restore the long value from the byte array - - long lVal = 0L; - - for (int i = 0; i < 8; i++) - { - - // Get the current byte, shift the value and add to the return value - - long curVal = (long) buf[pos + i] & 0xFF; - curVal = curVal << ((7 - i) * 8); - lVal += curVal; - } - - // Return the long value - - return lVal; - } - - /** - * Unpack a 64-bit integer that is stored in Intel format. - * - * @param bytarray Byte array containing the Intel long to be unpacked. - * @param pos Offset that the Intel integer is stored within the byte array. - * @return Unpacked long value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static long getIntelLong(byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to restore the long - - if (bytarray.length < pos + 7) - throw new java.lang.IndexOutOfBoundsException(); - - // Restore the long value from the byte array - - long lVal = 0L; - - for (int i = 0; i < 8; i++) - { - - // Get the current byte, shift the value and add to the return value - - long curVal = (long) bytarray[pos + i] & 0xFF; - curVal = curVal << (i * 8); - lVal += curVal; - } - - // Return the long value - - return lVal; - } - - /** - * Unpack a 16-bit value that is stored in Intel format. - * - * @param bytarray Byte array containing the short value to be unpacked. - * @param pos Offset to start unpacking the short value. - * @return Unpacked short value. - * @exception java.lang.IndexOutOfBoiundsException If there is not enough data in the buffer. - */ - public final static int getIntelShort(byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to restore the int - - if (bytarray.length < pos) - throw new java.lang.IndexOutOfBoundsException(); - - // Restore the short value from the byte array - - int sVal = (((int) bytarray[pos + 1] << 8) + ((int) bytarray[pos] & 0xFF)); - - // Return the short value - - return sVal & 0xFFFF; - } - - /** - * Unpack a 16-bit value. - * - * @param bytarray Byte array containing the short to be unpacked. - * @param pos Offset within the byte array that the short is stored. - * @return Unpacked short value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static int getShort(byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to restore the int - - if (bytarray.length < pos) - throw new java.lang.IndexOutOfBoundsException(); - - // Determine the byte ordering for this platform, and restore the short - - int sVal = 0; - - if (bigEndian == true) - { - - // Big endian - - sVal = ((((int) bytarray[pos + 1]) << 8) + ((int) bytarray[pos] & 0xFF)); - } - else - { - - // Little endian - - sVal = ((((int) bytarray[pos]) << 8) + ((int) bytarray[pos + 1] & 0xFF)); - } - - // Return the short value - - return sVal & 0xFFFF; - } - - /** - * Unpack a null terminated string from the data buffer. - * - * @param bytarray Byte array to unpack the string value from. - * @param pos Offset to start unpacking the string value. - * @param maxlen Maximum length of data to be searched for a null character. - * @return String, else null if the terminating null character was not found. - */ - public final static String getString(byte[] bytarray, int pos, int maxlen) - { - - // Search for the trailing null - - int maxpos = pos + maxlen; - int endpos = pos; - - while (bytarray[endpos] != 0x00 && endpos < maxpos) - endpos++; - - // Check if we reached the end of the buffer - - if (endpos <= maxpos) - return new String(bytarray, pos, endpos - pos); - return null; - } - - /** - * Unpack a null terminated string from the data buffer. The string may be ASCII or Unicode. - * - * @param bytarray Byte array to unpack the string value from. - * @param pos Offset to start unpacking the string value. - * @param maxlen Maximum length of data to be searched for a null character. - * @param isUni Unicode string if true, else ASCII string - * @return String, else null if the terminating null character was not found. - */ - public final static String getString(byte[] bytarray, int pos, int maxlen, boolean isUni) - { - - // Get a string from the buffer - - String str = null; - - if (isUni) - str = getUnicodeString(bytarray, pos, maxlen); - else - str = getString(bytarray, pos, maxlen); - - // return the string - - return str; - } - - /** - * Unpack a null terminated Unicode string from the data buffer. - * - * @param byt Byte array to unpack the string value from. - * @param pos Offset to start unpacking the string value. - * @param maxlen Maximum length of data to be searched for a null character. - * @return String, else null if the terminating null character was not found. - */ - public final static String getUnicodeString(byte[] byt, int pos, int maxlen) - { - - // Check for an empty string - - if (maxlen == 0) - return ""; - - // Search for the trailing null - - int maxpos = pos + (maxlen * 2); - int endpos = pos; - char[] chars = new char[maxlen]; - int cpos = 0; - char curChar; - - do - { - - // Get a Unicode character from the buffer - - curChar = (char) (((byt[endpos + 1] & 0xFF) << 8) + (byt[endpos] & 0xFF)); - - // Add the character to the array - - chars[cpos++] = curChar; - - // Update the buffer pointer - - endpos += 2; - - } while (curChar != 0 && endpos < maxpos); - - // Check if we reached the end of the buffer - - if (endpos <= maxpos) - { - if (curChar == 0) - cpos--; - return new String(chars, 0, cpos); - } - return null; - } - - /** - * Pack a 32-bit integer into the supplied byte buffer. - * - * @param val Integer value to be packed. - * @param bytarray Byte buffer to pack the integer value into. - * @param pos Offset to start packing the integer value. - * @exception java.lang.IndexOutOfBoundsException If the buffer does not have enough space. - */ - public final static void putInt(int val, byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the int - - if (bytarray.length < pos + 3) - throw new java.lang.IndexOutOfBoundsException(); - - // Pack the integer value - - bytarray[pos] = (byte) ((val >> 24) & 0xFF); - bytarray[pos + 1] = (byte) ((val >> 16) & 0xFF); - bytarray[pos + 2] = (byte) ((val >> 8) & 0xFF); - bytarray[pos + 3] = (byte) (val & 0xFF); - } - - /** - * Pack an 32-bit integer value in Intel format. - * - * @param val Integer value to be packed. - * @param bytarray Byte array to pack the value into. - * @param pos Offset to start packing the integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putIntelInt(int val, byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the int - - if (bytarray.length < pos + 3) - throw new java.lang.IndexOutOfBoundsException(); - - // Store the int value in the byte array - - bytarray[pos + 3] = (byte) ((val >> 24) & 0xFF); - bytarray[pos + 2] = (byte) ((val >> 16) & 0xFF); - bytarray[pos + 1] = (byte) ((val >> 8) & 0xFF); - bytarray[pos] = (byte) (val & 0xFF); - } - - /** - * Pack a 64-bit integer value into the buffer - * - * @param val Integer value to be packed. - * @param bytarray Byte array to pack the value into. - * @param pos Offset to start packing the integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putLong(long val, byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the int - - if (bytarray.length < pos + 7) - throw new java.lang.IndexOutOfBoundsException(); - - // Store the long value in the byte array - - bytarray[pos] = (byte) ((val >> 56) & 0xFF); - bytarray[pos + 1] = (byte) ((val >> 48) & 0xFF); - bytarray[pos + 2] = (byte) ((val >> 40) & 0xFF); - bytarray[pos + 3] = (byte) ((val >> 32) & 0xFF); - bytarray[pos + 4] = (byte) ((val >> 24) & 0xFF); - bytarray[pos + 5] = (byte) ((val >> 16) & 0xFF); - bytarray[pos + 6] = (byte) ((val >> 8) & 0xFF); - bytarray[pos + 7] = (byte) (val & 0xFF); - } - - /** - * Pack a 64-bit integer value in Intel format. - * - * @param val Integer value to be packed. - * @param bytarray Byte array to pack the value into. - * @param pos Offset to start packing the integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putIntelLong(long val, byte[] bytarray, int pos) - throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the int - - if (bytarray.length < pos + 7) - throw new java.lang.IndexOutOfBoundsException(); - - // Store the long value in the byte array - - bytarray[pos + 7] = (byte) ((val >> 56) & 0xFF); - bytarray[pos + 6] = (byte) ((val >> 48) & 0xFF); - bytarray[pos + 5] = (byte) ((val >> 40) & 0xFF); - bytarray[pos + 4] = (byte) ((val >> 32) & 0xFF); - bytarray[pos + 3] = (byte) ((val >> 24) & 0xFF); - bytarray[pos + 2] = (byte) ((val >> 16) & 0xFF); - bytarray[pos + 1] = (byte) ((val >> 8) & 0xFF); - bytarray[pos] = (byte) (val & 0xFF); - } - - /** - * Pack a 64-bit integer value in Intel format. - * - * @param val Integer value to be packed. - * @param bytarray Byte array to pack the value into. - * @param pos Offset to start packing the integer value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putIntelLong(int val, byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the int - - if (bytarray.length < pos + 7) - throw new java.lang.IndexOutOfBoundsException(); - - // Store the int value in the byte array - - bytarray[pos + 7] = (byte) 0; - bytarray[pos + 6] = (byte) 0; - bytarray[pos + 5] = (byte) 0; - bytarray[pos + 4] = (byte) 0; - bytarray[pos + 3] = (byte) ((val >> 24) & 0xFF); - bytarray[pos + 2] = (byte) ((val >> 16) & 0xFF); - bytarray[pos + 1] = (byte) ((val >> 8) & 0xFF); - bytarray[pos] = (byte) (val & 0xFF); - } - - /** - * Pack a 16 bit value in Intel byte order. - * - * @param val Short value to be packed. - * @param bytarray Byte array to pack the short value into. - * @param pos Offset to start packing the short value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putIntelShort(int val, byte[] bytarray, int pos) - throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the short - - if (bytarray.length < pos) - throw new java.lang.IndexOutOfBoundsException(); - - // Pack the short value - - bytarray[pos + 1] = (byte) ((val >> 8) & 0xFF); - bytarray[pos] = (byte) (val & 0xFF); - } - - /** - * Pack a 16-bit value into the supplied byte buffer. - * - * @param val Short value to be packed. - * @param bytarray Byte array to pack the short value into. - * @param pos Offset to start packing the short value. - * @exception java.lang.IndexOutOfBoundsException If there is not enough data in the buffer. - */ - public final static void putShort(int val, byte[] bytarray, int pos) throws java.lang.IndexOutOfBoundsException - { - - // Check if the byte array is long enough to store the short - - if (bytarray.length < pos) - throw new java.lang.IndexOutOfBoundsException(); - - // Pack the short value - - bytarray[pos] = (byte) ((val >> 8) & 0xFF); - bytarray[pos + 1] = (byte) (val & 0xFF); - } - - /** - * Pack a string into a data buffer - * - * @param str String to be packed into the buffer - * @param bytarray Byte array to pack the string into - * @param pos Position to start packing the string - * @param nullterm true if the string should be null terminated, else false - * @return The ending buffer position - */ - public final static int putString(String str, byte[] bytarray, int pos, boolean nullterm) - { - - // Get the string as a byte array - - byte[] byts = str.getBytes(); - - // Pack the data bytes - - int bufpos = pos; - - for (int i = 0; i < byts.length; i++) - bytarray[bufpos++] = byts[i]; - - // Null terminate the string, if required - - if (nullterm == true) - bytarray[bufpos++] = 0; - - // Return the next free buffer position - - return bufpos; - } - - /** - * Pack a string into a data buffer - * - * @param str String to be packed into the buffer - * @param fldLen Field length, will be space padded if short - * @param bytarray Byte array to pack the string into - * @param pos Position to start packing the string - * @return The ending buffer position - */ - public final static int putString(String str, int fldLen, byte[] bytarray, int pos) - { - - // Get the string as a byte array - - byte[] byts = str.getBytes(); - - // Pack the data bytes - - int bufpos = pos; - int idx = 0; - - while (idx < fldLen) - { - if (idx < byts.length) - bytarray[bufpos++] = byts[idx]; - else - bytarray[bufpos++] = (byte) 0; - idx++; - } - - // Return the next free buffer position - - return bufpos; - } - - /** - * Pack a string into a data buffer. The string may be ASCII or Unicode. - * - * @param str String to be packed into the buffer - * @param bytarray Byte array to pack the string into - * @param pos Position to start packing the string - * @param nullterm true if the string should be null terminated, else false - * @param isUni true if the string should be packed as Unicode, false to pack as ASCII - * @return The ending buffer position - */ - public final static int putString(String str, byte[] bytarray, int pos, boolean nullterm, boolean isUni) - { - - // Pack the string - - int newpos = -1; - - if (isUni) - newpos = putUnicodeString(str, bytarray, pos, nullterm); - else - newpos = putString(str, bytarray, pos, nullterm); - - // Return the end of string buffer position - - return newpos; - } - - /** - * Pack a Unicode string into a data buffer - * - * @param str String to be packed into the buffer - * @param bytarray Byte array to pack the string into - * @param pos Position to start packing the string - * @param nullterm true if the string should be null terminated, else false - * @return The ending buffer position - */ - public final static int putUnicodeString(String str, byte[] bytarray, int pos, boolean nullterm) - { - - // Pack the data bytes - - int bufpos = pos; - - for (int i = 0; i < str.length(); i++) - { - - // Get the current character from the string - - char ch = str.charAt(i); - - // Pack the unicode character - - bytarray[bufpos++] = (byte) (ch & 0xFF); - bytarray[bufpos++] = (byte) ((ch & 0xFF00) >> 8); - } - - // Null terminate the string, if required - - if (nullterm == true) - { - bytarray[bufpos++] = 0; - bytarray[bufpos++] = 0; - } - - // Return the next free buffer position - - return bufpos; - } - - /** - * Pack nulls into the buffer. - * - * @param buf Buffer to pack data into. - * @param pos Position to start packing. - * @param cnt Number of nulls to pack. - * @exception java.lang.ArrayIndexOutOfBoundsException If the buffer does not have enough space. - */ - public final static void putZeros(byte[] buf, int pos, int cnt) throws java.lang.ArrayIndexOutOfBoundsException - { - - // Check if the buffer is big enough - - if (buf.length < (pos + cnt)) - throw new java.lang.ArrayIndexOutOfBoundsException(); - - // Pack the nulls - - for (int i = 0; i < cnt; i++) - buf[pos + i] = 0; - } - - /** - * Align a buffer offset on a word boundary - * - * @param pos int - * @return int - */ - public final static int wordAlign(int pos) - { - return (pos + 1) & 0xFFFFFFFE; - } - - /** - * Align a buffer offset on a longword boundary - * - * @param pos int - * @return int - */ - public final static int longwordAlign(int pos) - { - return (pos + 3) & 0xFFFFFFFC; - } - - /** - * Calculate the string length in bytes - * - * @param str String - * @param uni boolean - * @param nul boolean - * @return int - */ - public final static int getStringLength(String str, boolean uni, boolean nul) - { - - // Calculate the string length in bytes - - int len = str.length(); - if (nul) - len += 1; - if (uni) - len *= 2; - - return len; - } - - /** - * Calculate the new buffer position after the specified string and encoding (ASCII or Unicode) - * - * @param pos int - * @param str String - * @param uni boolean - * @param nul boolean - * @return int - */ - public final static int getBufferPosition(int pos, String str, boolean uni, boolean nul) - { - - // Calculate the new buffer position - - int len = str.length(); - if (nul) - len += 1; - if (uni) - len *= 2; - - return pos + len; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/util/HexDump.java b/source/java/org/alfresco/filesys/util/HexDump.java deleted file mode 100644 index fb4b74af4f..0000000000 --- a/source/java/org/alfresco/filesys/util/HexDump.java +++ /dev/null @@ -1,277 +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.util; - -import java.io.PrintStream; - -/** - * Hex dump class. - */ -public final class HexDump -{ - - /** - * Hex dump a byte array - * - * @param byt Byte array to dump - */ - public static final void Dump(byte[] byt) - { - Dump(byt, byt.length, 0, System.out); - } - - /** - * Hex dump a byte array - * - * @param byt Byte array to dump - * @param len Length of data to dump - * @param offset Offset to start data dump - */ - public static final void Dump(byte[] byt, int len, int offset) - { - Dump(byt, len, offset, System.out); - } - - /** - * Hex dump a byte array - * - * @param byt Byte array to dump - * @param len Length of data to dump - * @param offset Offset to start data dump - * @param stream Output stream to dump the output to. - */ - - public static final void Dump(byte[] byt, int len, int offset, PrintStream stream) - { - - // Create buffers for the ASCII and Hex output - - StringBuilder ascBuf = new StringBuilder(); - StringBuilder hexBuf = new StringBuilder(); - - // Dump 16 byte blocks from the array until the length has been - // reached - - int dlen = 0; - int doff = offset; - String posStr = null; - - while (dlen < len) - { - - // Reset the ASCII/Hex buffers - - ascBuf.setLength(0); - hexBuf.setLength(0); - - posStr = generatePositionString(doff); - - // Dump a block of data, update the data offset - - doff = generateLine(byt, doff, ascBuf, hexBuf); - - // Output the current record - - stream.print(posStr); - stream.print(hexBuf.toString()); - stream.println(ascBuf.toString()); - - // Update the dump length - - dlen += 16; - } - } - - /** - * Generate a hex string for the specified string - * - * @param str String - * @return String - */ - public static final String hexString(String str) - { - if (str != null) - return hexString(str.getBytes()); - return ""; - } - - /** - * Generate a hex string for the specified string - * - * @param str String - * @param gap String - * @return String - */ - public static final String hexString(String str, String gap) - { - if (str != null) - return hexString(str.getBytes(), gap); - return ""; - } - - /** - * Generate a hex string for the specified bytes - * - * @param buf byte[] - * @return String - */ - public static final String hexString(byte[] buf) - { - return hexString(buf, 0, buf.length, null); - } - - /** - * Generate a hex string for the specified bytes - * - * @param buf byte[] - * @param gap String - * @return String - */ - public static final String hexString(byte[] buf, String gap) - { - return hexString(buf, 0, buf.length, gap); - } - - /** - * Generate a hex string for the specified bytes - * - * @param buf byte[] - * @param off int - * @param len int - * @param gap String - * @return String - */ - public static final String hexString(byte[] buf, int off, int len, String gap) - { - - // Check if the buffer is valid - - if (buf == null) - return ""; - - // Create a string buffer for the hex string - - int buflen = (buf.length - off) * 2; - if (gap != null) - buflen += buf.length * gap.length(); - - StringBuilder hex = new StringBuilder(buflen); - - // Convert the bytes to hex-ASCII - - for (int i = 0; i < len; i++) - { - - // Get the current byte - - int curbyt = (int) (buf[off + i] & 0x00FF); - - // Output the hex string - - hex.append(Integer.toHexString((curbyt & 0xF0) >> 4)); - hex.append(Integer.toHexString(curbyt & 0x0F)); - - // Add the gap string, if specified - - if (gap != null && i < (len - 1)) - hex.append(gap); - } - - // Return the hex-ASCII string - - return hex.toString(); - } - - /** - * Generate a buffer position string - * - * @param off int - * @return String - */ - private static final String generatePositionString(int off) - { - - // Create a buffer position string - - StringBuilder posStr = new StringBuilder("" + off + " - "); - while (posStr.length() < 8) - posStr.insert(0, " "); - - // Return the string - - return posStr.toString(); - } - - /** - * Output a single line of the hex dump to a debug device - * - * @param byt Byte array to dump - * @param off Offset to start data dump - * @param ascBuf Buffer for ASCII output - * @param hexBuf Buffer for Hex output - * @return New offset value - */ - - private static final int generateLine(byte[] byt, int off, StringBuilder ascBuf, StringBuilder hexBuf) - { - - // Check if there is enough buffer space to dump 16 bytes - - int dumplen = byt.length - off; - if (dumplen > 16) - dumplen = 16; - - // Dump a 16 byte block of data - - for (int i = 0; i < dumplen; i++) - { - - // Get the current byte - - int curbyt = (int) (byt[off++] & 0x00FF); - - // Output the hex string - - hexBuf.append(Integer.toHexString((curbyt & 0xF0) >> 4)); - hexBuf.append(Integer.toHexString(curbyt & 0x0F)); - hexBuf.append(" "); - - // Output the character equivalent, if printable - - if (Character.isLetterOrDigit((char) curbyt) || Character.getType((char) curbyt) != Character.CONTROL) - ascBuf.append((char) curbyt); - else - ascBuf.append("."); - } - - // Output the hex dump line - - hexBuf.append(" - "); - - // Return the new data offset - - return off; - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/util/IPAddress.java b/source/java/org/alfresco/filesys/util/IPAddress.java deleted file mode 100644 index a9fe2faf7f..0000000000 --- a/source/java/org/alfresco/filesys/util/IPAddress.java +++ /dev/null @@ -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.util; - -import java.net.InetAddress; -import java.util.StringTokenizer; - -/** - * TCP/IP Address Utility Class - */ -public class IPAddress -{ - - /** - * Check if the specified address is a valid numeric TCP/IP address - * - * @param ipaddr String - * @return boolean - */ - public final static boolean isNumericAddress(String ipaddr) - { - - // Check if the string is valid - - if (ipaddr == null || ipaddr.length() < 7 || ipaddr.length() > 15) - return false; - - // Check the address string, should be n.n.n.n format - - StringTokenizer token = new StringTokenizer(ipaddr, "."); - if (token.countTokens() != 4) - return false; - - while (token.hasMoreTokens()) - { - - // Get the current token and convert to an integer value - - String ipNum = token.nextToken(); - - try - { - int ipVal = Integer.valueOf(ipNum).intValue(); - if (ipVal < 0 || ipVal > 255) - return false; - } - catch (NumberFormatException ex) - { - return false; - } - } - - // Looks like a valid IP address - - return true; - } - - /** - * Check if the specified address is a valid numeric TCP/IP address and return as an integer - * value - * - * @param ipaddr String - * @return int - */ - public final static int parseNumericAddress(String ipaddr) - { - - // Check if the string is valid - - if (ipaddr == null || ipaddr.length() < 7 || ipaddr.length() > 15) - return 0; - - // Check the address string, should be n.n.n.n format - - StringTokenizer token = new StringTokenizer(ipaddr, "."); - if (token.countTokens() != 4) - return 0; - - int ipInt = 0; - - while (token.hasMoreTokens()) - { - - // Get the current token and convert to an integer value - - String ipNum = token.nextToken(); - - try - { - - // Validate the current address part - - int ipVal = Integer.valueOf(ipNum).intValue(); - if (ipVal < 0 || ipVal > 255) - return 0; - - // Add to the integer address - - ipInt = (ipInt << 8) + ipVal; - } - catch (NumberFormatException ex) - { - return 0; - } - } - - // Return the integer address - - return ipInt; - } - - /** - * Convert an IP address into an integer value - * - * @param ipaddr InetAddress - * @return int - */ - public final static int asInteger(InetAddress ipaddr) - { - - // Get the address as an array of bytes - - byte[] addrBytes = ipaddr.getAddress(); - - // Build an integer value from the bytes - - return DataPacker.getInt(addrBytes, 0); - } - - /** - * Check if the specified address is within the required subnet - * - * @param ipaddr String - * @param subnet String - * @param mask String - * @return boolean - */ - public final static boolean isInSubnet(String ipaddr, String subnet, String mask) - { - - // Convert the addresses to integer values - - int ipaddrInt = parseNumericAddress(ipaddr); - if (ipaddrInt == 0) - return false; - - int subnetInt = parseNumericAddress(subnet); - if (subnetInt == 0) - return false; - - int maskInt = parseNumericAddress(mask); - if (maskInt == 0) - return false; - - // Check if the address is part of the subnet - - if ((ipaddrInt & maskInt) == subnetInt) - return true; - return false; - } - - /** - * Convert a raw IP address array as a String - * - * @param ipaddr int - * @return String - */ - public final static String asString(int ipaddr) - { - byte[] ipbyts = new byte[4]; - ipbyts[0] = (byte) ((ipaddr >> 24) & 0xFF); - ipbyts[1] = (byte) ((ipaddr >> 16) & 0xFF); - ipbyts[2] = (byte) ((ipaddr >> 8) & 0xFF); - ipbyts[3] = (byte) (ipaddr & 0xFF); - - return asString( ipbyts); - } - - /** - * Convert a raw IP address array as a String - * - * @param ipaddr byte[] - * @return String - */ - public final static String asString(byte[] ipaddr) - { - - // Check if the address is valid - - if (ipaddr == null || ipaddr.length != 4) - return null; - - // Convert the raw IP address to a string - - StringBuffer str = new StringBuffer(); - - str.append((int) (ipaddr[0] & 0xFF)); - str.append("."); - str.append((int) (ipaddr[1] & 0xFF)); - str.append("."); - str.append((int) (ipaddr[2] & 0xFF)); - str.append("."); - str.append((int) (ipaddr[3] & 0xFF)); - - // Return the address string - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/util/MemorySize.java b/source/java/org/alfresco/filesys/util/MemorySize.java deleted file mode 100644 index a4d760d8eb..0000000000 --- a/source/java/org/alfresco/filesys/util/MemorySize.java +++ /dev/null @@ -1,222 +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.util; - -/** - * Memory Size Class - *

- * Convenience class to convert memory size value specified as 'nK' for kilobytes, 'nM' for - * megabytes and 'nG' for gigabytes, to an absolute value. - */ -public class MemorySize -{ - // Convertor constants - - public static final long KILOBYTE = 1024L; - public static final long MEGABYTE = 1024L * KILOBYTE; - public static final long GIGABYTE = 1024L * MEGABYTE; - public static final long TERABYTE = 1024L * GIGABYTE; - - /** - * Convert a memory size to an integer byte value. - * - * @param memSize String - * @return int - * @exception NumberFormatException - */ - public static final int getByteValueInt(String memSize) - { - return (int) (getByteValue(memSize) & 0xFFFFFFFFL); - } - - /** - * Convert a memory size to a byte value - * - * @param memSize String - * @return long - * @exception NumberFormatException - */ - public static final long getByteValue(String memSize) - { - - // Check if the string is valid - - if (memSize == null || memSize.length() == 0) - return -1L; - - // Check for a kilobyte value - - String sizeStr = memSize.toUpperCase(); - long mult = 1; - long val = 0; - - if (sizeStr.endsWith("K")) - { - - // Use the kilobyte multiplier - - mult = KILOBYTE; - val = getValue(sizeStr); - } - else if (sizeStr.endsWith("M")) - { - - // Use the megabyte nultiplier - - mult = MEGABYTE; - val = getValue(sizeStr); - } - else if (sizeStr.endsWith("G")) - { - - // Use the gigabyte multiplier - - mult = GIGABYTE; - val = getValue(sizeStr); - } - else if (sizeStr.endsWith("T")) - { - - // Use the terabyte multiplier - - mult = TERABYTE; - val = getValue(sizeStr); - } - else - { - - // Convert a numeric byte value - - val = Long.valueOf(sizeStr).longValue(); - } - - // Apply the multiplier - - return val * mult; - } - - /** - * Get the size value from a string and return the numeric value - * - * @param val String - * @return long - * @exception NumberFormatException - */ - private final static long getValue(String val) - { - - // Strip the trailing size indicator - - String sizStr = val.substring(0, val.length() - 1); - return Long.valueOf(sizStr).longValue(); - } - - /** - * Return a byte value as a kilobyte string - * - * @param val long - * @return String - */ - public final static String asKilobyteString(long val) - { - - // Calculate the kilobyte value - - long mbVal = val / KILOBYTE; - return "" + mbVal + "Kb"; - } - - /** - * Return a byte value as a megabyte string - * - * @param val long - * @return String - */ - public final static String asMegabyteString(long val) - { - - // Calculate the megabyte value - - long mbVal = val / MEGABYTE; - return "" + mbVal + "Mb"; - } - - /** - * Return a byte value as a gigabyte string - * - * @param val long - * @return String - */ - public final static String asGigabyteString(long val) - { - - // Calculate the gigabyte value - - long mbVal = val / GIGABYTE; - return "" + mbVal + "Gb"; - } - - /** - * Return a byte value as a terabyte string - * - * @param val long - * @return String - */ - public final static String asTerabyteString(long val) - { - - // Calculate the terabyte value - - long mbVal = val / TERABYTE; - return "" + mbVal + "Tb"; - } - - /** - * Return a byte value as a scaled string - * - * @param val long - * @return String - */ - public final static String asScaledString(long val) - { - - // Determine the scaling to apply - - String ret = null; - - if (val < (KILOBYTE * 2L)) - ret = Long.toString(val); - else if (val < (MEGABYTE * 2L)) - ret = asKilobyteString(val); - else if (val < (GIGABYTE * 2L)) - ret = asMegabyteString(val); - else if (val < (TERABYTE * 2L)) - ret = asGigabyteString(val); - else - ret = asTerabyteString(val); - - return ret; - } -} diff --git a/source/java/org/alfresco/filesys/util/Platform.java b/source/java/org/alfresco/filesys/util/Platform.java deleted file mode 100644 index 124093994c..0000000000 --- a/source/java/org/alfresco/filesys/util/Platform.java +++ /dev/null @@ -1,74 +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.util; - -/** - * Platform Class - * - *

Determine the platform type that we are runnng on. - * - * @author gkspencer - */ -public class Platform { - - // Platform types - - public enum Type - { - Unchecked, Unknown, WINDOWS, LINUX, SOLARIS, MACOSX - }; - - // Platform type we are running on - - private static Type _platformType = Type.Unchecked; - - /** - * Determine the platform type - * - * @return Type - */ - public static final Type isPlatformType() - { - // Check if the type has been set - - if ( _platformType == Type.Unchecked) - { - // Get the operating system type - - String osName = System.getProperty("os.name"); - - if (osName.startsWith("Windows")) - _platformType = Type.WINDOWS; - else if (osName.equalsIgnoreCase("Linux")) - _platformType = Type.LINUX; - else if (osName.startsWith("Mac OS X")) - _platformType = Type.MACOSX; - else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) - _platformType = Type.SOLARIS; - } - - // Return the current platform type - - return _platformType; - } -} diff --git a/source/java/org/alfresco/filesys/util/StringList.java b/source/java/org/alfresco/filesys/util/StringList.java deleted file mode 100644 index 4d5caf095e..0000000000 --- a/source/java/org/alfresco/filesys/util/StringList.java +++ /dev/null @@ -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.util; - -import java.util.Vector; - -/** - * String List Class - */ -public class StringList -{ - - // List of strings - - private Vector m_list; - - /** - * Default constructor - */ - public StringList() - { - m_list = new Vector(); - } - - /** - * Return the number of strings in the list - * - * @return int - */ - public final int numberOfStrings() - { - return m_list.size(); - } - - /** - * Add a string to the list - * - * @param str String - */ - public final void addString(String str) - { - m_list.add(str); - } - - /** - * Add a list of strings to this list - * - * @param list StringList - */ - public final void addStrings(StringList list) - { - if (list != null && list.numberOfStrings() > 0) - for (int i = 0; i < list.numberOfStrings(); m_list.add(list.getStringAt(i++))) - ; - } - - /** - * Return the string at the specified index - * - * @param idx int - * @return String - */ - public final String getStringAt(int idx) - { - if (idx < 0 || idx >= m_list.size()) - return null; - return (String) m_list.elementAt(idx); - } - - /** - * Check if the list contains the specified string - * - * @param str String - * @return boolean - */ - public final boolean containsString(String str) - { - return m_list.contains(str); - } - - /** - * Return the index of the specified string, or -1 if not in the list - * - * @param str String - * @return int - */ - public final int findString(String str) - { - return m_list.indexOf(str); - } - - /** - * Remove the specified string from the list - * - * @param str String - * @return boolean - */ - public final boolean removeString(String str) - { - return m_list.removeElement(str); - } - - /** - * Remove the string at the specified index within the list - * - * @param idx int - * @return String - */ - public final String removeStringAt(int idx) - { - if (idx < 0 || idx >= m_list.size()) - return null; - String ret = (String) m_list.elementAt(idx); - m_list.removeElementAt(idx); - return ret; - } - - /** - * Clear the strings from the list - */ - public final void remoteAllStrings() - { - m_list.removeAllElements(); - } - - /** - * Return the string list as a string - * - * @return String - */ - public String toString() - { - - // Check if the list is empty - - if (numberOfStrings() == 0) - return ""; - - // Build the string - - StringBuffer str = new StringBuffer(); - - for (int i = 0; i < m_list.size(); i++) - { - str.append(getStringAt(i)); - str.append(","); - } - - // Remove the trailing comma - - if (str.length() > 0) - str.setLength(str.length() - 1); - - // Return the string - - return str.toString(); - } -} diff --git a/source/java/org/alfresco/filesys/util/WildCard.java b/source/java/org/alfresco/filesys/util/WildCard.java deleted file mode 100644 index 205cc32da4..0000000000 --- a/source/java/org/alfresco/filesys/util/WildCard.java +++ /dev/null @@ -1,648 +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.util; - -/** - * Wildcard Utility Class. - *

- * The WildCard class may be used to check Strings against a wildcard pattern using the SMB/CIFS - * wildcard rules. - *

- * A number of static convenience methods are also provided. - * - * @author GKSpencer - */ -public final class WildCard -{ - - // Multiple character wildcard - - public static final int MULTICHAR_WILDCARD = '*'; - - // Single character wildcard - - public static final int SINGLECHAR_WILDCARD = '?'; - - // Unicode wildcards - // - // The spec states :- - // translate '?' to '>' - // translate '.' to '"' if followed by a '?' or '*' - // translate '*' to '<' if followed by a '.' - - public static final int SINGLECHAR_UNICODE_WILDCARD = '>'; - public static final int DOT_UNICODE_WILDCARD = '"'; - public static final int MULTICHAR_UNICODE_WILDCARD = '<'; - - // Wildcard types - - public static final int WILDCARD_NONE = 0; // no wildcard characters present in pattern - public static final int WILDCARD_ALL = 1; // '*.*' and '*' - public static final int WILDCARD_NAME = 2; // '*.ext' - public static final int WILDCARD_EXT = 3; // 'name.*' - public static final int WILDCARD_COMPLEX = 4; // complex wildcard - - public static final int WILDCARD_INVALID = -1; - - // Wildcard pattern and type - - private String m_pattern; - private int m_type; - - // Start/end string to match for name/extension matching - - private String m_matchPart; - private boolean m_caseSensitive; - - // Complex wildcard pattern - - private char[] m_patternChars; - - /** - * Default constructor - */ - public WildCard() - { - setType(WILDCARD_INVALID); - } - - /** - * Class constructor - * - * @param pattern String - * @param caseSensitive boolean - */ - public WildCard(String pattern, boolean caseSensitive) - { - setPattern(pattern, caseSensitive); - } - - /** - * Return the wildcard pattern type - * - * @return int - */ - public final int isType() - { - return m_type; - } - - /** - * Check if case sensitive matching is enabled - * - * @return boolean - */ - public final boolean isCaseSensitive() - { - return m_caseSensitive; - } - - /** - * Return the wildcard pattern string - * - * @return String - */ - public final String getPattern() - { - return m_pattern; - } - - /** - * Return the match part for wildcard name and wildcard extension type patterns - * - * @return String - */ - public final String getMatchPart() - { - return m_matchPart; - } - - /** - * Determine if the string matches the wildcard pattern - * - * @param str String - * @return boolean - */ - public final boolean matchesPattern(String str) - { - - // Check the pattern type and compare the string - - boolean sts = false; - - switch (isType()) - { - - // Match all wildcard - - case WILDCARD_ALL: - sts = true; - break; - - // Match any name - - case WILDCARD_NAME: - if (isCaseSensitive()) - { - - // Check if the string ends with the required file extension - - sts = str.endsWith(m_matchPart); - } - else - { - - // Normalize the string and compare - - String upStr = str.toUpperCase(); - sts = upStr.endsWith(m_matchPart); - } - break; - - // Match any file extension - - case WILDCARD_EXT: - if (isCaseSensitive()) - { - - // Check if the string starts with the required file name - - sts = str.startsWith(m_matchPart); - } - else - { - - // Normalize the string and compare - - String upStr = str.toUpperCase(); - sts = upStr.startsWith(m_matchPart); - } - break; - - // Complex wildcard matching - - case WILDCARD_COMPLEX: - if (isCaseSensitive()) - sts = matchComplexWildcard(str); - else - { - - // Normalize the string and compare - - String upStr = str.toUpperCase(); - sts = matchComplexWildcard(upStr); - } - break; - - // No wildcard characters in pattern, compare strings - - case WILDCARD_NONE: - if (isCaseSensitive()) - { - if (str.compareTo(m_pattern) == 0) - sts = true; - } - else if (str.equalsIgnoreCase(m_pattern)) - sts = true; - break; - } - - // Return the wildcard match status - - return sts; - } - - /** - * Match a complex wildcard pattern with the specified string - * - * @param str String - * @return boolean - */ - protected final boolean matchComplexWildcard(String str) - { - - // Convert the string to a char array for matching - - char[] strChars = str.toCharArray(); - - // Compare the string to the wildcard pattern - - int wpos = 0; - int wlen = m_patternChars.length; - - int spos = 0; - int slen = strChars.length; - - char patChar; - boolean matchFailed = false; - - while (matchFailed == false && wpos < m_patternChars.length) - { - - // Match the current pattern character - - patChar = m_patternChars[wpos++]; - - switch (patChar) - { - - // Match single character - - case SINGLECHAR_WILDCARD: - if (spos < slen) - spos++; - else - matchFailed = true; - break; - - // Match zero or more characters - - case MULTICHAR_WILDCARD: - - // Check if there is another character in the wildcard pattern - - if (wpos < wlen) - { - - // Check if the character is not a wildcard character - - patChar = m_patternChars[wpos]; - if (patChar != SINGLECHAR_WILDCARD && patChar != MULTICHAR_WILDCARD) - { - - // Find the required character in the string - - while (spos < slen && strChars[spos] != patChar) - spos++; - if (spos >= slen) - matchFailed = true; - } - } - else - { - - // Multi character wildcard at the end of the pattern, match all remaining - // characters - - spos = slen; - } - break; - - // Match the pattern and string character - - default: - if (spos >= slen || strChars[spos] != patChar) - matchFailed = true; - else - spos++; - break; - } - } - - // Check if the match was successul and return status - - if (matchFailed == false && spos == slen) - return true; - return false; - } - - /** - * Set the wildcard pattern string - * - * @param pattern String - * @param caseSensitive boolean - */ - public final void setPattern(String pattern, boolean caseSensitive) - { - - // Save the pattern string and case sensitive flag - - m_pattern = pattern; - m_caseSensitive = caseSensitive; - - setType(WILDCARD_INVALID); - - // Check if the pattern string is valid - - if (pattern == null || pattern.length() == 0) - return; - - // Check for the match all wildcard - - if (pattern.compareTo("*.*") == 0 || pattern.compareTo("*") == 0) - { - setType(WILDCARD_ALL); - return; - } - - // Check for a name wildcard, ie. '*.ext' - - if (pattern.startsWith("*.")) - { - - // Split the string to get the extension string - - if (pattern.length() > 2) - m_matchPart = pattern.substring(1); - else - m_matchPart = ""; - - // If matching is case insensitive then normalize the string - - if (isCaseSensitive() == false) - m_matchPart = m_matchPart.toUpperCase(); - - // If the file extension contains wildcards we will need to use a regular expression - - if (containsWildcards(m_matchPart) == false) - { - setType(WILDCARD_NAME); - return; - } - } - - // Check for a file extension wildcard - - if (pattern.endsWith(".*")) - { - - // Split the string to get the name string - - if (pattern.length() > 2) - m_matchPart = pattern.substring(0, pattern.length() - 2); - else - m_matchPart = ""; - - // If matching is case insensitive then normalize the string - - if (isCaseSensitive() == false) - m_matchPart = m_matchPart.toUpperCase(); - - // If the file name contains wildcards we will need to use a regular expression - - if (containsWildcards(m_matchPart) == false) - { - setType(WILDCARD_EXT); - return; - } - } - - // Save the complex wildcard pattern as a char array for later pattern matching - - if (isCaseSensitive() == false) - m_patternChars = m_pattern.toUpperCase().toCharArray(); - else - m_patternChars = m_pattern.toCharArray(); - - setType(WILDCARD_COMPLEX); - } - - /** - * Set the wildcard type - * - * @param typ int - */ - private final void setType(int typ) - { - m_type = typ; - } - - /** - * Return the wildcard as a string - * - * @return String - */ - public String toString() - { - StringBuffer str = new StringBuffer(); - str.append("["); - str.append(getPattern()); - str.append(","); - str.append(isType()); - str.append(","); - - if (m_matchPart != null) - str.append(m_matchPart); - - if (isCaseSensitive()) - str.append(",Case"); - else - str.append(",NoCase"); - str.append("]"); - - return str.toString(); - } - - /** - * Check if the string contains any wildcard characters. - * - * @return boolean - * @param str java.lang.String - */ - public final static boolean containsWildcards(String str) - { - - // Check the string for wildcard characters - - if (str.indexOf(MULTICHAR_WILDCARD) != -1) - return true; - - if (str.indexOf(SINGLECHAR_WILDCARD) != -1) - return true; - - // No wildcards found in the string - - return false; - } - - /** - * Check if a string contains any of the Unicode wildcard characters - * - * @param str String - * @return boolean - */ - public final static boolean containsUnicodeWildcard(String str) - { - - // Check if the string contains any of the Unicode wildcards - - if (str.indexOf(SINGLECHAR_UNICODE_WILDCARD) != -1 || str.indexOf(MULTICHAR_UNICODE_WILDCARD) != -1 - || str.indexOf(DOT_UNICODE_WILDCARD) != -1) - return true; - return false; - } - - /** - * Convert the Unicode wildcard string to a standard DOS wildcard string - * - * @param str String - * @return String - */ - public final static String convertUnicodeWildcardToDOS(String str) - { - - // Create a buffer for the new wildcard string - - StringBuffer newStr = new StringBuffer(str.length()); - - // Convert the Unicode wildcard string to a DOS wildcard string - - for (int i = 0; i < str.length(); i++) - { - - // Get the current character - - char ch = str.charAt(i); - - // Check for a Unicode wildcard character - - if (ch == SINGLECHAR_UNICODE_WILDCARD) - { - - // Translate to the DOS single character wildcard character - - ch = SINGLECHAR_WILDCARD; - } - else if (ch == MULTICHAR_UNICODE_WILDCARD) - { - - // Check if the current character is followed by a '.', if so then translate to the - // DOS multi character - // wildcard - - if (i < (str.length() - 1) && str.charAt(i + 1) == '.') - ch = MULTICHAR_WILDCARD; - } - else if (ch == DOT_UNICODE_WILDCARD) - { - - // Check if the current character is followed by a DOS single/multi character - // wildcard - - if (i < (str.length() - 1)) - { - char nextCh = str.charAt(i + 1); - if (nextCh == SINGLECHAR_WILDCARD || nextCh == MULTICHAR_WILDCARD - || nextCh == SINGLECHAR_UNICODE_WILDCARD) - ch = '.'; - } - } - - // Append the character to the translated wildcard string - - newStr.append(ch); - } - - // Return the translated wildcard string - - return newStr.toString(); - } - - /** - * Convert a wildcard string to a regular expression - * - * @param path String - * @return String - */ - public final static String convertToRegexp(String path) - { - - // Convert the path to characters, check if the wildcard string ends with a single character - // wildcard - - char[] smbPattern = path.toCharArray(); - boolean endsWithQ = smbPattern[smbPattern.length - 1] == '?'; - - // Build up the regular expression - - StringBuffer sb = new StringBuffer(); - sb.append('^'); - - for (int i = 0; i < smbPattern.length; i++) - { - - // Process the current character - - switch (smbPattern[i]) - { - - // Multi character wildcard - - case '*': - sb.append(".*"); - break; - - // Single character wildcard - - case '?': - if (endsWithQ) - { - boolean restQ = true; - for (int j = i + 1; j < smbPattern.length; j++) - { - if (smbPattern[j] != '?') - { - restQ = false; - break; - } - } - if (restQ) - sb.append(".?"); - else - sb.append('.'); - } - else - sb.append('.'); - break; - - // Escape regular expression special characters - - case '.': - case '+': - case '\\': - case '[': - case ']': - case '^': - case '$': - case '(': - case ')': - sb.append('\\'); - sb.append(smbPattern[i]); - break; - - // Normal characters, just pass through - - default: - sb.append(smbPattern[i]); - break; - } - } - sb.append('$'); - - // Return the regular expression string - - return sb.toString(); - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/filesys/util/X64.java b/source/java/org/alfresco/filesys/util/X64.java deleted file mode 100644 index aa00c04301..0000000000 --- a/source/java/org/alfresco/filesys/util/X64.java +++ /dev/null @@ -1,72 +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.util; - -/** - * X64 Class - * - *

Check if the platform is a 64bit operating system. - * - * @author gkspencer - */ -public class X64 -{ - /** - * Check if we are running on a Windows 64bit system - * - * @return boolean - */ - public static boolean isWindows64() - { - // Check for Windows - - String prop = System.getProperty("os.name"); - if ( prop == null || prop.startsWith("Windows") == false) - return false; - - // Check the OS architecture - - prop = System.getProperty("os.arch"); - if ( prop != null && prop.equalsIgnoreCase("amd64")) - return true; - - // Check the VM name - - prop = System.getProperty("java.vm.name"); - if ( prop != null && prop.indexOf("64-Bit") != -1) - return true; - - // Check the data model - - prop = System.getProperty("sun.arch.data.model"); - if ( prop != null && prop.equals("64")) - return true; - - // Not 64 bit Windows - - return false; - } -} diff --git a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationComponentImpl.java b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationComponentImpl.java index 33863ab311..074135f8f6 100644 --- a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationComponentImpl.java +++ b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationComponentImpl.java @@ -44,11 +44,11 @@ import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.server.auth.PasswordEncryptor; -import org.alfresco.filesys.server.auth.passthru.AuthenticateSession; -import org.alfresco.filesys.server.auth.passthru.PassthruServers; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.SMBStatus; +import org.alfresco.jlan.server.auth.PasswordEncryptor; +import org.alfresco.jlan.server.auth.passthru.AuthenticateSession; +import org.alfresco.jlan.server.auth.passthru.PassthruServers; +import org.alfresco.jlan.smb.SMBException; +import org.alfresco.jlan.smb.SMBStatus; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationException; @@ -287,7 +287,14 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo // Configure the passthru authentication server list using the domain controllers - m_passthruServers.setDomain(domain); + try + { + m_passthruServers.setDomain(domain); + } + catch ( IOException ex) + { + throw new AlfrescoRuntimeException("Failed to set passthru domain, " + ex); + } } /** diff --git a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationProvider.java b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationProvider.java index acbab12683..974fe37224 100644 --- a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationProvider.java +++ b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMAuthenticationProvider.java @@ -35,11 +35,11 @@ import java.util.Enumeration; import java.util.Hashtable; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.filesys.server.auth.PasswordEncryptor; -import org.alfresco.filesys.server.auth.passthru.AuthenticateSession; -import org.alfresco.filesys.server.auth.passthru.PassthruServers; -import org.alfresco.filesys.smb.SMBException; -import org.alfresco.filesys.smb.SMBStatus; +import org.alfresco.jlan.server.auth.PasswordEncryptor; +import org.alfresco.jlan.server.auth.passthru.AuthenticateSession; +import org.alfresco.jlan.server.auth.passthru.PassthruServers; +import org.alfresco.jlan.smb.SMBException; +import org.alfresco.jlan.smb.SMBStatus; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -341,7 +341,14 @@ public class NTLMAuthenticationProvider implements AuthenticationProvider // Configure the passthru authentication server list using the domain controllers - m_passthruServers.setDomain(domain); + try + { + m_passthruServers.setDomain(domain); + } + catch (IOException ex) + { + throw new AlfrescoRuntimeException("Failed to set passthru domain", ex); + } } /** diff --git a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMChallenge.java b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMChallenge.java index 4816fa5b18..7992d0e670 100644 --- a/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMChallenge.java +++ b/source/java/org/alfresco/repo/security/authentication/ntlm/NTLMChallenge.java @@ -24,7 +24,7 @@ */ package org.alfresco.repo.security.authentication.ntlm; -import org.alfresco.filesys.util.HexDump; +import org.alfresco.jlan.util.HexDump; /** * Contains the NTLM challenge bytes.