Align Alfresco, CIFS and FTP authentication stacks for NTLM passthru, kerberos and LDAP

- PassthruServerFactory created to allows PassthruServers singleton to be shared by CIFS, FTP and Alfresco passthru authenticators
- Also added NTLM + Alfresco (non-passthru) example. Doesn't seem to work yet!
- ExtendedServerConfigurationAccessor interface added BaseSSOAuthenticationFilter to get at local server name info from file server configuration
- toString() added to CIFSAuthenticator so that we can still properly log the authenticator type
- Fixed WebDAVServlet to go through ServerConfigurationAccessor interface to avoid ClassCastException

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13823 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2009-04-03 11:29:18 +00:00
parent 79c938f0b4
commit 1f78e6b28c
19 changed files with 829 additions and 617 deletions

View File

@@ -75,9 +75,10 @@
<!-- DAO that supports CRUD. -->
<bean id="alfrescoAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="alfrescoNtlmAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="kerberosAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="ldapAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="ntlmAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="passthruAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
<bean id="authenticationSelector" class="org.alfresco.repo.management.SwitchableManagedApplicationContextFactory">
<property name="sourceBeanName">
@@ -93,13 +94,39 @@
<list>
<value>org.alfresco.repo.security.authentication.AuthenticationComponent</value>
<value>org.alfresco.repo.security.authentication.MutableAuthenticationDao</value>
<value>org.alfresco.jlan.server.auth.ICifsAuthenticator</value>
<value>org.alfresco.jlan.ftp.FTPAuthenticator</value>
<!-- Allow listening for SMB Server session events -->
<value>org.alfresco.jlan.server.SessionListener</value>
</list>
</property>
</bean>
<bean id="cifsAuthenticator" class="org.alfresco.repo.management.ManagedSubsystemProxyFactory">
<property name="sourceApplicationContextFactory">
<ref bean="authenticationSelector" />
</property>
<property name="sourceBeanName">
<value>cifsAuthenticator</value>
</property>
<property name="interfaces">
<list>
<value>org.alfresco.jlan.server.auth.ICifsAuthenticator</value>
</list>
</property>
</bean>
<bean id="ftpAuthenticator" class="org.alfresco.repo.management.ManagedSubsystemProxyFactory">
<property name="sourceApplicationContextFactory">
<ref bean="authenticationSelector" />
</property>
<property name="sourceBeanName">
<value>ftpAuthenticator</value>
</property>
<property name="interfaces">
<list>
<value>org.alfresco.jlan.ftp.FTPAuthenticator</value>
</list>
</property>
</bean>
<!-- The DAO also acts as a salt provider. -->

View File

@@ -382,7 +382,7 @@
<property name="interfaces">
<list>
<!-- Allow authentication subsystem to see file server config at runtime -->
<value>org.alfresco.jlan.server.config.ServerConfigurationAccessor</value>
<value>org.alfresco.filesys.ExtendedServerConfigurationAccessor</value>
</list>
</property>
</bean>

View File

@@ -0,0 +1,62 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.AuthenticationComponentImpl"
parent="authenticationComponentBase">
<property name="authenticationDao">
<ref bean="authenticationDao" />
</property>
<property name="authenticationManager">
<ref bean="authenticationManager" />
</property>
<property name="allowGuestLogin">
<value>${alfresco.authentication.allowGuestLogin}</value>
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="transactionService">
<ref bean="transactionService" />
</property>
</bean>
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="tenantService">
<ref bean="tenantService" />
</property>
<property name="dictionaryService">
<ref bean="dictionaryService" />
</property>
<property name="namespaceService">
<ref bean="namespaceService" />
</property>
<property name="searchService">
<ref bean="admSearchService" />
</property>
<property name="retryingTransactionHelper">
<ref bean="retryingTransactionHelper" />
</property>
<property name="userNameMatcher">
<ref bean="userNameMatcher" />
</property>
<property name="passwordEncoder">
<ref bean="passwordEncoder" />
</property>
</bean>
<!-- CIFS authentication -->
<bean id="cifsAuthenticator" class="org.alfresco.filesys.auth.cifs.EnterpriseCifsAuthenticator" parent="cifsAuthenticatorBase" />
<!-- FTP authentication -->
<bean id="ftpAuthenticator" class="org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator" parent="ftpAuthenticatorBase" />
<!-- SMB session listener. Only required for passthru authentication -->
<bean id="smbSessionListener" class="org.alfresco.filesys.NullSessionListener" />
</beans>

View File

@@ -0,0 +1 @@
alfresco.authentication.allowGuestLogin=true

View File

@@ -127,7 +127,7 @@
<!-- CIFS authentication -->
<property name="authenticator">
<ref bean="authenticationDao" />
<ref bean="cifsAuthenticator" />
</property>
<property name="WINSConfig">
@@ -160,7 +160,7 @@
<!-- FTP authentication -->
<property name="authenticator">
<ref bean="authenticationDao" />
<ref bean="ftpAuthenticator" />
</property>
<!--property name="debugFlags">

View File

@@ -39,5 +39,24 @@
<property name="allowDeleteUser" value="true" />
<property name="allowCreateUser" value="true" />
</bean>
<!-- CIFS authentication -->
<bean id="cifsAuthenticator" class="org.alfresco.filesys.auth.cifs.EnterpriseCifsAuthenticator" parent="cifsAuthenticatorBase" >
<property name="realm">
<value>${kerberos.authentication.realm}</value>
</property>
<property name="password">
<value>${kerberos.authentication.cifs.password}</value>
</property>
<property name="jaasConfigEntryName">
<value>${kerberos.authentication.cifs.configEntryName}</value>
</property>
</bean>
<!-- FTP authentication -->
<bean id="ftpAuthenticator" class="org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator" parent="ftpAuthenticatorBase" />
<!-- SMB session listener. Only required for passthru authentication -->
<bean id="smbSessionListener" class="org.alfresco.filesys.NullSessionListener" />
</beans>

