Merged V2.0 to HEAD

5523: Merged V1.4 to V2.0
      5494: db.schema.update=false disables ALL metadata queries
      5500: AR-1399 NTProtocolHander search handle leakage
      5522: AR-1412 IndexRemoteTransactionTracker startup
   5541: Merged V1.4 to V2.0
      5525: Pass-through authentication and domain mapping
         Resolved minor conflict on AlfrescoAuthenticator.java
      5526: Domain mapping support


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5546 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-04-25 02:44:53 +00:00
parent 08897ad76b
commit fb1dd4080b
24 changed files with 885 additions and 74 deletions

View File

@@ -245,7 +245,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
{
// Create an authentication token for the session
NTLMPassthruToken authToken = new NTLMPassthruToken();
NTLMPassthruToken authToken = new NTLMPassthruToken( mapClientAddressToDomain( sess.getRemoteAddress()));
// Run the first stage of the passthru authentication to get the challenge

View File

@@ -24,8 +24,11 @@
*/
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;
@@ -33,7 +36,11 @@ 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;
@@ -53,6 +60,7 @@ 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;
@@ -969,4 +977,44 @@ public abstract class CifsAuthenticator
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;
}
}

View File

@@ -1119,6 +1119,8 @@ public class AuthenticateSession
if (getPCShare().hasDomain())
pkt.packString(getPCShare().getDomain(), false);
else if ( domain != null)
pkt.packString( domain, false);
else
pkt.packString("?", false);

View File

@@ -0,0 +1,58 @@
/*
* 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);
}

View File

@@ -358,7 +358,11 @@ public class PassthruAuthenticator extends CifsAuthenticator implements SessionL
try
{
AuthenticateSession authSess = m_passthruServers.openSession();
// Try and map the client address to a domain
String domain = mapClientAddressToDomain( sess.getRemoteAddress());
AuthenticateSession authSess = m_passthruServers.openSession( false, domain);
if (authSess != null)
{

View File

@@ -126,6 +126,16 @@ public class PassthruServerDetails
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
*

View File

@@ -306,27 +306,34 @@ public class PassthruServers
*/
public final AuthenticateSession openSession()
{
return openSession( false);
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)
public final AuthenticateSession openSession(boolean useExtSec, String clientDomain)
{
// Get the details of an authentication server to connect to
// Get the details of an authentication server to connect to
PassthruServerDetails passthruServer = getAuthenticationServer();
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);
logger.debug("Open authenticate session to " + passthruServer + ( clientDomain != null ? " (routed for client domain " + clientDomain + ")" : ""));
// Open a new authentication session to the server
@@ -402,6 +409,49 @@ public class PassthruServers
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
*
@@ -502,6 +552,17 @@ public class PassthruServers
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.
@@ -549,7 +610,7 @@ public class PassthruServers
{
// Create the passthru server details
PassthruServerDetails passthruServer = new PassthruServerDetails(srvName, null, srvAddr, false);
PassthruServerDetails passthruServer = new PassthruServerDetails(srvName, domain, srvAddr, false);
m_offlineList.add( passthruServer);
// Debug

View File

@@ -0,0 +1,101 @@
/*
* 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();
}
}

View File

@@ -0,0 +1,101 @@
/*
* 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();
}
}