mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
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:
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
@@ -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)
|
||||
{
|
||||
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user