View File

@@ -1,3 +1,5 @@
kerberos.authentication.realm=ALFRESCO.ORG
kerberos.authentication.user.configEntryName=Alfresco
kerberos.authentication.defaultAdministratorUserNames=
kerberos.authentication.defaultAdministratorUserNames=
kerberos.authentication.cifs.configEntryName=AlfrescoCIFS
kerberos.authentication.cifs.password=secret

View File

@@ -108,4 +108,43 @@
</property>
</bean>
<!-- The passthru servers -->
<!-- Properties that specify the server(s) to use for passthru -->
<!-- authentication :- -->
<!-- useLocalServer use the local server for authentication -->
<!-- domain use domain controllers from the specified domain-->
<!-- servers comma delimted list of server addresses or -->
<!-- names -->
<bean id="passthruServers" class="org.alfresco.filesys.auth.PassthruServerFactory">
<property name="useLocalServer">
<value>${ldap.passthru.authentication.useLocalServer}</value>
</property>
<property name="servers">
<value>${ldap.passthru.authentication.servers}</value>
</property>
<property name="domain">
<value>${ldap.passthru.authentication.domain}</value>
</property>
<!-- Timeout value when opening a session to an authentication server, in milliseconds -->
<property name="timeout">
<value>${ldap.passthru.authentication.connectTimeout}</value>
</property>
<!-- Offline server check interval -->
<property name="offlineCheckInterval">
<value>${ldap.passthru.authentication.offlineCheckInterval}</value>
</property>
<property name="protocolOrder">
<value>${ldap.passthru.authentication.protocolOrder}</value>
</property>
</bean>
<!-- CIFS authentication and SMB session listener -->
<bean id="cifsAuthenticator" class="org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator" parent="cifsAuthenticatorBase">
<property name="passthruServers">
<ref bean="passthruServers" />
</property>
</bean>
<!-- FTP authentication -->
<bean id="ftpAuthenticator" class="org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator" parent="ftpAuthenticatorBase" />
</beans>

View File

@@ -37,4 +37,13 @@ ldap.authentication.escapeCommasInBind=false
ldap.authentication.escapeCommasInUid=false
# Comma separated list of user names who should be considered users by default
ldap.authentication.defaultAdministratorUserNames=
ldap.authentication.defaultAdministratorUserNames=
# Passthru setings, if a CIFS server is in use with Active Directory
ldap.passthru.authentication.useLocalServer=false
ldap.passthru.authentication.domain=DOMAIN
ldap.passthru.authentication.servers=
ldap.passthru.authentication.guestAccess=false
ldap.passthru.authentication.connectTimeout=5000
ldap.passthru.authentication.offlineCheckInterval=300000
ldap.passthru.authentication.protocolOrder=NetBIOS,TCPIP

View File

@@ -1,5 +0,0 @@
ntlm.authentication.useLocalServer=false
ntlm.authentication.domain=DOMAIN
ntlm.authentication.servers=
ntlm.authentication.guestAccess=false
ntlm.authentication.defaultAdministratorUserNames=

View File

@@ -1,55 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao" >
<property name="allowSetEnabled" value="true" />
<property name="allowGetEnabled" value="true" />
<property name="allowDeleteUser" value="true" />
<property name="allowCreateUser" value="true" />
</bean>
<!-- The authentication component. -->
<!-- Use the passthru authentication component to authenticate using -->
<!-- user accounts on one or more Windows servers. -->
<!-- Properties that specify the server(s) to use for passthru -->
<!-- authentication :- -->
<!-- useLocalServer use the local server for authentication -->
<!-- domain use domain controllers from the specified domain-->
<!-- servers comma delimted list of server addresses or -->
<!-- names -->
<bean id="authenticationComponent"
class="org.alfresco.repo.security.authentication.ntlm.NTLMAuthenticationComponentImpl"
parent="authenticationComponentBase">
<property name="useLocalServer">
<value>${ntlm.authentication.useLocalServer}</value>
</property>
<property name="domain">
<value>${ntlm.authentication.domain}</value>
</property>
<property name="servers">
<value>${ntlm.authentication.servers}</value>
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="transactionService">
<ref bean="transactionComponent" />
</property>
<property name="guestAccess">
<value>${ntlm.authentication.guestAccess}</value>
</property>
<property name="defaultAdministratorUserNames">
<value>${ntlm.authentication.defaultAdministratorUserNames}</value>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,10 @@
passthru.authentication.useLocalServer=false
passthru.authentication.domain=DOMAIN
passthru.authentication.servers=
passthru.authentication.guestAccess=false
passthru.authentication.defaultAdministratorUserNames=
#Timeout value when opening a session to an authentication server, in milliseconds
passthru.authentication.connectTimeout=5000
#Offline server check interval in seconds
passthru.authentication.offlineCheckInterval=300
passthru.authentication.protocolOrder=NetBIOS,TCPIP

View File

