diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 65e3bfddff..04c614f23a 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -82,6 +82,7 @@ + @@ -113,6 +114,10 @@ value="${alfresco.jmx.dir}/alfresco-jmxrmi.access"/> + + + diff --git a/source/java/org/alfresco/filesys/server/config/FileServerConfig.java b/source/java/org/alfresco/filesys/server/config/FileServerConfig.java new file mode 100644 index 0000000000..bc20a9be06 --- /dev/null +++ b/source/java/org/alfresco/filesys/server/config/FileServerConfig.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2005-2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.filesys.server.config; + +import org.alfresco.filesys.smb.TcpipSMB; +import org.alfresco.filesys.util.CifsMounter; +import org.alfresco.filesys.util.Platform; + +/** + * File Server Configuration MBean Class + * + *

Implements the file server configuration interface using the fileServerConfigurationBase bean + * from network-protocol-context.xml. + * + * @author gkspencer + */ +public class FileServerConfig implements FileServerConfigMBean { + + // File server configuration + + private ServerConfiguration m_serverConfig; + + /** + * Default constructor + */ + public FileServerConfig() + { + } + + /** + * Set the file server configuration + * + * @return ServerConfiguration + */ + public ServerConfiguration getFileServerConfiguration() + { + return m_serverConfig; + } + + /** + * Set the file server configuration + * + * @param serverConfig ServerConfiguration + */ + public void setFileServerConfiguration(ServerConfiguration serverConfig) + { + m_serverConfig = serverConfig; + } + + /** + * Check if the CIFS server is enabled + * + * @return boolean + */ + public boolean isCIFSServerEnabled() + { + return m_serverConfig.isSMBServerEnabled(); + } + + /** + * Check if the FTP server is enabled + * + * @return boolean + */ + public boolean isFTPServerEnabled() + { + return m_serverConfig.isFTPServerEnabled(); + } + + /** + * Check if the NFS server is enabled + * + * @return boolean + */ + public boolean isNFSServerEnabled() + { +// return m_serverConfig.isNFSServerEnabled(); + return false; + } + + /** + * Return the CIFS server name + * + * @return String + */ + public String getCIFSServerName() + { + return m_serverConfig.getServerName(); + } + + /** + * Return the CIFS server IP address + * + * @return String + */ + public String getCIFSServerAddress() + { + return null; + } + + /** + * Create a mounter to mount/unmount a share on the CIFS server + * + * @return CifsMounter + */ + public CifsMounter createMounter() { + + // Check if the CIFS server is enabled + + if ( isCIFSServerEnabled() == false) + return null; + + // Create the CIFS mounter + + CifsMounter cifsMounter = new CifsMounter(); + cifsMounter.setServerName( getCIFSServerName()); + + // Get the local platform type + + Platform.Type platform = Platform.isPlatformType(); + + // Figure out which CIFS sub-protocol to use to connect to the server + + if ( platform == Platform.Type.LINUX && m_serverConfig.hasTcpipSMB()) + { + // Connect using native SMB, this defaults to port 445 but may be running on a different port + + cifsMounter.setProtocolType( CifsMounter.NativeSMB); + + // Check if the native SMB server is listening on a non-standard port + + if ( m_serverConfig.getTcpipSMBPort() != TcpipSMB.PORT) + cifsMounter.setProtocolPort( m_serverConfig.getTcpipSMBPort()); + } + else + { + // Check if the server is using Win32 NetBIOS + + if ( m_serverConfig.hasWin32NetBIOS()) + cifsMounter.setProtocolType( CifsMounter.Win32NetBIOS); + else if ( m_serverConfig.hasNetBIOSSMB()) + cifsMounter.setProtocolType( CifsMounter.NetBIOS); + } + + // Return the CIFS mounter + + return cifsMounter; + } +} diff --git a/source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java b/source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java new file mode 100644 index 0000000000..36c7645560 --- /dev/null +++ b/source/java/org/alfresco/filesys/server/config/FileServerConfigMBean.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2005-2006 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.filesys.server.config; + +import org.alfresco.filesys.util.CifsMounter; + +/** + * File Server Configuration MBean Interface + * + *

Provides file server configuration details to remote virtualization servers. + * + * @author gkspencer + */ +public interface FileServerConfigMBean { + + /** + * Check if the CIFS server is enabled + * + * @return boolean + */ + public boolean isCIFSServerEnabled(); + + /** + * Check if the FTP server is enabled + * + * @return boolean + */ + public boolean isFTPServerEnabled(); + + /** + * Check if the NFS server is enabled + * + * @return boolean + */ + public boolean isNFSServerEnabled(); + + /** + * Return the CIFS server name + * + * @return String + */ + public String getCIFSServerName(); + + /** + * Return the CIFS server IP address + * + * @return String + */ + public String getCIFSServerAddress(); + + /** + * Create a mounter to mount/unmount a share on the CIFS server + * + * @return CifsMounter + */ + public CifsMounter createMounter(); +} diff --git a/source/java/org/alfresco/filesys/util/CifsMountException.java b/source/java/org/alfresco/filesys/util/CifsMountException.java new file mode 100644 index 0000000000..e09a77b84d --- /dev/null +++ b/source/java/org/alfresco/filesys/util/CifsMountException.java @@ -0,0 +1,102 @@ +/* + * 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.util; + +/** + * CIFS Mounter Exception Class + * + * @author gkspencer + */ +public class CifsMountException extends Exception { + + // Version id + + private static final long serialVersionUID = -6075644008134098583L; + + // Mount command exit code and standard output/error strings + + private int m_errorCode; + + private String m_outString; + private String m_errString; + + /** + * Class constructor + * + * @param exitCode int + * @param outStr String + * @param errStr String + */ + public CifsMountException( int exitCode, String outStr, String errStr) + { + super( errStr == null ? outStr : errStr); + + m_errorCode = exitCode; + + m_outString = outStr; + m_errString = errStr; + } + + /** + * Return the exception message string + * + * @return String + */ + @Override + public String getMessage() { + StringBuilder str = new StringBuilder(); + + str.append( "Mount exit code="); + str.append( getExitCode()); + str.append( ",Out="); + str.append( getOutputString()); + str.append( ",Err="); + str.append( getErrorString()); + + return str.toString(); + } + + /** + * Return the exit code + * + * @return int + */ + public final int getExitCode() + { + return m_errorCode; + } + + /** + * Return the output string + * + * @return String + */ + public final String getOutputString() + { + return m_outString; + } + + /** + * Return the error string + * + * @return String + */ + public final String getErrorString() + { + return m_errString; + } +} diff --git a/source/java/org/alfresco/filesys/util/CifsMounter.java b/source/java/org/alfresco/filesys/util/CifsMounter.java new file mode 100644 index 0000000000..d70fd64fd3 --- /dev/null +++ b/source/java/org/alfresco/filesys/util/CifsMounter.java @@ -0,0 +1,440 @@ +/* + * 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.util; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.util.exec.RuntimeExec; +import org.alfresco.util.exec.RuntimeExec.ExecutionResult; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * CIFS Mounter Class + * + *

Mount/map a network drive taking care of platform differences. + * + * @author gkspencer + */ +public class CifsMounter { + + // Debug logging + + private static final Log logger = LogFactory.getLog( CifsMounter.class); + + // Protocol type constants + + public static final int Default = 0; + public static final int NetBIOS = 1; + public static final int NativeSMB = 2; + public static final int Win32NetBIOS = 3; + + // Windows mount/unmount commands + + private static final String WindowsMountCmd = "net use ${drive} \\\\${srvname}\\${sharename} ${password} /USER:${username}"; + private static final String WindowsUnMountCmd = "net use ${drive} /d"; + + // Linux mount/unmount commands + + private static final String LinuxMountSmbfsCmd = "mount -t smbfs //${srvname}/${sharename} ${mountpoint} -o username=${username},password=${password}"; + private static final String LinuxMountCifsCmd = "mount -t cifs //${srvname}/${sharename} ${mountpoint} -o username=${username},password=${password}"; + private static final String LinuxUnMountCmd = "umount ${mountpoint}"; + + // Mac OS X mount/unmount commands + + private static final String MacOSXMountCmd = "mount_smbfs -U ${username} //${password}@${srvname}/${sharename} ${mountpoint}"; + private static final String MacOSXUnMountCmd = "umount ${mountpoint}"; + + // Server name and share name + + private String m_srvName; + private String m_shareName; + + // Access details for remote share + + private String m_userName; + private String m_password; + + // Protocol to use for connection (non Windows platforms) + + private int m_protocolType = Default; + + // Port to connect on (non Windows platforms) + + private int m_port; + + /** + * Default constructor + */ + public CifsMounter() + { + } + + /** + * Class constructor + * + * @param srvName String + * @param shareName String + * @param userName String + * @param password String + */ + public CifsMounter(String srvName, String shareName, String userName, String password) + { + setServerName( srvName); + setShareName( shareName); + + setUserName( userName); + setPassword( password); + } + + /** + * Mount a remote CIFS shared filesystem + * + * @param driveLetter String + * @param mountPoint String + * @exception CifsMountException + */ + public void mountFilesystem( String driveLetter, String mountPoint) + throws CifsMountException + { + // Create the command line launcher + + RuntimeExec exec = new RuntimeExec(); + + // Create the command map and properties + + Map commandMap = new HashMap( 1); + Map defProperties = new HashMap( 10); + + // Determine the platform type and build the appropriate command line string + + Platform.Type platform = Platform.isPlatformType(); + + switch ( platform) + { + // Windows + + case WINDOWS: + commandMap.put( "Windows.*", WindowsMountCmd); + break; + + // Linux + + case LINUX: + + // Check the protocol type of the CIFS server + + if ( isProtocolType() == NativeSMB || isProtocolType() == Default) + { + // Use the CIFS VFS mounter to connect using native SMB + + StringBuilder cmd = new StringBuilder( LinuxMountCifsCmd); + if ( getProtocolPort() != 0) + { + cmd.append( ",port="); + cmd.append( getProtocolPort()); + } + + // Set the command line + + commandMap.put( "Linux", cmd.toString()); + } + else + { + // Set the command line to use the older smbfs VFS mounter to connect using NetBIOS + + commandMap.put( "Linux", LinuxMountSmbfsCmd); + } + break; + + // Mac OS X + + case MACOSX: + commandMap.put( "Mac OS X", MacOSXMountCmd); + break; + } + + // Set the command map + + exec.setCommandMap( commandMap); + + // Build the command line properties list + + defProperties.put( "drive", driveLetter); + defProperties.put( "srvname", getServerName()); + defProperties.put( "sharename", getShareName()); + defProperties.put( "username", getUserName()); + defProperties.put( "password", getPassword()); + defProperties.put( "mountpoint", mountPoint); + + exec.setDefaultProperties(defProperties); + + // Get the command to be used on this platform + + if ( logger.isDebugEnabled()) + logger.debug( "Mount CIFS share, cmdLine=" + exec.getCommand()); + + // Run the command + + ExecutionResult execRes = exec.execute(); + + if ( logger.isDebugEnabled()) + logger.debug( "Mount result=" + execRes); + + // Check if the command was successful + + if ( execRes.getSuccess() == false) + throw new CifsMountException( execRes.getExitValue(), execRes.getStdOut(), execRes.getStdErr()); + } + + /** + * Unmount a remote CIFS shared filesystem + * + * @param driveLetter String + * @param mountPoint String + * @exception CifsMountException + */ + public void unmountFilesystem( String driveLetter, String mountPoint) + throws CifsMountException + { + // Create the command line launcher + + RuntimeExec exec = new RuntimeExec(); + + // Create the command map and properties + + Map commandMap = new HashMap( 1); + Map defProperties = new HashMap( 10); + + // Determine the platform type and build the appropriate command line string + + Platform.Type platform = Platform.isPlatformType(); + + switch ( platform) + { + // Windows + + case WINDOWS: + commandMap.put( "Windows.*", WindowsUnMountCmd); + break; + + // Linux + + case LINUX: + commandMap.put( "Linux", LinuxUnMountCmd); + break; + + // Mac OS X + + case MACOSX: + commandMap.put( "Mac OS X", MacOSXUnMountCmd); + break; + } + + // Set the command map + + exec.setCommandMap( commandMap); + + // Build the command line properties list + + defProperties.put( "drive", driveLetter); + defProperties.put( "mountpoint", mountPoint); + + exec.setDefaultProperties(defProperties); + + // Get the command to be used on this platform + + if ( logger.isDebugEnabled()) + logger.debug( "UnMount CIFS share, cmdLine=" + exec.getCommand()); + + // Run the command + + ExecutionResult execRes = exec.execute(); + + if ( logger.isDebugEnabled()) + logger.debug( "UnMount result=" + execRes); + + // Check if the command was successful + + if ( execRes.getSuccess() == false) + throw new CifsMountException( execRes.getExitValue(), execRes.getStdOut(), execRes.getStdErr()); + } + + /** + * Return the server name + * + * @return String + */ + public final String getServerName() + { + return m_srvName; + } + + /** + * Return the share name + * + * @return String + */ + public final String getShareName() + { + return m_shareName; + } + + /** + * Return the user name + * + * @return String + */ + public final String getUserName() + { + return m_userName; + } + + /** + * Return the password + * + * @return String + */ + public final String getPassword() + { + return m_password; + } + + /** + * Return the protocol type + * + * @return int + */ + public final int isProtocolType() + { + return m_protocolType; + } + + /** + * Return the protocol port + * + * @return int + */ + public final int getProtocolPort() + { + return m_port; + } + + /** + * Set the server name + * + * @param name String + */ + public final void setServerName(String name) + { + m_srvName = name; + } + + /** + * Set the share name + * + * @param name String + */ + public final void setShareName(String name) + { + m_shareName = name; + } + + /** + * Set the user name + * + * @param user String + */ + public final void setUserName(String user) + { + m_userName = user; + } + + /** + * Set the password + * + * @param password String + */ + public final void setPassword(String password) + { + m_password = password; + } + + /** + * Set the protocol type to use + * + * @param proto int + */ + public final void setProtocolType(int proto) + { + m_protocolType = proto; + } + + /** + * Set the port to use for the connection + * + * @param port int + */ + public final void setProtocolPort(int port) + { + m_port = port; + } + + /** + * Return the CIFS mounter as a string + * + * @return String + */ + public String toString() + { + StringBuilder str = new StringBuilder(); + + str.append( "[\\\\"); + str.append( getServerName()); + str.append( "\\"); + str.append( getShareName()); + str.append( ","); + str.append( getUserName()); + str.append( ","); + str.append( getPassword()); + + if ( isProtocolType() != Default) + { + str.append( " ("); + if ( isProtocolType() == NetBIOS) + str.append ( "NetBIOS"); + else if ( isProtocolType() == NativeSMB) + str.append( "NativeSMB"); + else if ( isProtocolType() == Win32NetBIOS) + str.append( "Win32NetBIOS"); + + if ( getProtocolPort() != 0) + { + str.append( ","); + str.append( getProtocolPort()); + } + str.append( ")"); + } + str.append( "]"); + + return str.toString(); + } +} diff --git a/source/java/org/alfresco/filesys/util/Platform.java b/source/java/org/alfresco/filesys/util/Platform.java new file mode 100644 index 0000000000..27f5aefbe6 --- /dev/null +++ b/source/java/org/alfresco/filesys/util/Platform.java @@ -0,0 +1,68 @@ +/* + * 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.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; + } +}