@@ -0,0 +1,85 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao">
<property name="allowSetEnabled" value="true" />
<property name="allowGetEnabled" value="true" />
<property name="allowDeleteUser" value="true" />
<property name="allowCreateUser" value="true" />
</bean>
<!-- The passthru servers -->
<!-- Properties that specify the server(s) to use for passthru -->
<!-- authentication :- -->
<!-- useLocalServer use the local server for authentication -->
<!-- domain use domain controllers from the specified domain-->
<!-- servers comma delimted list of server addresses or -->
<!-- names -->
<bean id="passthruServers" class="org.alfresco.filesys.auth.PassthruServerFactory">
<property name="localServer">
<value>${passthru.authentication.useLocalServer}</value>
</property>
<property name="server">
<value>${passthru.authentication.servers}</value>
</property>
<property name="domain">
<value>${passthru.authentication.domain}</value>
</property>
<!-- Timeout value when opening a session to an authentication server, in milliseconds -->
<property name="timeout">
<value>${passthru.authentication.connectTimeout}</value>
</property>
<!-- Offline server check interval in seconds -->
<property name="offlineCheckInterval">
<value>${passthru.authentication.offlineCheckInterval}</value>
</property>
<property name="protocolOrder">
<value>${passthru.authentication.protocolOrder}</value>
</property>
</bean>
<!-- The authentication component. -->
<!-- Use the passthru authentication component to authenticate using -->
<!-- user accounts on one or more Windows servers. -->
<bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.ntlm.NTLMAuthenticationComponentImpl"
parent="authenticationComponentBase">
<property name="passthruServers">
<ref bean="passthruServers" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="transactionService">
<ref bean="transactionComponent" />
</property>
<property name="guestAccess">
<value>${passthru.authentication.guestAccess}</value>
</property>
<property name="defaultAdministratorUserNames">
<value>${passthru.authentication.defaultAdministratorUserNames}</value>
</property>
</bean>
<!-- CIFS authentication and SMB session listener -->
<bean id="cifsAuthenticator" class="org.alfresco.filesys.auth.cifs.PassthruCifsAuthenticator" parent="cifsAuthenticatorBase">
<property name="passthruServers">
<ref bean="passthruServers" />
</property>
</bean>
<!-- FTP authentication -->
<bean id="ftpAuthenticator" class="org.alfresco.filesys.auth.ftp.PassthruFtpAuthenticator" parent="ftpAuthenticatorBase">
<property name="passthruServers">
<ref bean="passthruServers" />
</property>
</bean>
</beans>

View File

@@ -76,7 +76,9 @@ import org.springframework.context.event.ContextRefreshedEvent;
*
* @author gkspencer
*/
public abstract class AbstractServerConfigurationBean extends ServerConfiguration implements ApplicationListener, ApplicationContextAware {
public abstract class AbstractServerConfigurationBean extends ServerConfiguration implements
ExtendedServerConfigurationAccessor, ApplicationListener, ApplicationContextAware
{
// Debug logging
@@ -178,6 +180,7 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
// Local server name and domain/workgroup name
private String m_localName;
private String m_localNameFull;
private String m_localDomain;
// Disable use of native code on Windows, do not use any JNI calls
@@ -630,11 +633,49 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
*/
public final String getLocalServerName(boolean trimDomain)
{
// Use cached untrimmed version if necessary
if (!trimDomain)
{
return getLocalServerName();
}
// Check if the name has already been set
if (m_localName != null)
return m_localName;
// Find the local server name
String srvName = getLocalServerName();
// 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 server name (untrimmed)
*
* @return String
*/
private String getLocalServerName()
{
// Check if the name has already been set
if (m_localNameFull != null)
return m_localNameFull;
// Find the local server name
String srvName = null;
@@ -658,18 +699,9 @@ public abstract class AbstractServerConfigurationBean extends ServerConfiguratio
}
}
// 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;
m_localNameFull = srvName;
// Return the local server name

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a 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.ServerConfigurationAccessor;
/**
* An interface exposing some extended capabilities of the AbstractServerConfigurationBean.
*
* @author dward
*/
public interface ExtendedServerConfigurationAccessor extends ServerConfigurationAccessor
{
/**
* Get the local server name and optionally trim the domain name
*
* @param trimDomain
* boolean
* @return String
*/
public String getLocalServerName(boolean trimDomain);
/**
* Get the local domain/workgroup name
*
* @return String
*/
public String getLocalDomainName();
}

View File

@@ -0,0 +1,378 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a 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;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.jlan.server.auth.passthru.AuthSessionFactory;
import org.alfresco.jlan.server.auth.passthru.PassthruServers;
import org.alfresco.jlan.server.config.InvalidConfigurationException;
import org.alfresco.jlan.smb.Protocol;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* A Factory for {@link PassthruServers} objects, allowing setting of the server list via local server, individual
* servers or domain name.
*
* @author dward
*/
public class PassthruServerFactory implements FactoryBean, InitializingBean, DisposableBean
{
private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth");
public final static int DefaultSessionTmo = 5000; // 5 seconds
public final static int MinSessionTmo = 2000; // 2 seconds
public final static int MaxSessionTmo = 30000; // 30 seconds
public final static int MinCheckInterval = 10; // 10 seconds
public final static int MaxCheckInterval = 15 * 60; // 15 minutes
private Integer timeout;
private boolean localServer;
private String server;
private String domain;
private Integer offlineCheckInterval;
private PassthruServers passthruServers;
/**
* Sets the timeout for opening a session to an authentication server
*
* @param timeout
* a time period in milliseconds
*/
public void setTimeout(int timeout)
{
this.timeout = timeout;
}
/**
* Indicates whether the local server should be used as the authentication server
*
* @param localServer
* <code>true</code> if the local server should be used as the authentication server
*/
public void setLocalServer(boolean localServer)
{
this.localServer = localServer;
}
/**
* Sets the server(s) to authenticate against.
*
* @param server
* comma-delimited list of server names
*/
public void setServer(String server)
{
this.server = server;
}
/**
* Sets the domain to authenticate against
*
* @param domain
* a domain name
*/
public void setDomain(String domain)
{
this.domain = domain;
}
/**
* Sets the offline server check interval in seconds
*
* @param offlineCheckInterval
* a time interval in seconds
*/
public void setOfflineCheckInterval(Integer offlineCheckInterval)
{
this.offlineCheckInterval = offlineCheckInterval;
}
/**
* Set the protocol order for passthru connections
*
* @param protoOrder
* a comma-delimited list containing one or more of "NetBIOS" and "TCPIP" in any order
*/
public void setProtocolOrder(String protoOrder)
{
// Parse the protocol order list
StringTokenizer tokens = new StringTokenizer(protoOrder, ",");
int primaryProto = Protocol.None;
int secondaryProto = Protocol.None;
// There should only be one or two tokens
if (tokens.countTokens() > 2)
throw new AlfrescoRuntimeException("Invalid protocol order list, " + protoOrder);
// Get the primary protocol
if (tokens.hasMoreTokens())
{
// Parse the primary protocol
String primaryStr = tokens.nextToken();
if (primaryStr.equalsIgnoreCase("TCPIP"))
primaryProto = Protocol.NativeSMB;
else if (primaryStr.equalsIgnoreCase("NetBIOS"))
primaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid protocol type, " + primaryStr);
// Check if there is a secondary protocol, and validate
if (tokens.hasMoreTokens())
{
// Parse the secondary protocol
String secondaryStr = tokens.nextToken();
if (secondaryStr.equalsIgnoreCase("TCPIP") && primaryProto != Protocol.NativeSMB)
secondaryProto = Protocol.NativeSMB;
else if (secondaryStr.equalsIgnoreCase("NetBIOS") && primaryProto != Protocol.TCPNetBIOS)
secondaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid secondary protocol, " + secondaryStr);
}
}
// Set the protocol order used for passthru authentication sessions
AuthSessionFactory.setProtocolOrder(primaryProto, secondaryProto);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Protocol order primary=" + Protocol.asString(primaryProto) + ", secondary="
+ Protocol.asString(secondaryProto));
}
public void afterPropertiesSet() throws InvalidConfigurationException
{
// Check if the offline check interval has been specified
if (this.offlineCheckInterval != null)
{
// Range check the value
if (this.offlineCheckInterval < MinCheckInterval || this.offlineCheckInterval > MaxCheckInterval)
throw new InvalidConfigurationException("Invalid offline check interval, valid range is "
+ MinCheckInterval + " to " + MaxCheckInterval);
// Set the offline check interval for offline passthru servers
passthruServers = new PassthruServers(this.offlineCheckInterval);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Using offline check interval of " + this.offlineCheckInterval + " seconds");
}
else
{
// Create the passthru server list with the default offline check interval
passthruServers = new PassthruServers();
}
// Propagate the debug setting
if (logger.isDebugEnabled())
passthruServers.setDebug(true);
// Check if the session timeout has been specified
if (this.timeout != null)
{
// Range check the timeout
if (this.timeout < MinSessionTmo || this.timeout > MaxSessionTmo)
throw new InvalidConfigurationException("Invalid session timeout, valid range is " + MinSessionTmo
+ " to " + MaxSessionTmo);
// Set the session timeout for connecting to an authentication server
passthruServers.setConnectionTimeout(this.timeout);
}
// Check if a server name has been specified
String srvList = null;
if (localServer)
{
try
{
// Get the list of local network addresses
InetAddress[] localAddrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
// Build the list of local addresses
if (localAddrs != null && localAddrs.length > 0)
{
StringBuilder addrStr = new StringBuilder();
for (InetAddress curAddr : localAddrs)
{
if (curAddr.isLoopbackAddress() == false)
{
addrStr.append(curAddr.getHostAddress());
addrStr.append(",");
}
}
if (addrStr.length() > 0)
addrStr.setLength(addrStr.length() - 1);
// Set the server list using the local address list
srvList = addrStr.toString();
}
else
throw new AlfrescoRuntimeException("No local server address(es)");
}
catch (UnknownHostException ex)
{
throw new AlfrescoRuntimeException("Failed to get local address list");
}
}
if (this.server != null && this.server.length() > 0)
{
// Check if the server name was already set
if (srvList != null)
throw new AlfrescoRuntimeException("Set passthru server via local server or specify name");
// Get the passthru authenticator server name
srvList = this.server;
}
// If the passthru server name has been set initialize the passthru connection
if (srvList != null)
{
// Initialize using a list of server names/addresses
passthruServers.setServerList(srvList);
}
else
{
// Get the domain/workgroup name
String domainName = null;
// Check if a domain name has been specified
if (this.domain != null && this.domain.length() > 0)
{
// Check if the authentication server has already been set, ie. server name was also specified
if (srvList != null)
throw new AlfrescoRuntimeException("Specify server or domain name for passthru authentication");
domainName = this.domain;
}
// If the domain name has been set initialize the passthru connection
if (domainName != null)
{
try
{
// Initialize using the domain
passthruServers.setDomain(domainName);
}
catch (IOException ex)
{
throw new AlfrescoRuntimeException("Error setting passthru domain, " + ex.getMessage());
}
}
}
// Check if we have an authentication server
if (passthruServers.getTotalServerCount() == 0)
throw new AlfrescoRuntimeException("No valid authentication servers found for passthru");
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#getObject()
*/
public Object getObject()
{
return passthruServers;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<?> getObjectType()
{
return PassthruServers.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton()
{
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception
{
passthruServers.shutdown();
}
}

View File

@@ -24,11 +24,9 @@
*/
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.StringTokenizer;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
@@ -36,6 +34,7 @@ import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.filesys.auth.PassthruServerFactory;
import org.alfresco.jlan.server.SessionListener;
import org.alfresco.jlan.server.SrvSession;
import org.alfresco.jlan.server.auth.AuthContext;
@@ -49,7 +48,6 @@ 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.AuthSessionFactory;
import org.alfresco.jlan.server.auth.passthru.AuthenticateSession;
import org.alfresco.jlan.server.auth.passthru.PassthruDetails;
import org.alfresco.jlan.server.auth.passthru.PassthruServers;
@@ -57,7 +55,6 @@ 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.Protocol;
import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.jlan.smb.dcerpc.UUID;
import org.alfresco.jlan.smb.server.SMBServer;
@@ -111,24 +108,12 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
// Passthru servers used to authenticate users
private PassthruServers m_passthruServers;
// SMB server
private SMBServer m_server;
private boolean m_localPassThruServers;
// Sessions that are currently in the negotiate/session setup state
private Hashtable<String, PassthruDetails> m_sessions;
private Integer timeout;
private String server;
private String domain;
private String protocolOrder;
private Integer offlineCheckInterval;
/**
* Passthru Authenticator Constructor
@@ -142,29 +127,10 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
m_sessions = new Hashtable<String, PassthruDetails>();
}
public void setTimeout(int timeout)
{
this.timeout = timeout;
}
public void setServer(String server)
{
this.server = server;
}
public void setDomain(String domain)
public void setPassthruServers(PassthruServers servers)
{
this.domain = domain;
}
public void setProtocolOrder(String protocolOrder)
{
this.protocolOrder = protocolOrder;
}
public void setOfflineCheckInterval(Integer offlineCheckInterval)
{
this.offlineCheckInterval = offlineCheckInterval;
m_passthruServers = servers;
}
/**
@@ -440,16 +406,6 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
*/
public AuthContext getAuthContext( SMBSrvSession sess)
{
// Make sure the SMB server listener is installed
if ( m_server == null)
{
// Install the server listener
m_server = sess.getSMBServer();
m_server.addSessionListener(this);
}
// Open a connection to the authentication server, use normal session setup
AuthContext authCtx = null;
@@ -1202,8 +1158,10 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
*/
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
{
// Check if the offline check interval has been specified
// Manually construct our own passthru server list
PassthruServerFactory factory = new PassthruServerFactory();
// Check if the offline check interval has been specified
ConfigElement checkInterval = params.getChild("offlineCheckInterval");
if ( checkInterval != null)
{
@@ -1211,7 +1169,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
{
// Validate the check interval value
setOfflineCheckInterval(Integer.parseInt(checkInterval.getValue()));
factory.setOfflineCheckInterval(Integer.parseInt(checkInterval.getValue()));
}
catch (NumberFormatException ex)
@@ -1231,7 +1189,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
// Validate the session timeout value
setTimeout(Integer.parseInt(sessTmoElem.getValue()));
factory.setTimeout(Integer.parseInt(sessTmoElem.getValue()));
}
catch (NumberFormatException ex)
{
@@ -1251,7 +1209,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
String server = getCIFSConfig().getServerName();
if(server == null)
throw new AlfrescoRuntimeException("Passthru authenticator failed to get local server name");
setServer(server);
factory.setServer(server);
}
// Check if a server name has been specified
@@ -1260,7 +1218,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
if (srvNamesElem != null && srvNamesElem.getValue().length() > 0)
{
setServer(srvNamesElem.getValue());
factory.setServer(srvNamesElem.getValue());
}
// Check if the local domain/workgroup should be used
@@ -1269,7 +1227,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
{
// Get the local domain/workgroup name
setDomain(getCIFSConfig().getDomainName());
factory.setDomain(getCIFSConfig().getDomainName());
}
// Check if a domain name has been specified
@@ -1278,7 +1236,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
if (domNameElem != null && domNameElem.getValue().length() > 0)
{
setDomain(domNameElem.getValue());
factory.setDomain(domNameElem.getValue());
}
// Check if a protocol order has been set
@@ -1287,9 +1245,15 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
if (protoOrderElem != null && protoOrderElem.getValue().length() > 0)
{
setProtocolOrder(protoOrderElem.getValue());
factory.setProtocolOrder(protoOrderElem.getValue());
}
// Complete initialization
factory.afterPropertiesSet();
setPassthruServers((PassthruServers) factory.getObject());
// Remember that we have to shut down the servers
m_localPassThruServers = true;
// Call the base class
super.initialize(config, params);
@@ -1303,185 +1267,6 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
// Note that for container-based initialization, session listeners can be registered directly on CIFSSeverBean
}
/**
* Initialize the authenticator (after properties have been set)
*
* @exception InvalidConfigurationException
*/
@Override
public void initialize() throws InvalidConfigurationException
{
// Call the base class
super.initialize();
// Check if the offline check interval has been specified
if ( this.offlineCheckInterval != null)
{
// Range check the value
if ( this.offlineCheckInterval < MinCheckInterval || this.offlineCheckInterval > MaxCheckInterval)
throw new InvalidConfigurationException("Invalid offline check interval, valid range is " + MinCheckInterval + " to " + MaxCheckInterval);
// Set the offline check interval for offline passthru servers
m_passthruServers = new PassthruServers( this.offlineCheckInterval);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Using offline check interval of " + this.offlineCheckInterval + " seconds");
}
else
{
// Create the passthru server list with the default offline check interval
m_passthruServers = new PassthruServers();
}
// Propagate the debug setting
if ( logger.isDebugEnabled())
m_passthruServers.setDebug( true);
// Check if the session timeout has been specified
if (this.timeout != null)
{
// Range check the timeout
if ( this.timeout < MinSessionTmo || this.timeout > MaxSessionTmo)
throw new InvalidConfigurationException("Invalid session timeout, valid range is " +
MinSessionTmo + " to " + MaxSessionTmo);
// Set the session timeout for connecting to an authentication server
m_passthruServers.setConnectionTimeout( this.timeout);
}
// Check if a server name has been specified
String srvList = null;
if (this.server != null && this.server.length() > 0)
{
// Get the passthru authenticator server name
srvList = this.server;
}
// If the passthru server name has been set initialize the passthru connection
if (srvList != null)
{
// Initialize using a list of server names/addresses
m_passthruServers.setServerList(srvList);
}
else
{
// Get the domain/workgroup name
String domainName = null;
// Check if a domain name has been specified
if (this.domain != null && this.domain.length() > 0)
{
// Check if the authentication server has already been set, ie. server name was also specified
if (srvList != null)
throw new AlfrescoRuntimeException("Specify server or domain name for passthru authentication");
domainName = this.domain;
}
// If the domain name has been set initialize the passthru connection
if (domainName != null)
{
try
{
// Initialize using the domain
m_passthruServers.setDomain(domainName);
}
catch ( IOException ex)
{
throw new AlfrescoRuntimeException("Error setting passthru domain, " + ex.getMessage());
}
}
}
// Check if a protocol order has been set
if ( this.protocolOrder != null && this.protocolOrder.length() > 0)
{
// Parse the protocol order list
StringTokenizer tokens = new StringTokenizer( this.protocolOrder, ",");
int primaryProto = Protocol.None;
int secondaryProto = Protocol.None;
// There should only be one or two tokens
if ( tokens.countTokens() > 2)
throw new AlfrescoRuntimeException("Invalid protocol order list, " + this.protocolOrder);
// Get the primary protocol
if ( tokens.hasMoreTokens())
{
// Parse the primary protocol
String primaryStr = tokens.nextToken();
if ( primaryStr.equalsIgnoreCase( "TCPIP"))
primaryProto = Protocol.NativeSMB;
else if ( primaryStr.equalsIgnoreCase( "NetBIOS"))
primaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid protocol type, " + primaryStr);
// Check if there is a secondary protocol, and validate
if ( tokens.hasMoreTokens())
{
// Parse the secondary protocol
String secondaryStr = tokens.nextToken();
if ( secondaryStr.equalsIgnoreCase( "TCPIP") && primaryProto != Protocol.NativeSMB)
secondaryProto = Protocol.NativeSMB;
else if ( secondaryStr.equalsIgnoreCase( "NetBIOS") && primaryProto != Protocol.TCPNetBIOS)
secondaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid secondary protocol, " + secondaryStr);
}
}
// Set the protocol order used for passthru authentication sessions
AuthSessionFactory.setProtocolOrder( primaryProto, secondaryProto);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Protocol order primary=" + Protocol.asString(primaryProto) + ", secondary=" + Protocol.asString(secondaryProto));
}
// Check if we have an authentication server
if (m_passthruServers.getTotalServerCount() == 0)
throw new AlfrescoRuntimeException("No valid authentication servers found for passthru");
// Note that for container-based initialization, session listeners can be registered directly on CIFSSeverBean
}
/**
* Return the server capability flags
*
@@ -1501,7 +1286,7 @@ public class PassthruCifsAuthenticator extends CifsAuthenticatorBase implements
{
// Close the passthru authentication server list
if ( m_passthruServers != null)
if ( m_localPassThruServers && m_passthruServers != null)
m_passthruServers.shutdown();
}

View File

@@ -25,9 +25,7 @@
package org.alfresco.filesys.auth.ftp;
import java.io.IOException;
import java.net.InetAddress;
import java.util.StringTokenizer;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
@@ -36,20 +34,19 @@ import net.sf.acegisecurity.Authentication;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.ServerConfigurationBean;
import org.alfresco.filesys.ExtendedServerConfigurationAccessor;
import org.alfresco.filesys.alfresco.AlfrescoClientInfo;
import org.alfresco.filesys.auth.PassthruServerFactory;
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.auth.passthru.AuthSessionFactory;
import org.alfresco.jlan.server.auth.passthru.AuthenticateSession;
import org.alfresco.jlan.server.auth.passthru.DomainMapping;
import org.alfresco.jlan.server.auth.passthru.PassthruServers;
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.smb.Protocol;
import org.alfresco.jlan.util.IPAddress;
import org.alfresco.repo.security.authentication.NTLMMode;
@@ -77,50 +74,22 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
private PassthruServers m_passthruServers;
private boolean m_localPassThruServers;
// Password encryption, for CIFS NTLM style encryption/hashing
private PasswordEncryptor m_passwordEncryptor;
private Integer timeout;
private String server;
private String domain;
private String protocolOrder;
private Integer offlineCheckInterval;
public void setTimeout(Integer timeout)
{
this.timeout = timeout;
}
public void setServer(String server)
{
this.server = server;
}
public void setDomain(String domain)
{
this.domain = domain;
}
public void setProtocolOrder(String protocolOrder)
{
this.protocolOrder = protocolOrder;
}
public void setOfflineCheckInterval(Integer offlineCheckInterval)
{
this.offlineCheckInterval = offlineCheckInterval;
}
protected SecurityConfigSection getSecurityConfig()
{
return (SecurityConfigSection) this.serverConfiguration.getConfigSection(SecurityConfigSection.SectionName);
}
public void setPassthruServers(PassthruServers passthruServers)
{
m_passthruServers = passthruServers;
}
/**
* Initialize the authenticator
*
@@ -131,6 +100,9 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
@Override
public void initialize(ServerConfiguration config, ConfigElement params)
throws InvalidConfigurationException {
// Manually construct our own passthru server list
PassthruServerFactory factory = new PassthruServerFactory();
// Check if the offline check interval has been specified
@@ -141,7 +113,7 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
{
// Validate the check interval value
setOfflineCheckInterval(Integer.parseInt(checkInterval.getValue()));
factory.setOfflineCheckInterval(Integer.parseInt(checkInterval.getValue()));
}
catch (NumberFormatException ex)
{
@@ -160,7 +132,7 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
// Validate the session timeout value
setTimeout(Integer.parseInt(sessTmoElem.getValue()));
factory.setTimeout(Integer.parseInt(sessTmoElem.getValue()));
}
catch (NumberFormatException ex)
@@ -169,24 +141,24 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
}
}
// Get the server configuration bean
// Get the extended server configuration
ServerConfigurationBean configBean = null;
ExtendedServerConfigurationAccessor configExtended = null;
if ( config instanceof ServerConfigurationBean)
configBean = (ServerConfigurationBean) config;
if ( config instanceof ExtendedServerConfigurationAccessor)
configExtended = (ExtendedServerConfigurationAccessor) config;
// Check if the local server should be used
if ( params.getChild("LocalServer") != null && configBean != null) {
if ( params.getChild("LocalServer") != null && configExtended != null) {
// Get the local server name, trim the domain name
String server = configBean.getLocalServerName( true);
String server = configExtended.getLocalServerName( true);
if ( server == null)
throw new AlfrescoRuntimeException("Passthru authenticator failed to get local server name");
setServer(server);
factory.setServer(server);
}
// Check if a server name has been specified
@@ -195,16 +167,16 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
if (srvNamesElem != null && srvNamesElem.getValue().length() > 0)
{
setServer(srvNamesElem.getValue());
factory.setServer(srvNamesElem.getValue());
}
// Check if the local domain/workgroup should be used
if ( params.getChild("LocalDomain") != null && configBean != null) {
if ( params.getChild("LocalDomain") != null && configExtended != null) {
// Get the local domain/workgroup name
setDomain(configBean.getLocalDomainName());
factory.setDomain(configExtended.getLocalDomainName());
}
// Check if a domain name has been specified
@@ -214,7 +186,7 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
if (domNameElem != null && domNameElem.getValue().length() > 0)
{
setDomain(domNameElem.getValue());
factory.setDomain(domNameElem.getValue());
}
// Check if a protocol order has been set
@@ -223,9 +195,15 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
if (protoOrderElem != null && protoOrderElem.getValue().length() > 0)
{
setProtocolOrder(protoOrderElem.getValue());
factory.setProtocolOrder(protoOrderElem.getValue());
}
// Complete initialization
factory.afterPropertiesSet();
setPassthruServers((PassthruServers) factory.getObject());
// Remember that we have to shut down the servers
m_localPassThruServers = true;
super.initialize(config, params);
}
@@ -248,161 +226,7 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
// Create the password encryptor
m_passwordEncryptor = new PasswordEncryptor();
// Check if the offline check interval has been specified
if ( this.offlineCheckInterval != null)
{
// Range check the value
if ( this.offlineCheckInterval < MinCheckInterval || this.offlineCheckInterval > MaxCheckInterval)
throw new InvalidConfigurationException("Invalid offline check interval, valid range is " + MinCheckInterval + " to " + MaxCheckInterval);
// Set the offline check interval for offline passthru servers
m_passthruServers = new PassthruServers( this.offlineCheckInterval);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Using offline check interval of " + this.offlineCheckInterval + " seconds");
}
else
{
// Create the passthru server list with the default offline check interval
m_passthruServers = new PassthruServers();
}
// Check if the session timeout has been specified
if (this.timeout != null)
{
// Range check the timeout
if (this.timeout < MinSessionTmo || this.timeout > MaxSessionTmo)
throw new InvalidConfigurationException("Invalid session timeout, valid range is " + MinSessionTmo
+ " to " + MaxSessionTmo);
// Set the session timeout for connecting to an authentication server
m_passthruServers.setConnectionTimeout(this.timeout);
}
// Check if a server name has been specified
String srvList = null;
if ( this.server != null && this.server.length() > 0) {
// Get the passthru authenticator server name
srvList = this.server;
}
// If the passthru server name has been set initialize the passthru connection
if ( srvList != null) {
// Initialize using a list of server names/addresses
m_passthruServers.setServerList(srvList);
}
else {
// Get the domain/workgroup name
String domainName = null;
// Check if a domain name has been specified
if ( this.domain != null && this.domain.length() > 0) {
// Check if the authentication server has already been set, ie. server name was also
// specified
if ( srvList != null)
throw new AlfrescoRuntimeException("Specify server or domain name for passthru authentication");
domainName = this.domain;
}
// If the domain name has been set initialize the passthru connection
if ( domainName != null) {
try {
// Initialize using the domain
m_passthruServers.setDomain(domainName);
}
catch (IOException ex) {
throw new AlfrescoRuntimeException("Error setting passthru domain, " + ex.getMessage());
}
}
}
// Check if a protocol order has been set
if ( this.protocolOrder != null && this.protocolOrder.length() > 0)
{
// Parse the protocol order list
StringTokenizer tokens = new StringTokenizer( this.protocolOrder, ",");
int primaryProto = Protocol.None;
int secondaryProto = Protocol.None;
// There should only be one or two tokens
if ( tokens.countTokens() > 2)
throw new AlfrescoRuntimeException("Invalid protocol order list, " + this.protocolOrder);
// Get the primary protocol
if ( tokens.hasMoreTokens())
{
// Parse the primary protocol
String primaryStr = tokens.nextToken();
if ( primaryStr.equalsIgnoreCase( "TCPIP"))
primaryProto = Protocol.NativeSMB;
else if ( primaryStr.equalsIgnoreCase( "NetBIOS"))
primaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid protocol type, " + primaryStr);
// Check if there is a secondary protocol, and validate
if ( tokens.hasMoreTokens())
{
// Parse the secondary protocol
String secondaryStr = tokens.nextToken();
if ( secondaryStr.equalsIgnoreCase( "TCPIP") && primaryProto != Protocol.NativeSMB)
secondaryProto = Protocol.NativeSMB;
else if ( secondaryStr.equalsIgnoreCase( "NetBIOS") && primaryProto != Protocol.TCPNetBIOS)
secondaryProto = Protocol.TCPNetBIOS;
else
throw new AlfrescoRuntimeException("Invalid secondary protocol, " + secondaryStr);
}
}
// Set the protocol order used for passthru authentication sessions
AuthSessionFactory.setProtocolOrder( primaryProto, secondaryProto);
// DEBUG
if (logger.isDebugEnabled())
logger.debug("Protocol order primary=" + Protocol.asString(primaryProto) + ", secondary=" + Protocol.asString(secondaryProto));
}
// Check if we have an authentication server
if ( m_passthruServers.getTotalServerCount() == 0)
throw new AlfrescoRuntimeException("No valid authentication servers found for passthru");
m_passwordEncryptor = new PasswordEncryptor();
}
/**
@@ -664,7 +488,7 @@ public class PassthruFtpAuthenticator extends FTPAuthenticatorBase {
// Close the passthru authentication server list
if ( m_passthruServers != null)
if ( m_localPassThruServers && m_passthruServers != null)
m_passthruServers.shutdown();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,8 +25,6 @@
package org.alfresco.repo.security.authentication.ntlm;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
@@ -45,6 +43,7 @@ import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.auth.PassthruServerFactory;
import org.alfresco.jlan.server.auth.PasswordEncryptor;
import org.alfresco.jlan.server.auth.passthru.AuthSessionFactory;
import org.alfresco.jlan.server.auth.passthru.AuthenticateSession;
@@ -55,10 +54,10 @@ import org.alfresco.jlan.smb.SMBStatus;
import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.service.Managed;
import org.alfresco.service.cmr.security.NoSuchPersonException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
/**
* NTLM Authentication Component Class
@@ -68,7 +67,7 @@ import org.apache.commons.logging.LogFactory;
*
* @author GKSpencer
*/
public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationComponent
public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationComponent implements InitializingBean
{
// Logging
@@ -88,6 +87,7 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
// Passthru authentication servers
private PassthruServerFactory m_passthruServerFactory = new PassthruServerFactory();
private PassthruServers m_passthruServers;
// Password encryptor for generating password hash for local authentication
@@ -245,13 +245,7 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
* Class constructor
*/
public NTLMAuthenticationComponentImpl() {
// Create the passthru authentication server list
m_passthruServers = new PassthruServers();
m_passthruServers.setDebug( logger.isDebugEnabled());
// Create the password encryptor for local password hashing
m_encryptor = new PasswordEncryptor();
@@ -261,6 +255,21 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
m_passthruSessions = new Hashtable<NTLMPassthruToken,AuthenticateSession>();
m_reaperThread = new PassthruReaperThread();
}
public void afterPropertiesSet() throws Exception
{
if (m_passthruServers == null)
{
// Create the passthru authentication server list
m_passthruServerFactory.afterPropertiesSet();
m_passthruServers = (PassthruServers) m_passthruServerFactory.getObject();
}
}
/**
* Determine if guest logons are allowed
@@ -272,30 +281,27 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
return m_allowGuest;
}
/**
* Directly sets the passthru server list.
*
* @param servers
* a passthru server list, usually created by {@link org.alfresco.filesys.auth.PassthruServerFactory}
*/
public void setPassthruServers(PassthruServers servers)
{
m_passthruServers = servers;
}
/**
* Set the domain to authenticate against
*
* @param domain String
*/
@Managed(category="Security")
public void setDomain(String domain) {
if (domain.length() > 0)
{
// Check if the passthru server list is already configured
if ( m_passthruServers.getTotalServerCount() > 0)
throw new AlfrescoRuntimeException("Passthru server list already configured");
// Configure the passthru authentication server list using the domain controllers
try
{
m_passthruServers.setDomain(domain);
}
catch ( IOException ex)
{
throw new AlfrescoRuntimeException("Failed to set passthru domain, " + ex);
}
{
m_passthruServerFactory.setDomain(domain);
}
}
@@ -304,18 +310,10 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param servers String
*/
@Managed(category="Security")
public void setServers(String servers) {
if (servers.length() > 0)
{
// Check if the passthru server list is already configured
if (m_passthruServers.getTotalServerCount() > 0)
throw new AlfrescoRuntimeException("Passthru server list already configured");
// Configure the passthru authenticaiton list using a list of server names/addresses
m_passthruServers.setServerList(servers);
m_passthruServerFactory.setServer(servers);
}
}
@@ -324,54 +322,9 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param useLocal String
*/
@Managed(category="Security")
public void setUseLocalServer(String useLocal)
{
// Check if the local server should be used for authentication
if ( Boolean.parseBoolean(useLocal) == true)
{
// Check if the passthru server list is already configured
if ( m_passthruServers.getTotalServerCount() > 0)
throw new AlfrescoRuntimeException("Passthru server list already configured");
try
{
// Get the list of local network addresses
InetAddress[] localAddrs = InetAddress.getAllByName(InetAddress.getLocalHost().getHostName());
// Build the list of local addresses
if ( localAddrs != null && localAddrs.length > 0)
{
StringBuilder addrStr = new StringBuilder();
for ( InetAddress curAddr : localAddrs)
{
if ( curAddr.isLoopbackAddress() == false)
{
addrStr.append(curAddr.getHostAddress());
addrStr.append(",");
}
}
if ( addrStr.length() > 0)
addrStr.setLength(addrStr.length() - 1);
// Set the server list using the local address list
m_passthruServers.setServerList(addrStr.toString());
}
else
throw new AlfrescoRuntimeException("No local server address(es)");
}
catch ( UnknownHostException ex)
{
throw new AlfrescoRuntimeException("Failed to get local address list");
}
}
m_passthruServerFactory.setLocalServer(Boolean.parseBoolean(useLocal));
}
/**
@@ -379,7 +332,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param guest String
*/
@Managed(category="Security")
public void setGuestAccess(String guest)
{
m_allowGuest = Boolean.parseBoolean(guest);
@@ -390,7 +342,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param auth String
*/
@Managed(category="Security")
public void setAllowAuthUserAsGuest(String auth)
{
m_allowAuthUserAsGuest = Boolean.parseBoolean(auth);
@@ -401,7 +352,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param nullDomain String
*/
@Managed(category="Security")
public void setNullDomainUseAnyServer(String nullDomain)
{
m_nullDomainUseAnyServer = Boolean.parseBoolean(nullDomain);
@@ -416,7 +366,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param providerClass String
*/
@Managed(category="Security")
public void setJCEProvider(String providerClass)
{
// Set the JCE provider, required to provide various encryption/hashing algorithms not available
@@ -464,7 +413,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param sessTmo String
*/
@Managed(category="Security")
public void setSessionTimeout(String sessTmo)
{
// Convert to an integer value and range check the timeout value
@@ -497,7 +445,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
*
* @param protoOrder String
*/
@Managed(category="Security")
public void setProtocolOrder(String protoOrder)
{
// Parse the protocol order list