Separate SharePoint claim space authority into an AD authority and a SharePoint Native authority.
git-svn-id: https://svn.apache.org/repos/asf/manifoldcf/branches/CONNECTORS-754-2@1536145 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/build.xml b/build.xml
index cb2c5bd..98d0de5 100644
--- a/build.xml
+++ b/build.xml
@@ -2414,7 +2414,12 @@
</antcall>
<antcall target="general-add-authority-connector">
<param name="connector-name" value="sharepoint"/>
- <param name="connector-label" value="SharePoint"/>
+ <param name="connector-label" value="SharePoint/ActiveDirectory"/>
+ <param name="connector-class" value="org.apache.manifoldcf.authorities.authorities.sharepoint.SharePointADAuthority"/>
+ </antcall>
+ <antcall target="general-add-authority-connector">
+ <param name="connector-name" value="sharepoint"/>
+ <param name="connector-label" value="SharePoint/Native"/>
<param name="connector-class" value="org.apache.manifoldcf.authorities.authorities.sharepoint.SharePointAuthority"/>
</antcall>
</target>
diff --git a/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointADAuthority.java b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointADAuthority.java
new file mode 100644
index 0000000..474a066
--- /dev/null
+++ b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointADAuthority.java
@@ -0,0 +1,1107 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* 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.apache.manifoldcf.authorities.authorities.sharepoint;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.*;
+import org.apache.manifoldcf.authorities.interfaces.*;
+import org.apache.manifoldcf.authorities.system.Logging;
+import org.apache.manifoldcf.authorities.system.ManifoldCF;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.concurrent.TimeUnit;
+import javax.naming.*;
+import javax.naming.ldap.*;
+import javax.naming.directory.*;
+
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.NTCredentials;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.util.EntityUtils;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.protocol.HttpContext;
+
+
+/** This is the Active Directory implementation of the IAuthorityConnector interface, as used
+* by SharePoint in Claim Space. It is meant to be used in conjunction with other SharePoint authorities,
+* and should ONLY be used if SharePoint native authorization is being performed in ClaimSpace mode.
+*/
+public class SharePointADAuthority extends org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector
+{
+ public static final String _rcsid = "@(#)$Id$";
+
+ // Data from the parameters
+
+ /** The list of suffixes and the associated domain controllers */
+ private List<DCRule> dCRules = null;
+ /** How to create a connection for a DC, keyed by DC name */
+ private Map<String,DCConnectionParameters> dCConnectionParameters = null;
+
+ private boolean hasSessionParameters = false;
+ private String cacheLifetime = null;
+ private String cacheLRUsize = null;
+ private long responseLifetime = 60000L;
+ private int LRUsize = 1000;
+
+ /** Session information for all DC's we talk with. */
+ private Map<String,DCSessionInfo> sessionInfo = null;
+
+ /** Cache manager. */
+ private ICacheManager cacheManager = null;
+
+ /** The length of time in milliseconds that an connection remains idle before expiring. Currently 5 minutes. */
+ private static final long ADExpirationInterval = 300000L;
+
+ /** Constructor.
+ */
+ public SharePointADAuthority()
+ {
+ }
+
+ /** Set thread context.
+ */
+ @Override
+ public void setThreadContext(IThreadContext tc)
+ throws ManifoldCFException
+ {
+ super.setThreadContext(tc);
+ cacheManager = CacheManagerFactory.make(tc);
+ }
+
+ /** Clear thread context.
+ */
+ @Override
+ public void clearThreadContext()
+ {
+ super.clearThreadContext();
+ cacheManager = null;
+ }
+
+ /** Connect. The configuration parameters are included.
+ *@param configParams are the configuration parameters for this connection.
+ */
+ @Override
+ public void connect(ConfigParams configParams)
+ {
+ super.connect(configParams);
+
+
+ // Allocate the session data, currently empty
+ sessionInfo = new HashMap<String,DCSessionInfo>();
+
+ // Set up the DC param set, and the rules
+ dCRules = new ArrayList<DCRule>();
+ dCConnectionParameters = new HashMap<String,DCConnectionParameters>();
+ // Read DC info from the config parameters
+ for (int i = 0; i < params.getChildCount(); i++)
+ {
+ ConfigNode cn = params.getChild(i);
+ if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
+ {
+ // Domain controller name is the actual key...
+ String dcName = cn.getAttributeValue(SharePointConfig.ATTR_DOMAINCONTROLLER);
+ // Set up the parameters for the domain controller
+ dCConnectionParameters.put(dcName,new DCConnectionParameters(cn.getAttributeValue(SharePointConfig.ATTR_USERNAME),
+ deobfuscate(cn.getAttributeValue(SharePointConfig.ATTR_PASSWORD)),
+ cn.getAttributeValue(SharePointConfig.ATTR_AUTHENTICATION),
+ cn.getAttributeValue(SharePointConfig.ATTR_USERACLsUSERNAME)));
+ // Order-based rule, as well
+ dCRules.add(new DCRule(cn.getAttributeValue(SharePointConfig.ATTR_SUFFIX),dcName));
+ }
+ }
+
+ cacheLifetime = params.getParameter(SharePointConfig.PARAM_CACHELIFETIME);
+ if (cacheLifetime == null)
+ cacheLifetime = "1";
+ cacheLRUsize = params.getParameter(SharePointConfig.PARAM_CACHELRUSIZE);
+ if (cacheLRUsize == null)
+ cacheLRUsize = "1000";
+ }
+
+ protected static String deobfuscate(String input)
+ {
+ if (input == null)
+ return null;
+ try
+ {
+ return ManifoldCF.deobfuscate(input);
+ }
+ catch (ManifoldCFException e)
+ {
+ return "";
+ }
+ }
+
+ // All methods below this line will ONLY be called if a connect() call succeeded
+ // on this instance!
+
+ /** Check connection for sanity.
+ */
+ @Override
+ public String check()
+ throws ManifoldCFException
+ {
+ // Set up the basic AD session...
+ getSessionParameters();
+ // Clear the DC session info, so we're forced to redo it
+ for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
+ {
+ sessionEntry.getValue().closeConnection();
+ }
+ // Loop through all domain controllers and attempt to establish a session with each one.
+ for (String domainController : dCConnectionParameters.keySet())
+ {
+ createDCSession(domainController);
+ }
+
+ return super.check();
+ }
+
+ /** Create or lookup a session for a domain controller.
+ */
+ protected LdapContext createDCSession(String domainController)
+ throws ManifoldCFException
+ {
+ getSessionParameters();
+ DCConnectionParameters parms = dCConnectionParameters.get(domainController);
+ // Find the session in the hash, if it exists
+ DCSessionInfo session = sessionInfo.get(domainController);
+ if (session == null)
+ {
+ session = new DCSessionInfo();
+ sessionInfo.put(domainController,session);
+ }
+ return session.getADSession(domainController,parms);
+ }
+
+ /** Poll. The connection should be closed if it has been idle for too long.
+ */
+ @Override
+ public void poll()
+ throws ManifoldCFException
+ {
+ long currentTime = System.currentTimeMillis();
+ for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
+ {
+ sessionEntry.getValue().closeIfExpired(currentTime);
+ }
+ super.poll();
+ }
+
+ /** Close the connection. Call this before discarding the repository connector.
+ */
+ @Override
+ public void disconnect()
+ throws ManifoldCFException
+ {
+ // Clean up caching parameters
+
+ cacheLifetime = null;
+ cacheLRUsize = null;
+
+ // Clean up AD parameters
+
+ hasSessionParameters = false;
+
+ // Close all connections
+ for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
+ {
+ sessionEntry.getValue().closeConnection();
+ }
+ sessionInfo = null;
+
+ super.disconnect();
+ }
+
+ /** Obtain the access tokens for a given user name.
+ *@param userName is the user name or identifier.
+ *@return the response tokens (according to the current authority).
+ * (Should throws an exception only when a condition cannot be properly described within the authorization response object.)
+ */
+ @Override
+ public AuthorizationResponse getAuthorizationResponse(String userName)
+ throws ManifoldCFException
+ {
+ // This sets up parameters we need to construct the response description
+ getSessionParameters();
+
+ // Construct a cache description object
+ ICacheDescription objectDescription = new AuthorizationResponseDescription(userName,
+ dCConnectionParameters,dCRules,this.responseLifetime,this.LRUsize);
+
+ // Enter the cache
+ ICacheHandle ch = cacheManager.enterCache(new ICacheDescription[]{objectDescription},null,null);
+ try
+ {
+ ICacheCreateHandle createHandle = cacheManager.enterCreateSection(ch);
+ try
+ {
+ // Lookup the object
+ AuthorizationResponse response = (AuthorizationResponse)cacheManager.lookupObject(createHandle,objectDescription);
+ if (response != null)
+ return response;
+ // Create the object.
+ response = getAuthorizationResponseUncached(userName);
+ // Save it in the cache
+ cacheManager.saveObject(createHandle,objectDescription,response);
+ // And return it...
+ return response;
+ }
+ finally
+ {
+ cacheManager.leaveCreateSection(createHandle);
+ }
+ }
+ finally
+ {
+ cacheManager.leaveCache(ch);
+ }
+ }
+
+ /** Obtain the access tokens for a given user name, uncached.
+ *@param userName is the user name or identifier.
+ *@return the response tokens (according to the current authority).
+ * (Should throws an exception only when a condition cannot be properly described within the authorization response object.)
+ */
+ protected AuthorizationResponse getAuthorizationResponseUncached(String userName)
+ throws ManifoldCFException
+ {
+ //String searchBase = "CN=Administrator,CN=Users,DC=qa-ad-76,DC=metacarta,DC=com";
+ int index = userName.indexOf("@");
+ if (index == -1)
+ throw new ManifoldCFException("Username is in unexpected form (no @): '"+userName+"'");
+
+ String userPart = userName.substring(0,index);
+ String domainPart = userName.substring(index+1);
+
+ try
+ {
+ List<String> adTokens = getADTokens(userPart,domainPart,userName);
+ if (adTokens == null)
+ return RESPONSE_USERNOTFOUND_ADDITIVE;
+ return new AuthorizationResponse(adTokens.toArray(new String[0]),AuthorizationResponse.RESPONSE_OK);
+ }
+ catch (NameNotFoundException e)
+ {
+ // This means that the user doesn't exist
+ return RESPONSE_USERNOTFOUND_ADDITIVE;
+ }
+ catch (NamingException e)
+ {
+ // Unreachable
+ return RESPONSE_UNREACHABLE_ADDITIVE;
+ }
+
+ }
+
+ /** Obtain the default access tokens for a given user name.
+ *@param userName is the user name or identifier.
+ *@return the default response tokens, presuming that the connect method fails.
+ */
+ @Override
+ public AuthorizationResponse getDefaultAuthorizationResponse(String userName)
+ {
+ // The default response if the getConnection method fails
+ return RESPONSE_UNREACHABLE_ADDITIVE;
+ }
+
+ /** Get the AD-derived access tokens for a user and domain */
+ protected List<String> getADTokens(String userPart, String domainPart, String userName)
+ throws NameNotFoundException, NamingException, ManifoldCFException
+ {
+ // Now, look through the rules for the matching domain controller
+ String domainController = null;
+ for (DCRule rule : dCRules)
+ {
+ String suffix = rule.getSuffix();
+ if (suffix.length() == 0 || domainPart.toLowerCase(Locale.ROOT).endsWith(suffix.toLowerCase(Locale.ROOT)) &&
+ (suffix.length() == domainPart.length() || domainPart.charAt((domainPart.length()-suffix.length())-1) == '.'))
+ {
+ domainController = rule.getDomainControllerName();
+ break;
+ }
+ }
+
+ if (domainController == null)
+ // No AD user
+ return null;
+
+ // Look up connection parameters
+ DCConnectionParameters dcParams = dCConnectionParameters.get(domainController);
+ if (dcParams == null)
+ // No AD user
+ return null;
+
+ // Use the complete fqn if the field is the "userPrincipalName"
+ String userBase;
+ String userACLsUsername = dcParams.getUserACLsUsername();
+ if (userACLsUsername != null && userACLsUsername.equals("userPrincipalName")){
+ userBase = userName;
+ }
+ else
+ {
+ userBase = userPart;
+ }
+
+ //Build the DN searchBase from domain part
+ StringBuilder domainsb = new StringBuilder();
+ int j = 0;
+ while (true)
+ {
+ if (j > 0)
+ domainsb.append(",");
+
+ int k = domainPart.indexOf(".",j);
+ if (k == -1)
+ {
+ domainsb.append("DC=").append(ldapEscape(domainPart.substring(j)));
+ break;
+ }
+ domainsb.append("DC=").append(ldapEscape(domainPart.substring(j,k)));
+ j = k+1;
+ }
+
+ // Establish a session with the selected domain controller
+ LdapContext ctx = createDCSession(domainController);
+
+ //Get DistinguishedName (for this method we are using DomainPart as a searchBase ie: DC=qa-ad-76,DC=metacarta,DC=com")
+ String searchBase = getDistinguishedName(ctx, userBase, domainsb.toString(), userACLsUsername);
+ if (searchBase == null)
+ return null;
+
+ //specify the LDAP search filter
+ String searchFilter = "(objectClass=user)";
+
+ //Create the search controls for finding the access tokens
+ SearchControls searchCtls = new SearchControls();
+
+ //Specify the search scope, must be base level search for tokenGroups
+ searchCtls.setSearchScope(SearchControls.OBJECT_SCOPE);
+
+ //Specify the attributes to return
+ String returnedAtts[]={"tokenGroups","objectSid"};
+ searchCtls.setReturningAttributes(returnedAtts);
+
+ //Search for tokens. Since every user *must* have a SID, the "no user" detection should be safe.
+ NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
+
+ List<String> theGroups = new ArrayList<String>();
+ String userToken = userTokenFromLoginName(domainPart + "\\" + userPart);
+ if (userToken != null)
+ theGroups.add(userToken);
+
+ //Loop through the search results
+ while (answer.hasMoreElements())
+ {
+ SearchResult sr = (SearchResult)answer.next();
+
+ //the sr.GetName should be null, as it is relative to the base object
+
+ Attributes attrs = sr.getAttributes();
+ if (attrs != null)
+ {
+ try
+ {
+ for (NamingEnumeration ae = attrs.getAll();ae.hasMore();)
+ {
+ Attribute attr = (Attribute)ae.next();
+ for (NamingEnumeration e = attr.getAll();e.hasMore();)
+ {
+ String sid = sid2String((byte[])e.next());
+ String token = attr.getID().equals("objectSid")?userTokenFromSID(sid):groupTokenFromSID(sid);
+ theGroups.add(token);
+ }
+ }
+ }
+ catch (NamingException e)
+ {
+ throw new ManifoldCFException(e.getMessage(),e);
+ }
+ }
+ }
+
+ if (theGroups.size() == 0)
+ return null;
+
+ // User is in AD, so add the 'everyone' group
+ theGroups.add(everyoneGroup());
+ return theGroups;
+ }
+
+ protected static String everyoneGroup()
+ {
+ return "c:0!.s|windows";
+ }
+
+ protected static String groupTokenFromSID(String SID)
+ {
+ return "c:0+.w|"+SID.toLowerCase(Locale.ROOT);
+ }
+
+ protected static String userTokenFromSID(String SID)
+ {
+ return "i:0+.w|"+SID.toLowerCase(Locale.ROOT);
+ }
+
+ protected static String userTokenFromLoginName(String loginName)
+ {
+ try
+ {
+ return "i:0#.w|"+URLEncoder.encode(loginName,"utf-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("Utf-8 encoding unrecognized");
+ }
+ }
+
+ // UI support methods.
+ //
+ // These support methods are involved in setting up authority connection configuration information. The configuration methods cannot assume that the
+ // current authority object is connected. That is why they receive a thread context argument.
+
+ /** Output the configuration header section.
+ * This method is called in the head section of the connector's configuration page. Its purpose is to add the required tabs to the list, and to output any
+ * javascript methods that might be needed by the configuration editing HTML.
+ *@param threadContext is the local thread context.
+ *@param out is the output to which any HTML should be sent.
+ *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
+ *@param tabsArray is an array of tab names. Add to this array any tab names that are specific to the connector.
+ */
+ @Override
+ public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters, List<String> tabsArray)
+ throws ManifoldCFException, IOException
+ {
+ tabsArray.add(Messages.getString(locale,"SharePointAuthority.DomainController"));
+ tabsArray.add(Messages.getString(locale,"SharePointAuthority.Cache"));
+ Messages.outputResourceWithVelocity(out,locale,"editADConfiguration.js",null);
+ }
+
+ /** Output the configuration body section.
+ * This method is called in the body section of the authority connector's configuration page. Its purpose is to present the required form elements for editing.
+ * The coder can presume that the HTML that is output from this configuration will be within appropriate <html>, <body>, and <form> tags. The name of the
+ * form is "editconnection".
+ *@param threadContext is the local thread context.
+ *@param out is the output to which any HTML should be sent.
+ *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
+ *@param tabName is the current tab name.
+ */
+ @Override
+ public void outputConfigurationBody(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters, String tabName)
+ throws ManifoldCFException, IOException
+ {
+ Map<String,Object> velocityContext = new HashMap<String,Object>();
+ velocityContext.put("TabName",tabName);
+ fillInDomainControllerTab(velocityContext,out,parameters);
+ fillInCacheTab(velocityContext,out,parameters);
+ Messages.outputResourceWithVelocity(out,locale,"editADConfiguration_DomainController.html",velocityContext);
+ Messages.outputResourceWithVelocity(out,locale,"editADConfiguration_Cache.html",velocityContext);
+ }
+
+ protected static void fillInDomainControllerTab(Map<String,Object> velocityContext, IPasswordMapperActivity mapper, ConfigParams parameters)
+ {
+ List<Map<String,String>> domainControllers = new ArrayList<Map<String,String>>();
+
+ // Go through nodes looking for DC nodes
+ for (int i = 0; i < parameters.getChildCount(); i++)
+ {
+ ConfigNode cn = parameters.getChild(i);
+ if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
+ {
+ // Grab the info
+ String dcSuffix = cn.getAttributeValue(SharePointConfig.ATTR_SUFFIX);
+ String dcDomainController = cn.getAttributeValue(SharePointConfig.ATTR_DOMAINCONTROLLER);
+ String dcUserName = cn.getAttributeValue(SharePointConfig.ATTR_USERNAME);
+ String dcPassword = deobfuscate(cn.getAttributeValue(SharePointConfig.ATTR_PASSWORD));
+ String dcAuthentication = cn.getAttributeValue(SharePointConfig.ATTR_AUTHENTICATION);
+ String dcUserACLsUsername = cn.getAttributeValue(SharePointConfig.ATTR_USERACLsUSERNAME);
+ domainControllers.add(createDomainControllerMap(mapper,dcSuffix,dcDomainController,dcUserName,dcPassword,dcAuthentication,dcUserACLsUsername));
+ }
+ }
+ velocityContext.put("DOMAINCONTROLLERS",domainControllers);
+ }
+
+ protected static Map<String,String> createDomainControllerMap(IPasswordMapperActivity mapper, String suffix, String domainControllerName,
+ String userName, String password, String authentication, String userACLsUsername)
+ {
+ Map<String,String> defaultMap = new HashMap<String,String>();
+ if (suffix != null)
+ defaultMap.put("SUFFIX",suffix);
+ if (domainControllerName != null)
+ defaultMap.put("DOMAINCONTROLLER",domainControllerName);
+ if (userName != null)
+ defaultMap.put("USERNAME",userName);
+ if (password != null)
+ defaultMap.put("PASSWORD",mapper.mapPasswordToKey(password));
+ if (authentication != null)
+ defaultMap.put("AUTHENTICATION",authentication);
+ if (userACLsUsername != null)
+ defaultMap.put("USERACLsUSERNAME",userACLsUsername);
+ return defaultMap;
+ }
+
+ protected static void fillInCacheTab(Map<String,Object> velocityContext, IPasswordMapperActivity mapper, ConfigParams parameters)
+ {
+ String cacheLifetime = parameters.getParameter(SharePointConfig.PARAM_CACHELIFETIME);
+ if (cacheLifetime == null)
+ cacheLifetime = "1";
+ velocityContext.put("CACHELIFETIME",cacheLifetime);
+ String cacheLRUsize = parameters.getParameter(SharePointConfig.PARAM_CACHELRUSIZE);
+ if (cacheLRUsize == null)
+ cacheLRUsize = "1000";
+ velocityContext.put("CACHELRUSIZE",cacheLRUsize);
+ }
+
+ /** Process a configuration post.
+ * This method is called at the start of the authority connector's configuration page, whenever there is a possibility that form data for a connection has been
+ * posted. Its purpose is to gather form information and modify the configuration parameters accordingly.
+ * The name of the posted form is "editconnection".
+ *@param threadContext is the local thread context.
+ *@param variableContext is the set of variables available from the post, including binary file post information.
+ *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
+ *@return null if all is well, or a string error message if there is an error that should prevent saving of the connection (and cause a redirection to an error page).
+ */
+ @Override
+ public String processConfigurationPost(IThreadContext threadContext, IPostParameters variableContext, Locale locale, ConfigParams parameters)
+ throws ManifoldCFException
+ {
+ String x = variableContext.getParameter("dcrecord_count");
+ if (x != null)
+ {
+ // Delete old nodes
+ int i = 0;
+ while (i < parameters.getChildCount())
+ {
+ ConfigNode cn = parameters.getChild(i);
+ if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
+ parameters.removeChild(i);
+ else
+ i++;
+ }
+ // Scan form fields and apply operations
+ int count = Integer.parseInt(x);
+ i = 0;
+ String op;
+
+ Set<String> seenDomains = new HashSet<String>();
+
+ while (i < count)
+ {
+ op = variableContext.getParameter("dcrecord_op_"+i);
+ if (op != null && op.equals("Insert"))
+ {
+ // Insert a new record right here
+ addDomainController(seenDomains,parameters,
+ variableContext.getParameter("dcrecord_suffix"),
+ variableContext.getParameter("dcrecord_domaincontrollername"),
+ variableContext.getParameter("dcrecord_username"),
+ variableContext.mapKeyToPassword(variableContext.getParameter("dcrecord_password")),
+ variableContext.getParameter("dcrecord_authentication"),
+ variableContext.getParameter("dcrecord_userACLsUsername"));
+ }
+ if (op == null || !op.equals("Delete"))
+ {
+ // Add this record back in
+ addDomainController(seenDomains,parameters,
+ variableContext.getParameter("dcrecord_suffix_"+i),
+ variableContext.getParameter("dcrecord_domaincontrollername_"+i),
+ variableContext.getParameter("dcrecord_username_"+i),
+ variableContext.mapKeyToPassword(variableContext.getParameter("dcrecord_password_"+i)),
+ variableContext.getParameter("dcrecord_authentication_"+i),
+ variableContext.getParameter("dcrecord_userACLsUsername_"+i));
+ }
+ i++;
+ }
+ op = variableContext.getParameter("dcrecord_op");
+ if (op != null && op.equals("Add"))
+ {
+ // Insert a new record right here
+ addDomainController(seenDomains,parameters,
+ variableContext.getParameter("dcrecord_suffix"),
+ variableContext.getParameter("dcrecord_domaincontrollername"),
+ variableContext.getParameter("dcrecord_username"),
+ variableContext.getParameter("dcrecord_password"),
+ variableContext.getParameter("dcrecord_authentication"),
+ variableContext.getParameter("dcrecord_userACLsUsername"));
+ }
+ }
+
+ // Cache parameters
+
+ String cacheLifetime = variableContext.getParameter("cachelifetime");
+ if (cacheLifetime != null)
+ parameters.setParameter(SharePointConfig.PARAM_CACHELIFETIME,cacheLifetime);
+ String cacheLRUsize = variableContext.getParameter("cachelrusize");
+ if (cacheLRUsize != null)
+ parameters.setParameter(SharePointConfig.PARAM_CACHELRUSIZE,cacheLRUsize);
+
+ return null;
+ }
+
+ protected static void addDomainController(Set<String> seenDomains, ConfigParams parameters,
+ String suffix, String domainControllerName, String userName, String password, String authentication,
+ String userACLsUsername)
+ throws ManifoldCFException
+ {
+ if (!seenDomains.contains(domainControllerName))
+ {
+ ConfigNode cn = new ConfigNode(SharePointConfig.NODE_DOMAINCONTROLLER);
+ cn.setAttribute(SharePointConfig.ATTR_SUFFIX,suffix);
+ cn.setAttribute(SharePointConfig.ATTR_DOMAINCONTROLLER,domainControllerName);
+ cn.setAttribute(SharePointConfig.ATTR_USERNAME,userName);
+ cn.setAttribute(SharePointConfig.ATTR_PASSWORD,ManifoldCF.obfuscate(password));
+ cn.setAttribute(SharePointConfig.ATTR_AUTHENTICATION,authentication);
+ cn.setAttribute(SharePointConfig.ATTR_USERACLsUSERNAME,userACLsUsername);
+ parameters.addChild(parameters.getChildCount(),cn);
+ seenDomains.add(domainControllerName);
+ }
+ }
+
+ /** View configuration.
+ * This method is called in the body section of the authority connector's view configuration page. Its purpose is to present the connection information to the user.
+ * The coder can presume that the HTML that is output from this configuration will be within appropriate <html> and <body> tags.
+ *@param threadContext is the local thread context.
+ *@param out is the output to which any HTML should be sent.
+ *@param parameters are the configuration parameters, as they currently exist, for this connection being configured.
+ */
+ @Override
+ public void viewConfiguration(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters)
+ throws ManifoldCFException, IOException
+ {
+ Map<String,Object> velocityContext = new HashMap<String,Object>();
+ fillInDomainControllerTab(velocityContext,out,parameters);
+ fillInCacheTab(velocityContext,out,parameters);
+ Messages.outputResourceWithVelocity(out,locale,"viewADConfiguration.html",velocityContext);
+ }
+
+ // Protected methods
+
+ /** Get parameters needed for caching.
+ */
+ protected void getSessionParameters()
+ throws ManifoldCFException
+ {
+ if (!hasSessionParameters)
+ {
+ try
+ {
+ responseLifetime = Long.parseLong(this.cacheLifetime) * 60L * 1000L;
+ LRUsize = Integer.parseInt(this.cacheLRUsize);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new ManifoldCFException("Cache lifetime or Cache LRU size must be an integer: "+e.getMessage(),e);
+ }
+ hasSessionParameters = true;
+ }
+ }
+
+ /** Obtain the DistinguishedName for a given user logon name.
+ *@param ctx is the ldap context to use.
+ *@param userName (Domain Logon Name) is the user name or identifier.
+ *@param searchBase (Full Domain Name for the search ie: DC=qa-ad-76,DC=metacarta,DC=com)
+ *@return DistinguishedName for given domain user logon name.
+ * (Should throws an exception if user is not found.)
+ */
+ protected String getDistinguishedName(LdapContext ctx, String userName, String searchBase, String userACLsUsername)
+ throws ManifoldCFException
+ {
+ String returnedAtts[] = {"distinguishedName"};
+ String searchFilter = "(&(objectClass=user)(" + userACLsUsername + "=" + userName + "))";
+ SearchControls searchCtls = new SearchControls();
+ searchCtls.setReturningAttributes(returnedAtts);
+ //Specify the search scope
+ searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ searchCtls.setReturningAttributes(returnedAtts);
+
+ try
+ {
+ NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
+ while (answer.hasMoreElements())
+ {
+ SearchResult sr = (SearchResult)answer.next();
+ Attributes attrs = sr.getAttributes();
+ if (attrs != null)
+ {
+ String dn = attrs.get("distinguishedName").get().toString();
+ return dn;
+ }
+ }
+ return null;
+ }
+ catch (NamingException e)
+ {
+ throw new ManifoldCFException(e.getMessage(),e);
+ }
+ }
+
+ /** LDAP escape a string.
+ */
+ protected static String ldapEscape(String input)
+ {
+ //Add escape sequence to all commas
+ StringBuilder sb = new StringBuilder();
+ int index = 0;
+ while (true)
+ {
+ int oldIndex = index;
+ index = input.indexOf(",",oldIndex);
+ if (index == -1)
+ {
+ sb.append(input.substring(oldIndex));
+ break;
+ }
+ sb.append(input.substring(oldIndex,index)).append("\\,");
+ index++;
+ }
+ return sb.toString();
+ }
+
+ /** Convert a binary SID to a string */
+ protected static String sid2String(byte[] SID)
+ {
+ StringBuilder strSID = new StringBuilder("S");
+ long version = SID[0];
+ strSID.append("-").append(Long.toString(version));
+ long authority = SID[4];
+ for (int i = 0;i<4;i++)
+ {
+ authority <<= 8;
+ authority += SID[4+i] & 0xFF;
+ }
+ strSID.append("-").append(Long.toString(authority));
+ long count = SID[2];
+ count <<= 8;
+ count += SID[1] & 0xFF;
+ for (int j=0;j<count;j++)
+ {
+ long rid = SID[11 + (j*4)] & 0xFF;
+ for (int k=1;k<4;k++)
+ {
+ rid <<= 8;
+ rid += SID[11-k + (j*4)] & 0xFF;
+ }
+ strSID.append("-").append(Long.toString(rid));
+ }
+ return strSID.toString();
+ }
+
+ /** Class representing the session information for a specific domain controller
+ * connection.
+ */
+ protected static class DCSessionInfo
+ {
+ /** The initialized LDAP context (which functions as a session) */
+ private LdapContext ctx = null;
+ /** The time of last access to this ctx object */
+ private long expiration = -1L;
+
+ public DCSessionInfo()
+ {
+ }
+
+ /** Initialize the session. */
+ public LdapContext getADSession(String domainControllerName, DCConnectionParameters params)
+ throws ManifoldCFException
+ {
+ String authentication = params.getAuthentication();
+ String userName = params.getUserName();
+ String password = params.getPassword();
+
+ while (true)
+ {
+ if (ctx == null)
+ {
+ // Calculate the ldap url first
+ String ldapURL = "ldap://" + domainControllerName + ":389";
+
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.SECURITY_AUTHENTICATION,authentication);
+ env.put(Context.SECURITY_PRINCIPAL,userName);
+ env.put(Context.SECURITY_CREDENTIALS,password);
+
+ //connect to my domain controller
+ env.put(Context.PROVIDER_URL,ldapURL);
+
+ //specify attributes to be returned in binary format
+ env.put("java.naming.ldap.attributes.binary","tokenGroups objectSid");
+
+ // Now, try the connection...
+ try
+ {
+ ctx = new InitialLdapContext(env,null);
+ // If successful, break
+ break;
+ }
+ catch (AuthenticationException e)
+ {
+ // This means we couldn't authenticate!
+ throw new ManifoldCFException("Authentication problem authenticating admin user '"+userName+"': "+e.getMessage(),e);
+ }
+ catch (CommunicationException e)
+ {
+ // This means we couldn't connect, most likely
+ throw new ManifoldCFException("Couldn't communicate with domain controller '"+domainControllerName+"': "+e.getMessage(),e);
+ }
+ catch (NamingException e)
+ {
+ throw new ManifoldCFException(e.getMessage(),e);
+ }
+ }
+ else
+ {
+ // Attempt to reconnect. I *hope* this is efficient and doesn't do unnecessary work.
+ try
+ {
+ ctx.reconnect(null);
+ // Break on apparent success
+ break;
+ }
+ catch (AuthenticationException e)
+ {
+ // This means we couldn't authenticate! Log it and retry creating a whole new context.
+ Logging.authorityConnectors.warn("Reconnect: Authentication problem authenticating admin user '"+userName+"': "+e.getMessage(),e);
+ }
+ catch (CommunicationException e)
+ {
+ // This means we couldn't connect, most likely. Log it and retry creating a whole new context.
+ Logging.authorityConnectors.warn("Reconnect: Couldn't communicate with domain controller '"+domainControllerName+"': "+e.getMessage(),e);
+ }
+ catch (NamingException e)
+ {
+ Logging.authorityConnectors.warn("Reconnect: Naming exception: "+e.getMessage(),e);
+ }
+
+ // So we have no chance of leaking resources, attempt to close the context.
+ closeConnection();
+ // Loop back around to try our luck with a fresh connection.
+
+ }
+ }
+
+ // Set the expiration time anew
+ expiration = System.currentTimeMillis() + ADExpirationInterval;
+ return ctx;
+ }
+
+ /** Close the connection handle. */
+ protected void closeConnection()
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException e)
+ {
+ // Eat this error
+ }
+ ctx = null;
+ expiration = -1L;
+ }
+ }
+
+ /** Close connection if it has expired. */
+ protected void closeIfExpired(long currentTime)
+ {
+ if (expiration != -1L && currentTime > expiration)
+ closeConnection();
+ }
+
+ }
+
+ /** Class describing a domain suffix and corresponding domain controller name rule.
+ */
+ protected static class DCRule
+ {
+ private String suffix;
+ private String domainControllerName;
+
+ public DCRule(String suffix, String domainControllerName)
+ {
+ this.suffix = suffix;
+ this.domainControllerName = domainControllerName;
+ }
+
+ public String getSuffix()
+ {
+ return suffix;
+ }
+
+ public String getDomainControllerName()
+ {
+ return domainControllerName;
+ }
+ }
+
+ /** Class describing the connection parameters to a domain controller.
+ */
+ protected static class DCConnectionParameters
+ {
+ private String userName;
+ private String password;
+ private String authentication;
+ private String userACLsUsername;
+
+ public DCConnectionParameters(String userName, String password, String authentication, String userACLsUsername)
+ {
+ this.userName = userName;
+ this.password = password;
+ this.authentication = authentication;
+ this.userACLsUsername = userACLsUsername;
+ }
+
+ public String getUserName()
+ {
+ return userName;
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+ public String getAuthentication()
+ {
+ return authentication;
+ }
+
+ public String getUserACLsUsername()
+ {
+ return userACLsUsername;
+ }
+ }
+
+ protected static StringSet emptyStringSet = new StringSet();
+
+ /** This is the cache object descriptor for cached access tokens from
+ * this connector.
+ */
+ protected static class AuthorizationResponseDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription
+ {
+ /** The user name */
+ protected String userName;
+ /** Connection parameters */
+ protected Map<String,DCConnectionParameters> dcConnectionParams;
+ /** Rules */
+ protected List<DCRule> dcRules;
+ /** The response lifetime */
+ protected long responseLifetime;
+ /** The expiration time */
+ protected long expirationTime = -1;
+
+ /** Constructor. */
+ public AuthorizationResponseDescription(String userName, Map<String,DCConnectionParameters> dcConnectionParams,
+ List<DCRule> dcRules, long responseLifetime, int LRUsize)
+ {
+ super("SharePointADAuthority",LRUsize);
+ this.userName = userName;
+ this.dcConnectionParams = dcConnectionParams;
+ this.dcRules = dcRules;
+ this.responseLifetime = responseLifetime;
+ }
+
+ /** Return the invalidation keys for this object. */
+ public StringSet getObjectKeys()
+ {
+ return emptyStringSet;
+ }
+
+ /** Get the critical section name, used for synchronizing the creation of the object */
+ public String getCriticalSectionName()
+ {
+ StringBuilder sb = new StringBuilder(getClass().getName());
+ sb.append("-").append(userName);
+ for (DCRule rule : dcRules)
+ {
+ sb.append("-").append(rule.getSuffix());
+ String domainController = rule.getDomainControllerName();
+ DCConnectionParameters params = dcConnectionParams.get(domainController);
+ sb.append("-").append(domainController).append("-").append(params.getUserName()).append("-").append(params.getPassword());
+ }
+ return sb.toString();
+ }
+
+ /** Return the object expiration interval */
+ public long getObjectExpirationTime(long currentTime)
+ {
+ if (expirationTime == -1)
+ expirationTime = currentTime + responseLifetime;
+ return expirationTime;
+ }
+
+ public int hashCode()
+ {
+ int rval = userName.hashCode();
+ for (DCRule rule : dcRules)
+ {
+ String domainController = rule.getDomainControllerName();
+ DCConnectionParameters params = dcConnectionParams.get(domainController);
+ rval += rule.getSuffix().hashCode() + domainController.hashCode() + params.getUserName().hashCode() + params.getPassword().hashCode();
+ }
+ return rval;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof AuthorizationResponseDescription))
+ return false;
+ AuthorizationResponseDescription ard = (AuthorizationResponseDescription)o;
+ if (!ard.userName.equals(userName))
+ return false;
+ if (ard.dcRules.size() != dcRules.size())
+ return false;
+ for (int i = 0 ; i < dcRules.size() ; i++)
+ {
+ DCRule rule = dcRules.get(i);
+ DCRule ardRule = ard.dcRules.get(i);
+ if (!rule.getSuffix().equals(ardRule.getSuffix()) || !rule.getDomainControllerName().equals(ardRule.getDomainControllerName()))
+ return false;
+ String domainController = rule.getDomainControllerName();
+ DCConnectionParameters params = dcConnectionParams.get(domainController);
+ DCConnectionParameters ardParams = ard.dcConnectionParams.get(domainController);
+ if (!params.getUserName().equals(ardParams.getUserName()) || !params.getPassword().equals(ardParams.getPassword()))
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+}
+
+
diff --git a/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
index 0e24e63..fd59e68 100644
--- a/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
+++ b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointAuthority.java
@@ -54,10 +54,7 @@
import org.apache.http.protocol.HttpContext;
-/** This is the Active Directory implementation of the IAuthorityConnector interface.
-* Access tokens for this connector are simple SIDs, except for the "global deny" token, which
-* is designed to allow the authority to shut off access to all authorized documents when the
-* user is unrecognized or the domain controller does not respond.
+/** This is the native SharePoint implementation of the IAuthorityConnector interface.
*/
public class SharePointAuthority extends org.apache.manifoldcf.authorities.authorities.BaseAuthorityConnector
{
@@ -65,56 +62,46 @@
// Data from the parameters
- /** The list of suffixes and the associated domain controllers */
- private List<DCRule> dCRules = null;
- /** How to create a connection for a DC, keyed by DC name */
- private Map<String,DCConnectionParameters> dCConnectionParameters = null;
-
- private boolean hasSessionParameters = false;
- private String cacheLifetime = null;
- private String cacheLRUsize = null;
- private long responseLifetime = 60000L;
- private int LRUsize = 1000;
-
- /** Session information for all DC's we talk with. */
- private Map<String,DCSessionInfo> sessionInfo = null;
-
/** Cache manager. */
private ICacheManager cacheManager = null;
- /** The length of time in milliseconds that an connection remains idle before expiring. Currently 5 minutes. */
- private static final long ADExpirationInterval = 300000L;
+ private boolean hasSessionParameters = false;
/** Length of time that a SharePoint session can remain idle */
private static final long SharePointExpirationInterval = 300000L;
// SharePoint server parameters
-
+ // These are needed for caching, so they are set at connect() time
private String serverProtocol = null;
private String serverUrl = null;
private String fileBaseUrl = null;
- private String userName = null;
- private String strippedUserName = null;
+ private String serverUserName = null;
private String password = null;
private String ntlmDomain = null;
private String serverName = null;
+ private String serverPortString = null;
private String serverLocation = null;
+ private String strippedUserName = null;
private String encodedServerLocation = null;
- private int serverPort = -1;
-
- private SPSProxyHelper proxy = null;
-
- private boolean isClaimSpace = false;
+ private String keystoreData = null;
+ private String cacheLRUsize = null;
+ private String cacheLifetime = null;
+
+ // These are calculated when the session is set up
+ private int serverPort = -1;
+ private SPSProxyHelper proxy = null;
private long sharepointSessionTimeout;
- // SSL support
- private String keystoreData = null;
+ private long responseLifetime = -1L;
+ private int LRUsize = -1;
+
private IKeystoreManager keystoreManager = null;
private ClientConnectionManager connectionManager = null;
private HttpClient httpClient = null;
+
// Current host name
private static String currentHost = null;
static
@@ -165,53 +152,53 @@
{
super.connect(configParams);
-
- // Allocate the session data, currently empty
- sessionInfo = new HashMap<String,DCSessionInfo>();
-
- // Set up the DC param set, and the rules
- dCRules = new ArrayList<DCRule>();
- dCConnectionParameters = new HashMap<String,DCConnectionParameters>();
- // Read DC info from the config parameters
- for (int i = 0; i < params.getChildCount(); i++)
- {
- ConfigNode cn = params.getChild(i);
- if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
- {
- // Domain controller name is the actual key...
- String dcName = cn.getAttributeValue(SharePointConfig.ATTR_DOMAINCONTROLLER);
- // Set up the parameters for the domain controller
- dCConnectionParameters.put(dcName,new DCConnectionParameters(cn.getAttributeValue(SharePointConfig.ATTR_USERNAME),
- deobfuscate(cn.getAttributeValue(SharePointConfig.ATTR_PASSWORD)),
- cn.getAttributeValue(SharePointConfig.ATTR_AUTHENTICATION),
- cn.getAttributeValue(SharePointConfig.ATTR_USERACLsUSERNAME)));
- // Order-based rule, as well
- dCRules.add(new DCRule(cn.getAttributeValue(SharePointConfig.ATTR_SUFFIX),dcName));
- }
- }
-
- cacheLifetime = params.getParameter(SharePointConfig.PARAM_CACHELIFETIME);
+ // Pick up all the parameters that go into the cache key here
+ cacheLifetime = configParams.getParameter(SharePointConfig.PARAM_CACHELIFETIME);
if (cacheLifetime == null)
cacheLifetime = "1";
- cacheLRUsize = params.getParameter(SharePointConfig.PARAM_CACHELRUSIZE);
+ cacheLRUsize = configParams.getParameter(SharePointConfig.PARAM_CACHELRUSIZE);
if (cacheLRUsize == null)
- cacheLRUsize = "1000";
+ cacheLRUsize = "1000";
+
+ String serverVersion = configParams.getParameter( SharePointConfig.PARAM_SERVERVERSION );
+ if (serverVersion == null)
+ serverVersion = "2.0";
+ // Authority needs to do nothing with SharePoint version right now.
+
+ serverProtocol = configParams.getParameter( SharePointConfig.PARAM_SERVERPROTOCOL );
+ if (serverProtocol == null)
+ serverProtocol = "http";
+
+ serverName = configParams.getParameter( SharePointConfig.PARAM_SERVERNAME );
+ serverPortString = configParams.getParameter( SharePointConfig.PARAM_SERVERPORT );
+ serverLocation = configParams.getParameter(SharePointConfig.PARAM_SERVERLOCATION);
+ if (serverLocation == null)
+ serverLocation = "";
+ if (serverLocation.endsWith("/"))
+ serverLocation = serverLocation.substring(0,serverLocation.length()-1);
+ if (serverLocation.length() > 0 && !serverLocation.startsWith("/"))
+ serverLocation = "/" + serverLocation;
+ encodedServerLocation = serverLocation;
+ serverLocation = decodePath(serverLocation);
+
+ serverUserName = configParams.getParameter(SharePointConfig.PARAM_SERVERUSERNAME);
+ password = configParams.getObfuscatedParameter(SharePointConfig.PARAM_SERVERPASSWORD);
+ int index = serverUserName.indexOf("\\");
+ if (index != -1)
+ {
+ strippedUserName = serverUserName.substring(index+1);
+ ntlmDomain = serverUserName.substring(0,index);
+ }
+ else
+ {
+ strippedUserName = null;
+ ntlmDomain = null;
+ }
+
+ keystoreData = params.getParameter(SharePointConfig.PARAM_SERVERKEYSTORE);
+
}
- protected static String deobfuscate(String input)
- {
- if (input == null)
- return null;
- try
- {
- return ManifoldCF.deobfuscate(input);
- }
- catch (ManifoldCFException e)
- {
- return "";
- }
- }
-
// All methods below this line will ONLY be called if a connect() call succeeded
// on this instance!
@@ -221,20 +208,6 @@
public String check()
throws ManifoldCFException
{
- // Set up the basic AD session...
- getSessionParameters();
- // Clear the DC session info, so we're forced to redo it
- for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
- {
- sessionEntry.getValue().closeConnection();
- }
- // Loop through all domain controllers and attempt to establish a session with each one.
- for (String domainController : dCConnectionParameters.keySet())
- {
- createDCSession(domainController);
- }
-
- // SharePoint check
getSharePointSession();
try
{
@@ -257,23 +230,6 @@
return super.check();
}
- /** Create or lookup a session for a domain controller.
- */
- protected LdapContext createDCSession(String domainController)
- throws ManifoldCFException
- {
- getSessionParameters();
- DCConnectionParameters parms = dCConnectionParameters.get(domainController);
- // Find the session in the hash, if it exists
- DCSessionInfo session = sessionInfo.get(domainController);
- if (session == null)
- {
- session = new DCSessionInfo();
- sessionInfo.put(domainController,session);
- }
- return session.getADSession(domainController,parms);
- }
-
/** Poll. The connection should be closed if it has been idle for too long.
*/
@Override
@@ -281,10 +237,6 @@
throws ManifoldCFException
{
long currentTime = System.currentTimeMillis();
- for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
- {
- sessionEntry.getValue().closeIfExpired(currentTime);
- }
if (proxy != null && System.currentTimeMillis() >= sharepointSessionTimeout)
expireSharePointSession();
if (connectionManager != null)
@@ -303,22 +255,11 @@
cacheLifetime = null;
cacheLRUsize = null;
- // Clean up AD parameters
-
- hasSessionParameters = false;
-
- // Close all connections
- for (Map.Entry<String,DCSessionInfo> sessionEntry : sessionInfo.entrySet())
- {
- sessionEntry.getValue().closeConnection();
- }
- sessionInfo = null;
-
// Clean up SharePoint parameters
serverUrl = null;
fileBaseUrl = null;
- userName = null;
+ serverUserName = null;
strippedUserName = null;
password = null;
ntlmDomain = null;
@@ -336,6 +277,8 @@
connectionManager.shutdown();
connectionManager = null;
+ hasSessionParameters = false;
+
super.disconnect();
}
@@ -348,12 +291,11 @@
public AuthorizationResponse getAuthorizationResponse(String userName)
throws ManifoldCFException
{
- // This sets up parameters we need to construct the response description
getSessionParameters();
-
// Construct a cache description object
ICacheDescription objectDescription = new AuthorizationResponseDescription(userName,
- dCConnectionParameters,dCRules,this.responseLifetime,this.LRUsize);
+ serverName,serverPortString,serverLocation,serverProtocol,serverUserName,password,
+ this.responseLifetime,this.LRUsize);
// Enter the cache
ICacheHandle ch = cacheManager.enterCache(new ICacheDescription[]{objectDescription},null,null);
@@ -400,38 +342,13 @@
String userPart = userName.substring(0,index);
String domainPart = userName.substring(index+1);
- List<String> theGroups = new ArrayList<String>();
-
// First, look up user in SharePoint.
getSharePointSession();
List<String> sharePointTokens = proxy.getAccessTokens("/", domainPart + "\\" + userPart);
if (sharePointTokens == null)
- return RESPONSE_USERNOTFOUND;
- theGroups.addAll(sharePointTokens);
+ return RESPONSE_USERNOTFOUND_ADDITIVE;
- // Use AD only if Claim Space
- if (isClaimSpace)
- {
- try
- {
- List<String> adTokens = getADTokens(userPart,domainPart,userName);
- // User not present in AD is perfectly OK provided the user exists in SharePoint
- if (adTokens != null)
- theGroups.addAll(adTokens);
- }
- catch (NameNotFoundException e)
- {
- // This means that the user doesn't exist
- return RESPONSE_USERNOTFOUND;
- }
- catch (NamingException e)
- {
- // Unreachable
- return RESPONSE_UNREACHABLE;
- }
- }
-
- return new AuthorizationResponse(theGroups.toArray(new String[0]),AuthorizationResponse.RESPONSE_OK);
+ return new AuthorizationResponse(sharePointTokens.toArray(new String[0]),AuthorizationResponse.RESPONSE_OK);
}
/** Obtain the default access tokens for a given user name.
@@ -442,164 +359,9 @@
public AuthorizationResponse getDefaultAuthorizationResponse(String userName)
{
// The default response if the getConnection method fails
- return RESPONSE_UNREACHABLE;
+ return RESPONSE_UNREACHABLE_ADDITIVE;
}
- /** Get the AD-derived access tokens for a user and domain */
- protected List<String> getADTokens(String userPart, String domainPart, String userName)
- throws NameNotFoundException, NamingException, ManifoldCFException
- {
- // Now, look through the rules for the matching domain controller
- String domainController = null;
- for (DCRule rule : dCRules)
- {
- String suffix = rule.getSuffix();
- if (suffix.length() == 0 || domainPart.toLowerCase(Locale.ROOT).endsWith(suffix.toLowerCase(Locale.ROOT)) &&
- (suffix.length() == domainPart.length() || domainPart.charAt((domainPart.length()-suffix.length())-1) == '.'))
- {
- domainController = rule.getDomainControllerName();
- break;
- }
- }
-
- if (domainController == null)
- // No AD user
- return null;
-
- // Look up connection parameters
- DCConnectionParameters dcParams = dCConnectionParameters.get(domainController);
- if (dcParams == null)
- // No AD user
- return null;
-
- // Use the complete fqn if the field is the "userPrincipalName"
- String userBase;
- String userACLsUsername = dcParams.getUserACLsUsername();
- if (userACLsUsername != null && userACLsUsername.equals("userPrincipalName")){
- userBase = userName;
- }
- else
- {
- userBase = userPart;
- }
-
- //Build the DN searchBase from domain part
- StringBuilder domainsb = new StringBuilder();
- int j = 0;
- while (true)
- {
- if (j > 0)
- domainsb.append(",");
-
- int k = domainPart.indexOf(".",j);
- if (k == -1)
- {
- domainsb.append("DC=").append(ldapEscape(domainPart.substring(j)));
- break;
- }
- domainsb.append("DC=").append(ldapEscape(domainPart.substring(j,k)));
- j = k+1;
- }
-
- // Establish a session with the selected domain controller
- LdapContext ctx = createDCSession(domainController);
-
- //Get DistinguishedName (for this method we are using DomainPart as a searchBase ie: DC=qa-ad-76,DC=metacarta,DC=com")
- String searchBase = getDistinguishedName(ctx, userBase, domainsb.toString(), userACLsUsername);
- if (searchBase == null)
- return null;
-
- //specify the LDAP search filter
- String searchFilter = "(objectClass=user)";
-
- //Create the search controls for finding the access tokens
- SearchControls searchCtls = new SearchControls();
-
- //Specify the search scope, must be base level search for tokenGroups
- searchCtls.setSearchScope(SearchControls.OBJECT_SCOPE);
-
- //Specify the attributes to return
- String returnedAtts[]={"tokenGroups","objectSid"};
- searchCtls.setReturningAttributes(returnedAtts);
-
- //Search for tokens. Since every user *must* have a SID, the "no user" detection should be safe.
- NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
-
- List<String> theGroups = new ArrayList<String>();
- String userToken = userTokenFromLoginName(domainPart + "\\" + userPart);
- if (userToken != null)
- theGroups.add(userToken);
-
- //Loop through the search results
- while (answer.hasMoreElements())
- {
- SearchResult sr = (SearchResult)answer.next();
-
- //the sr.GetName should be null, as it is relative to the base object
-
- Attributes attrs = sr.getAttributes();
- if (attrs != null)
- {
- try
- {
- for (NamingEnumeration ae = attrs.getAll();ae.hasMore();)
- {
- Attribute attr = (Attribute)ae.next();
- for (NamingEnumeration e = attr.getAll();e.hasMore();)
- {
- String sid = sid2String((byte[])e.next());
- String token = attr.getID().equals("objectSid")?userTokenFromSID(sid):groupTokenFromSID(sid);
- theGroups.add(token);
- }
- }
- }
- catch (NamingException e)
- {
- throw new ManifoldCFException(e.getMessage(),e);
- }
- }
- }
-
- if (theGroups.size() == 0)
- return null;
-
- // User is in AD, so add the 'everyone' group
- theGroups.add(everyoneGroup());
- return theGroups;
- }
-
- protected String everyoneGroup()
- {
- if (isClaimSpace)
- return "c:0!.s|windows";
- else
- return "S-1-1-0";
- }
-
- protected String groupTokenFromSID(String SID)
- {
- if (isClaimSpace)
- return "c:0+.w|"+SID.toLowerCase(Locale.ROOT);
- else
- return SID;
- }
-
- protected String userTokenFromSID(String SID)
- {
- if (isClaimSpace)
- return "i:0+.w|"+SID.toLowerCase(Locale.ROOT);
- else
- return SID;
- }
-
- protected String userTokenFromLoginName(String loginName)
- {
- if (isClaimSpace)
- return "i:0#.w|"+URLEncoder.encode(loginName);
- else
- return null;
- }
-
// UI support methods.
//
// These support methods are involved in setting up authority connection configuration information. The configuration methods cannot assume that the
@@ -617,9 +379,7 @@
public void outputConfigurationHeader(IThreadContext threadContext, IHTTPOutput out, Locale locale, ConfigParams parameters, List<String> tabsArray)
throws ManifoldCFException, IOException
{
- tabsArray.add(Messages.getString(locale,"SharePointAuthority.DomainController"));
tabsArray.add(Messages.getString(locale,"SharePointAuthority.Server"));
- tabsArray.add(Messages.getString(locale,"SharePointAuthority.AuthorizationModel"));
tabsArray.add(Messages.getString(locale,"SharePointAuthority.Cache"));
Messages.outputResourceWithVelocity(out,locale,"editConfiguration.js",null);
}
@@ -639,25 +399,10 @@
{
Map<String,Object> velocityContext = new HashMap<String,Object>();
velocityContext.put("TabName",tabName);
- fillInDomainControllerTab(velocityContext,out,parameters);
fillInCacheTab(velocityContext,out,parameters);
fillInServerTab(velocityContext,out,parameters);
- fillInAuthorizationModelTab(velocityContext,out,parameters);
- Messages.outputResourceWithVelocity(out,locale,"editConfiguration_DomainController.html",velocityContext);
Messages.outputResourceWithVelocity(out,locale,"editConfiguration_Cache.html",velocityContext);
Messages.outputResourceWithVelocity(out,locale,"editConfiguration_Server.html",velocityContext);
- Messages.outputResourceWithVelocity(out,locale,"editConfiguration_AuthorizationModel.html",velocityContext);
- }
-
- protected static void fillInAuthorizationModelTab(Map<String,Object> velocityContext, IHTTPOutput out, ConfigParams parameters)
- throws ManifoldCFException
- {
- String authorizationModel = parameters.getParameter(SharePointConfig.PARAM_AUTHORIZATIONMODEL);
- if (authorizationModel == null)
- authorizationModel = "Classic";
-
- // Fill in context
- velocityContext.put("AUTHORIZATIONMODEL", authorizationModel);
}
protected static void fillInServerTab(Map<String,Object> velocityContext, IHTTPOutput out, ConfigParams parameters)
@@ -728,48 +473,6 @@
}
- protected static void fillInDomainControllerTab(Map<String,Object> velocityContext, IPasswordMapperActivity mapper, ConfigParams parameters)
- {
- List<Map<String,String>> domainControllers = new ArrayList<Map<String,String>>();
-
- // Go through nodes looking for DC nodes
- for (int i = 0; i < parameters.getChildCount(); i++)
- {
- ConfigNode cn = parameters.getChild(i);
- if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
- {
- // Grab the info
- String dcSuffix = cn.getAttributeValue(SharePointConfig.ATTR_SUFFIX);
- String dcDomainController = cn.getAttributeValue(SharePointConfig.ATTR_DOMAINCONTROLLER);
- String dcUserName = cn.getAttributeValue(SharePointConfig.ATTR_USERNAME);
- String dcPassword = deobfuscate(cn.getAttributeValue(SharePointConfig.ATTR_PASSWORD));
- String dcAuthentication = cn.getAttributeValue(SharePointConfig.ATTR_AUTHENTICATION);
- String dcUserACLsUsername = cn.getAttributeValue(SharePointConfig.ATTR_USERACLsUSERNAME);
- domainControllers.add(createDomainControllerMap(mapper,dcSuffix,dcDomainController,dcUserName,dcPassword,dcAuthentication,dcUserACLsUsername));
- }
- }
- velocityContext.put("DOMAINCONTROLLERS",domainControllers);
- }
-
- protected static Map<String,String> createDomainControllerMap(IPasswordMapperActivity mapper, String suffix, String domainControllerName,
- String userName, String password, String authentication, String userACLsUsername)
- {
- Map<String,String> defaultMap = new HashMap<String,String>();
- if (suffix != null)
- defaultMap.put("SUFFIX",suffix);
- if (domainControllerName != null)
- defaultMap.put("DOMAINCONTROLLER",domainControllerName);
- if (userName != null)
- defaultMap.put("USERNAME",userName);
- if (password != null)
- defaultMap.put("PASSWORD",mapper.mapPasswordToKey(password));
- if (authentication != null)
- defaultMap.put("AUTHENTICATION",authentication);
- if (userACLsUsername != null)
- defaultMap.put("USERACLsUSERNAME",userACLsUsername);
- return defaultMap;
- }
-
protected static void fillInCacheTab(Map<String,Object> velocityContext, IPasswordMapperActivity mapper, ConfigParams parameters)
{
String cacheLifetime = parameters.getParameter(SharePointConfig.PARAM_CACHELIFETIME);
@@ -795,67 +498,6 @@
public String processConfigurationPost(IThreadContext threadContext, IPostParameters variableContext, Locale locale, ConfigParams parameters)
throws ManifoldCFException
{
- String x = variableContext.getParameter("dcrecord_count");
- if (x != null)
- {
- // Delete old nodes
- int i = 0;
- while (i < parameters.getChildCount())
- {
- ConfigNode cn = parameters.getChild(i);
- if (cn.getType().equals(SharePointConfig.NODE_DOMAINCONTROLLER))
- parameters.removeChild(i);
- else
- i++;
- }
- // Scan form fields and apply operations
- int count = Integer.parseInt(x);
- i = 0;
- String op;
-
- Set<String> seenDomains = new HashSet<String>();
-
- while (i < count)
- {
- op = variableContext.getParameter("dcrecord_op_"+i);
- if (op != null && op.equals("Insert"))
- {
- // Insert a new record right here
- addDomainController(seenDomains,parameters,
- variableContext.getParameter("dcrecord_suffix"),
- variableContext.getParameter("dcrecord_domaincontrollername"),
- variableContext.getParameter("dcrecord_username"),
- variableContext.mapKeyToPassword(variableContext.getParameter("dcrecord_password")),
- variableContext.getParameter("dcrecord_authentication"),
- variableContext.getParameter("dcrecord_userACLsUsername"));
- }
- if (op == null || !op.equals("Delete"))
- {
- // Add this record back in
- addDomainController(seenDomains,parameters,
- variableContext.getParameter("dcrecord_suffix_"+i),
- variableContext.getParameter("dcrecord_domaincontrollername_"+i),
- variableContext.getParameter("dcrecord_username_"+i),
- variableContext.mapKeyToPassword(variableContext.getParameter("dcrecord_password_"+i)),
- variableContext.getParameter("dcrecord_authentication_"+i),
- variableContext.getParameter("dcrecord_userACLsUsername_"+i));
- }
- i++;
- }
- op = variableContext.getParameter("dcrecord_op");
- if (op != null && op.equals("Add"))
- {
- // Insert a new record right here
- addDomainController(seenDomains,parameters,
- variableContext.getParameter("dcrecord_suffix"),
- variableContext.getParameter("dcrecord_domaincontrollername"),
- variableContext.getParameter("dcrecord_username"),
- variableContext.getParameter("dcrecord_password"),
- variableContext.getParameter("dcrecord_authentication"),
- variableContext.getParameter("dcrecord_userACLsUsername"));
- }
- }
-
// Cache parameters
String cacheLifetime = variableContext.getParameter("cachelifetime");
@@ -956,33 +598,9 @@
}
}
- // Authorization model
- String authorizationModel = variableContext.getParameter("authorizationModel");
- if (authorizationModel != null)
- parameters.setParameter(SharePointConfig.PARAM_AUTHORIZATIONMODEL,authorizationModel);
-
return null;
}
- protected static void addDomainController(Set<String> seenDomains, ConfigParams parameters,
- String suffix, String domainControllerName, String userName, String password, String authentication,
- String userACLsUsername)
- throws ManifoldCFException
- {
- if (!seenDomains.contains(domainControllerName))
- {
- ConfigNode cn = new ConfigNode(SharePointConfig.NODE_DOMAINCONTROLLER);
- cn.setAttribute(SharePointConfig.ATTR_SUFFIX,suffix);
- cn.setAttribute(SharePointConfig.ATTR_DOMAINCONTROLLER,domainControllerName);
- cn.setAttribute(SharePointConfig.ATTR_USERNAME,userName);
- cn.setAttribute(SharePointConfig.ATTR_PASSWORD,ManifoldCF.obfuscate(password));
- cn.setAttribute(SharePointConfig.ATTR_AUTHENTICATION,authentication);
- cn.setAttribute(SharePointConfig.ATTR_USERACLsUSERNAME,userACLsUsername);
- parameters.addChild(parameters.getChildCount(),cn);
- seenDomains.add(domainControllerName);
- }
- }
-
/** View configuration.
* This method is called in the body section of the authority connector's view configuration page. Its purpose is to present the connection information to the user.
* The coder can presume that the HTML that is output from this configuration will be within appropriate <html> and <body> tags.
@@ -995,10 +613,8 @@
throws ManifoldCFException, IOException
{
Map<String,Object> velocityContext = new HashMap<String,Object>();
- fillInDomainControllerTab(velocityContext,out,parameters);
fillInCacheTab(velocityContext,out,parameters);
fillInServerTab(velocityContext,out,parameters);
- fillInAuthorizationModelTab(velocityContext,out,parameters);
Messages.outputResourceWithVelocity(out,locale,"viewConfiguration.html",velocityContext);
}
@@ -1029,24 +645,10 @@
{
if (proxy == null)
{
- String serverVersion = params.getParameter( SharePointConfig.PARAM_SERVERVERSION );
- if (serverVersion == null)
- serverVersion = "2.0";
- // Authority needs to do nothing with SharePoint version right now.
-
- String authorizationModel = params.getParameter( SharePointConfig.PARAM_AUTHORIZATIONMODEL );
- isClaimSpace = (authorizationModel != null &&authorizationModel.equals("ClaimSpace"));
-
- serverProtocol = params.getParameter( SharePointConfig.PARAM_SERVERPROTOCOL );
- if (serverProtocol == null)
- serverProtocol = "http";
-
- serverName = params.getParameter( SharePointConfig.PARAM_SERVERNAME );
-
+ // Set up server URL
try
{
- String serverPort = params.getParameter( SharePointConfig.PARAM_SERVERPORT );
- if (serverPort == null || serverPort.length() == 0)
+ if (serverPortString == null || serverPortString.length() == 0)
{
if (serverProtocol.equals("https"))
this.serverPort = 443;
@@ -1054,36 +656,13 @@
this.serverPort = 80;
}
else
- this.serverPort = Integer.parseInt(serverPort);
+ this.serverPort = Integer.parseInt(serverPortString);
}
catch (NumberFormatException e)
{
throw new ManifoldCFException(e.getMessage(),e);
}
- serverLocation = params.getParameter(SharePointConfig.PARAM_SERVERLOCATION);
- if (serverLocation == null)
- serverLocation = "";
- if (serverLocation.endsWith("/"))
- serverLocation = serverLocation.substring(0,serverLocation.length()-1);
- if (serverLocation.length() > 0 && !serverLocation.startsWith("/"))
- serverLocation = "/" + serverLocation;
- encodedServerLocation = serverLocation;
- serverLocation = decodePath(serverLocation);
-
- userName = params.getParameter(SharePointConfig.PARAM_SERVERUSERNAME);
- password = params.getObfuscatedParameter(SharePointConfig.PARAM_SERVERPASSWORD);
- int index = userName.indexOf("\\");
- if (index != -1)
- {
- strippedUserName = userName.substring(index+1);
- ntlmDomain = userName.substring(0,index);
- }
- else
- {
- strippedUserName = null;
- ntlmDomain = null;
- }
-
+
serverUrl = serverProtocol + "://" + serverName;
if (serverProtocol.equals("https"))
{
@@ -1097,7 +676,6 @@
}
// Set up ssl if indicated
- keystoreData = params.getParameter(SharePointConfig.PARAM_SERVERKEYSTORE);
PoolingClientConnectionManager localConnectionManager = new PoolingClientConnectionManager();
localConnectionManager.setMaxTotal(1);
@@ -1142,7 +720,7 @@
httpClient = localHttpClient;
- proxy = new SPSProxyHelper( serverUrl, encodedServerLocation, serverLocation, userName, password,
+ proxy = new SPSProxyHelper( serverUrl, encodedServerLocation, serverLocation, serverUserName, password,
org.apache.manifoldcf.sharepoint.CommonsHTTPSender.class, "sharepoint-client-config.wsdd",
httpClient );
@@ -1153,19 +731,10 @@
protected void expireSharePointSession()
throws ManifoldCFException
{
+ serverPort = -1;
serverUrl = null;
fileBaseUrl = null;
- userName = null;
- strippedUserName = null;
- password = null;
- ntlmDomain = null;
- serverLocation = null;
- encodedServerLocation = null;
- serverPort = -1;
-
- keystoreData = null;
keystoreManager = null;
-
proxy = null;
httpClient = null;
if (connectionManager != null)
@@ -1173,222 +742,6 @@
connectionManager = null;
}
- /** Obtain the DistinguishedName for a given user logon name.
- *@param ctx is the ldap context to use.
- *@param userName (Domain Logon Name) is the user name or identifier.
- *@param searchBase (Full Domain Name for the search ie: DC=qa-ad-76,DC=metacarta,DC=com)
- *@return DistinguishedName for given domain user logon name.
- * (Should throws an exception if user is not found.)
- */
- protected String getDistinguishedName(LdapContext ctx, String userName, String searchBase, String userACLsUsername)
- throws ManifoldCFException
- {
- String returnedAtts[] = {"distinguishedName"};
- String searchFilter = "(&(objectClass=user)(" + userACLsUsername + "=" + userName + "))";
- SearchControls searchCtls = new SearchControls();
- searchCtls.setReturningAttributes(returnedAtts);
- //Specify the search scope
- searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
- searchCtls.setReturningAttributes(returnedAtts);
-
- try
- {
- NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
- while (answer.hasMoreElements())
- {
- SearchResult sr = (SearchResult)answer.next();
- Attributes attrs = sr.getAttributes();
- if (attrs != null)
- {
- String dn = attrs.get("distinguishedName").get().toString();
- return dn;
- }
- }
- return null;
- }
- catch (NamingException e)
- {
- throw new ManifoldCFException(e.getMessage(),e);
- }
- }
-
- /** LDAP escape a string.
- */
- protected static String ldapEscape(String input)
- {
- //Add escape sequence to all commas
- StringBuilder sb = new StringBuilder();
- int index = 0;
- while (true)
- {
- int oldIndex = index;
- index = input.indexOf(",",oldIndex);
- if (index == -1)
- {
- sb.append(input.substring(oldIndex));
- break;
- }
- sb.append(input.substring(oldIndex,index)).append("\\,");
- index++;
- }
- return sb.toString();
- }
-
- /** Convert a binary SID to a string */
- protected static String sid2String(byte[] SID)
- {
- StringBuilder strSID = new StringBuilder("S");
- long version = SID[0];
- strSID.append("-").append(Long.toString(version));
- long authority = SID[4];
- for (int i = 0;i<4;i++)
- {
- authority <<= 8;
- authority += SID[4+i] & 0xFF;
- }
- strSID.append("-").append(Long.toString(authority));
- long count = SID[2];
- count <<= 8;
- count += SID[1] & 0xFF;
- for (int j=0;j<count;j++)
- {
- long rid = SID[11 + (j*4)] & 0xFF;
- for (int k=1;k<4;k++)
- {
- rid <<= 8;
- rid += SID[11-k + (j*4)] & 0xFF;
- }
- strSID.append("-").append(Long.toString(rid));
- }
- return strSID.toString();
- }
-
- /** Class representing the session information for a specific domain controller
- * connection.
- */
- protected static class DCSessionInfo
- {
- /** The initialized LDAP context (which functions as a session) */
- private LdapContext ctx = null;
- /** The time of last access to this ctx object */
- private long expiration = -1L;
-
- public DCSessionInfo()
- {
- }
-
- /** Initialize the session. */
- public LdapContext getADSession(String domainControllerName, DCConnectionParameters params)
- throws ManifoldCFException
- {
- String authentication = params.getAuthentication();
- String userName = params.getUserName();
- String password = params.getPassword();
-
- while (true)
- {
- if (ctx == null)
- {
- // Calculate the ldap url first
- String ldapURL = "ldap://" + domainControllerName + ":389";
-
- Hashtable env = new Hashtable();
- env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
- env.put(Context.SECURITY_AUTHENTICATION,authentication);
- env.put(Context.SECURITY_PRINCIPAL,userName);
- env.put(Context.SECURITY_CREDENTIALS,password);
-
- //connect to my domain controller
- env.put(Context.PROVIDER_URL,ldapURL);
-
- //specify attributes to be returned in binary format
- env.put("java.naming.ldap.attributes.binary","tokenGroups objectSid");
-
- // Now, try the connection...
- try
- {
- ctx = new InitialLdapContext(env,null);
- // If successful, break
- break;
- }
- catch (AuthenticationException e)
- {
- // This means we couldn't authenticate!
- throw new ManifoldCFException("Authentication problem authenticating admin user '"+userName+"': "+e.getMessage(),e);
- }
- catch (CommunicationException e)
- {
- // This means we couldn't connect, most likely
- throw new ManifoldCFException("Couldn't communicate with domain controller '"+domainControllerName+"': "+e.getMessage(),e);
- }
- catch (NamingException e)
- {
- throw new ManifoldCFException(e.getMessage(),e);
- }
- }
- else
- {
- // Attempt to reconnect. I *hope* this is efficient and doesn't do unnecessary work.
- try
- {
- ctx.reconnect(null);
- // Break on apparent success
- break;
- }
- catch (AuthenticationException e)
- {
- // This means we couldn't authenticate! Log it and retry creating a whole new context.
- Logging.authorityConnectors.warn("Reconnect: Authentication problem authenticating admin user '"+userName+"': "+e.getMessage(),e);
- }
- catch (CommunicationException e)
- {
- // This means we couldn't connect, most likely. Log it and retry creating a whole new context.
- Logging.authorityConnectors.warn("Reconnect: Couldn't communicate with domain controller '"+domainControllerName+"': "+e.getMessage(),e);
- }
- catch (NamingException e)
- {
- Logging.authorityConnectors.warn("Reconnect: Naming exception: "+e.getMessage(),e);
- }
-
- // So we have no chance of leaking resources, attempt to close the context.
- closeConnection();
- // Loop back around to try our luck with a fresh connection.
-
- }
- }
-
- // Set the expiration time anew
- expiration = System.currentTimeMillis() + ADExpirationInterval;
- return ctx;
- }
-
- /** Close the connection handle. */
- protected void closeConnection()
- {
- if (ctx != null)
- {
- try
- {
- ctx.close();
- }
- catch (NamingException e)
- {
- // Eat this error
- }
- ctx = null;
- expiration = -1L;
- }
- }
-
- /** Close connection if it has expired. */
- protected void closeIfExpired(long currentTime)
- {
- if (expiration != -1L && currentTime > expiration)
- closeConnection();
- }
-
- }
-
/** Decode a path item.
*/
public static String pathItemDecode(String pathItem)
@@ -1462,68 +815,6 @@
return sb.toString();
}
- /** Class describing a domain suffix and corresponding domain controller name rule.
- */
- protected static class DCRule
- {
- private String suffix;
- private String domainControllerName;
-
- public DCRule(String suffix, String domainControllerName)
- {
- this.suffix = suffix;
- this.domainControllerName = domainControllerName;
- }
-
- public String getSuffix()
- {
- return suffix;
- }
-
- public String getDomainControllerName()
- {
- return domainControllerName;
- }
- }
-
- /** Class describing the connection parameters to a domain controller.
- */
- protected static class DCConnectionParameters
- {
- private String userName;
- private String password;
- private String authentication;
- private String userACLsUsername;
-
- public DCConnectionParameters(String userName, String password, String authentication, String userACLsUsername)
- {
- this.userName = userName;
- this.password = password;
- this.authentication = authentication;
- this.userACLsUsername = userACLsUsername;
- }
-
- public String getUserName()
- {
- return userName;
- }
-
- public String getPassword()
- {
- return password;
- }
-
- public String getAuthentication()
- {
- return authentication;
- }
-
- public String getUserACLsUsername()
- {
- return userACLsUsername;
- }
- }
-
protected static StringSet emptyStringSet = new StringSet();
/** This is the cache object descriptor for cached access tokens from
@@ -1532,25 +823,33 @@
protected static class AuthorizationResponseDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription
{
/** The user name */
- protected String userName;
- /** Connection parameters */
- protected Map<String,DCConnectionParameters> dcConnectionParams;
- /** Rules */
- protected List<DCRule> dcRules;
+ protected final String userName;
/** The response lifetime */
- protected long responseLifetime;
+ protected final long responseLifetime;
/** The expiration time */
protected long expirationTime = -1;
+ // Parameters designed to guarantee cache key uniqueness
+ protected final String serverName;
+ protected final String serverPortString;
+ protected final String serverLocation;
+ protected final String serverProtocol;
+ protected final String serverUserName;
+ protected final String password;
/** Constructor. */
- public AuthorizationResponseDescription(String userName, Map<String,DCConnectionParameters> dcConnectionParams,
- List<DCRule> dcRules, long responseLifetime, int LRUsize)
+ public AuthorizationResponseDescription(String userName,
+ String serverName, String serverPortString, String serverLocation, String serverProtocol, String serverUserName, String password,
+ long responseLifetime, int LRUsize)
{
super("SharePointAuthority",LRUsize);
this.userName = userName;
- this.dcConnectionParams = dcConnectionParams;
- this.dcRules = dcRules;
this.responseLifetime = responseLifetime;
+ this.serverName = serverName;
+ this.serverPortString = serverPortString;
+ this.serverLocation = serverLocation;
+ this.serverProtocol = serverProtocol;
+ this.serverUserName = serverUserName;
+ this.password = password;
}
/** Return the invalidation keys for this object. */
@@ -1564,13 +863,12 @@
{
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append("-").append(userName);
- for (DCRule rule : dcRules)
- {
- sb.append("-").append(rule.getSuffix());
- String domainController = rule.getDomainControllerName();
- DCConnectionParameters params = dcConnectionParams.get(domainController);
- sb.append("-").append(domainController).append("-").append(params.getUserName()).append("-").append(params.getPassword());
- }
+ sb.append("-").append(serverName);
+ sb.append("-").append(serverPortString);
+ sb.append("-").append(serverLocation);
+ sb.append("-").append(serverProtocol);
+ sb.append("-").append(serverUserName);
+ sb.append("-").append(password);
return sb.toString();
}
@@ -1585,12 +883,12 @@
public int hashCode()
{
int rval = userName.hashCode();
- for (DCRule rule : dcRules)
- {
- String domainController = rule.getDomainControllerName();
- DCConnectionParameters params = dcConnectionParams.get(domainController);
- rval += rule.getSuffix().hashCode() + domainController.hashCode() + params.getUserName().hashCode() + params.getPassword().hashCode();
- }
+ rval += serverName.hashCode();
+ rval += serverPortString.hashCode();
+ rval += serverLocation.hashCode();
+ rval += serverProtocol.hashCode();
+ rval += serverUserName.hashCode();
+ rval += password.hashCode();
return rval;
}
@@ -1601,20 +899,18 @@
AuthorizationResponseDescription ard = (AuthorizationResponseDescription)o;
if (!ard.userName.equals(userName))
return false;
- if (ard.dcRules.size() != dcRules.size())
+ if (!ard.serverName.equals(serverName))
return false;
- for (int i = 0 ; i < dcRules.size() ; i++)
- {
- DCRule rule = dcRules.get(i);
- DCRule ardRule = ard.dcRules.get(i);
- if (!rule.getSuffix().equals(ardRule.getSuffix()) || !rule.getDomainControllerName().equals(ardRule.getDomainControllerName()))
- return false;
- String domainController = rule.getDomainControllerName();
- DCConnectionParameters params = dcConnectionParams.get(domainController);
- DCConnectionParameters ardParams = ard.dcConnectionParams.get(domainController);
- if (!params.getUserName().equals(ardParams.getUserName()) || !params.getPassword().equals(ardParams.getPassword()))
- return false;
- }
+ if (!ard.serverPortString.equals(serverPortString))
+ return false;
+ if (!ard.serverLocation.equals(serverLocation))
+ return false;
+ if (!ard.serverProtocol.equals(serverProtocol))
+ return false;
+ if (!ard.serverUserName.equals(serverUserName))
+ return false;
+ if (!ard.password.equals(password))
+ return false;
return true;
}
diff --git a/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointConfig.java b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointConfig.java
index b5f1c00..c97308d 100644
--- a/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointConfig.java
+++ b/connectors/sharepoint/connector/src/main/java/org/apache/manifoldcf/authorities/authorities/sharepoint/SharePointConfig.java
@@ -49,9 +49,6 @@
/** SharePoint server certificate store */
public static final String PARAM_SERVERKEYSTORE = "keystore";
- /** SharePoint authorization model */
- public static final String PARAM_AUTHORIZATIONMODEL = "authorizationModel";
-
// Nodes
/** Domain controller node */
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration.js b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration.js
new file mode 100644
index 0000000..d3fd88e
--- /dev/null
+++ b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration.js
@@ -0,0 +1,134 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ 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.
+-->
+
+<script type="text/javascript">
+<!--
+function checkConfig()
+{
+ var i = 0;
+ var count = editconnection.dcrecord_count.value;
+ while (i < count)
+ {
+ var username = eval("editconnection.dcrecord_username_"+i+".value");
+ if (username == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
+ eval("editconnection.dcrecord_username_"+i+".focus()");
+ return false;
+ }
+ var authentication = eval("editconnection.dcrecord_authentication_"+i+".value");
+ if (authentication == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
+ eval("editconnection.dcrecord_authentication_"+i+".focus()");
+ return false;
+ }
+ i += 1;
+ }
+ return true;
+}
+
+function checkConfigForSave()
+{
+ if (editconnection.cachelifetime.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetimeCannotBeNull'))");
+ SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.Cache'))");
+ editconnection.cachelifetime.focus();
+ return false;
+ }
+ if (editconnection.cachelifetime.value != "" && !isInteger(editconnection.cachelifetime.value))
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetimeMustBeAnInteger'))");
+ SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.Cache'))");
+ editconnection.cachelifetime.focus();
+ return false;
+ }
+ if (editconnection.cachelrusize.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSizeCannotBeNull'))");
+ SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.Cache'))");
+ editconnection.cachelrusize.focus();
+ return false;
+ }
+ if (editconnection.cachelrusize.value != "" && !isInteger(editconnection.cachelrusize.value))
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSizeMustBeAnInteger'))");
+ SelectTab("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.Cache'))");
+ editconnection.cachelrusize.focus();
+ return false;
+ }
+ return true;
+}
+
+function deleteDC(i)
+{
+ eval("editconnection.dcrecord_op_"+i+".value=\"Delete\"");
+ postFormSetAnchor("dcrecord");
+}
+
+function insertDC(i)
+{
+ if (editconnection.dcrecord_domaincontrollername.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.EnterADomainControllerServerName'))");
+ editconnection.dcrecord_domaincontrollername.focus();
+ return;
+ }
+ if (editconnection.dcrecord_username.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
+ editconnection.dcrecord_username.focus();
+ return;
+ }
+ if (editconnection.dcrecord_authentication.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
+ editconnection.dcrecord_authentication.focus();
+ return;
+ }
+ eval("editconnection.dcrecord_op_"+i+".value=\"Insert\"");
+ postFormSetAnchor("dcrecord_"+i);
+}
+
+function addDC()
+{
+ if (editconnection.dcrecord_domaincontrollername.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.EnterADomainControllerServerName'))");
+ editconnection.dcrecord_domaincontrollername.focus();
+ return;
+ }
+ if (editconnection.dcrecord_username.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
+ editconnection.dcrecord_username.focus();
+ return;
+ }
+ if (editconnection.dcrecord_authentication.value == "")
+ {
+ alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
+ editconnection.dcrecord_authentication.focus();
+ return;
+ }
+ editconnection.dcrecord_op.value="Add";
+ postFormSetAnchor("dcrecord");
+}
+
+//-->
+</script>
+
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration_Cache.html b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration_Cache.html
new file mode 100644
index 0000000..384abd1
--- /dev/null
+++ b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration_Cache.html
@@ -0,0 +1,37 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ 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.
+-->
+
+#if($TabName == $ResourceBundle.getString('SharePointAuthority.Cache'))
+
+<table class="displaytable">
+ <tr><td class="separator" colspan="2"><hr/></td></tr>
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetime'))</nobr></td>
+ <td class="value"><input type="text" size="5" name="cachelifetime" value="$Encoder.attributeEscape($CACHELIFETIME)"/> $Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.minutes'))</td>
+ </tr>
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSize'))</nobr></td>
+ <td class="value"><input type="text" size="5" name="cachelrusize" value="$Encoder.attributeEscape($CACHELRUSIZE)"/></td>
+ </tr>
+</table>
+
+#else
+
+<input type="hidden" name="cachelifetime" value="$Encoder.attributeEscape($CACHELIFETIME)"/>
+<input type="hidden" name="cachelrusize" value="$Encoder.attributeEscape($CACHELRUSIZE)"/>
+
+#end
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration_DomainController.html b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration_DomainController.html
similarity index 100%
rename from connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration_DomainController.html
rename to connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editADConfiguration_DomainController.html
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration.js b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration.js
index 3006a73..9fed1f9 100644
--- a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration.js
+++ b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration.js
@@ -19,26 +19,6 @@
<!--
function checkConfig()
{
- var i = 0;
- var count = editconnection.dcrecord_count.value;
- while (i < count)
- {
- var username = eval("editconnection.dcrecord_username_"+i+".value");
- if (username == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
- eval("editconnection.dcrecord_username_"+i+".focus()");
- return false;
- }
- var authentication = eval("editconnection.dcrecord_authentication_"+i+".value");
- if (authentication == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
- eval("editconnection.dcrecord_authentication_"+i+".focus()");
- return false;
- }
- i += 1;
- }
if (editconnection.serverPort.value != "" && !isInteger(editconnection.serverPort.value))
{
alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.PleaseSupplyAValidNumber'))");
@@ -149,60 +129,6 @@
return true;
}
-function deleteDC(i)
-{
- eval("editconnection.dcrecord_op_"+i+".value=\"Delete\"");
- postFormSetAnchor("dcrecord");
-}
-
-function insertDC(i)
-{
- if (editconnection.dcrecord_domaincontrollername.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.EnterADomainControllerServerName'))");
- editconnection.dcrecord_domaincontrollername.focus();
- return;
- }
- if (editconnection.dcrecord_username.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
- editconnection.dcrecord_username.focus();
- return;
- }
- if (editconnection.dcrecord_authentication.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
- editconnection.dcrecord_authentication.focus();
- return;
- }
- eval("editconnection.dcrecord_op_"+i+".value=\"Insert\"");
- postFormSetAnchor("dcrecord_"+i);
-}
-
-function addDC()
-{
- if (editconnection.dcrecord_domaincontrollername.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.EnterADomainControllerServerName'))");
- editconnection.dcrecord_domaincontrollername.focus();
- return;
- }
- if (editconnection.dcrecord_username.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserNameCannotBeNull'))");
- editconnection.dcrecord_username.focus();
- return;
- }
- if (editconnection.dcrecord_authentication.value == "")
- {
- alert("$Encoder.bodyJavascriptEscape($ResourceBundle.getString('SharePointAuthority.AuthenticationCannotBeNull'))");
- editconnection.dcrecord_authentication.focus();
- return;
- }
- editconnection.dcrecord_op.value="Add";
- postFormSetAnchor("dcrecord");
-}
-
function ShpDeleteCertificate(aliasName)
{
editconnection.shpkeystorealias.value = aliasName;
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration_AuthorizationModel.html b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration_AuthorizationModel.html
deleted file mode 100644
index 4d112e6..0000000
--- a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/editConfiguration_AuthorizationModel.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- 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.
--->
-
-#if($TabName == $ResourceBundle.getString('SharePointAuthority.AuthorizationModel'))
-
-<table class="displaytable">
- <tr><td class="separator" colspan="2"><hr/></td></tr>
- <tr>
- <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.AuthorizationModelColon'))</nobr></td>
- <td class="value">
- #if($AUTHORIZATIONMODEL == 'Classic')
- <input type="radio" name="authorizationModel" value="Classic" checked="true"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.Classic'))</nobr></input>
- #else
- <input type="radio" name="authorizationModel" value="Classic"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.Classic'))</nobr></input>
- #end
- #if($AUTHORIZATIONMODEL == 'ClaimSpace')
- <input type="radio" name="authorizationModel" value="ClaimSpace" checked="true"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.ClaimSpace'))</nobr></input>
- #else
- <input type="radio" name="authorizationModel" value="ClaimSpace"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.ClaimSpace'))</nobr></input>
- #end
- </td>
- </tr>
-</table>
-
-#else
-
-<input type="hidden" name="authorizationModel" value="$AUTHORIZATIONMODEL"/>
-
-#end
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewADConfiguration.html b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewADConfiguration.html
new file mode 100644
index 0000000..666c2e3
--- /dev/null
+++ b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewADConfiguration.html
@@ -0,0 +1,62 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ 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.
+-->
+
+<table class="displaytable">
+ <tr>
+ <td class="description">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainControllers'))</td>
+ <td class="boxcell">
+ <table class="formtable">
+ <tr class="formheaderrow">
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainControllerName'))</td>
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainSuffix'))</td>
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserName'))</td>
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.AdministrativePassword'))</td>
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.Authentication'))</td>
+ <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.LoginNameADAttribute'))</td>
+ </tr>
+#set($dccounter = 0)
+#foreach($domaincontroller in $DOMAINCONTROLLERS)
+ #if(($dccounter % 2) == 0)
+ <tr class="evenformrow">
+ #else
+ <tr class="oddformrow">
+ #end
+ <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('DOMAINCONTROLLER'))</nobr></td>
+ <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('SUFFIX'))</nobr></td>
+ <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('USERNAME'))</nobr></td>
+ <td class="formcolumncell"><nobr>******</nobr></td>
+ <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('AUTHENTICATION'))</nobr></td>
+ <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('USERACLsUSERNAME'))</nobr></td>
+ </tr>
+ #set($dccounter = $dccounter + 1)
+#end
+ </table>
+ </td>
+ </tr>
+
+ <tr><td class="separator" colspan="2"><hr/></td></tr>
+
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetime'))</nobr></td>
+ <td class="value"><nobr>$Encoder.bodyEscape($CACHELIFETIME)</nobr> $Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.minutes'))</td>
+ </tr>
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSize'))</nobr></td>
+ <td class="value"><nobr>$Encoder.bodyEscape($CACHELRUSIZE)</nobr></td>
+ </tr>
+
+</table>
diff --git a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewConfiguration.html b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewConfiguration.html
index 65b0060..d70017a 100644
--- a/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewConfiguration.html
+++ b/connectors/sharepoint/connector/src/main/resources/org/apache/manifoldcf/authorities/authorities/sharepoint/viewConfiguration.html
@@ -17,51 +17,6 @@
<table class="displaytable">
<tr>
- <td class="description">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainControllers'))</td>
- <td class="boxcell">
- <table class="formtable">
- <tr class="formheaderrow">
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainControllerName'))</td>
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.DomainSuffix'))</td>
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.AdministrativeUserName'))</td>
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.AdministrativePassword'))</td>
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.Authentication'))</td>
- <td class="formcolumnheader">$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.LoginNameADAttribute'))</td>
- </tr>
-#set($dccounter = 0)
-#foreach($domaincontroller in $DOMAINCONTROLLERS)
- #if(($dccounter % 2) == 0)
- <tr class="evenformrow">
- #else
- <tr class="oddformrow">
- #end
- <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('DOMAINCONTROLLER'))</nobr></td>
- <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('SUFFIX'))</nobr></td>
- <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('USERNAME'))</nobr></td>
- <td class="formcolumncell"><nobr>******</nobr></td>
- <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('AUTHENTICATION'))</nobr></td>
- <td class="formcolumncell"><nobr>$Encoder.bodyEscape($domaincontroller.get('USERACLsUSERNAME'))</nobr></td>
- </tr>
- #set($dccounter = $dccounter + 1)
-#end
- </table>
- </td>
- </tr>
-
- <tr><td class="separator" colspan="2"><hr/></td></tr>
-
- <tr>
- <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetime'))</nobr></td>
- <td class="value"><nobr>$Encoder.bodyEscape($CACHELIFETIME)</nobr> $Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.minutes'))</td>
- </tr>
- <tr>
- <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSize'))</nobr></td>
- <td class="value"><nobr>$Encoder.bodyEscape($CACHELRUSIZE)</nobr></td>
- </tr>
-
- <tr><td class="separator" colspan="2"><hr/></td></tr>
-
- <tr>
<td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.ServerSharePointVersion'))</nobr></td>
<td class="value">
#if($SERVERVERSION == '2.0')
@@ -145,4 +100,15 @@
</td>
</tr>
+ <tr><td class="separator" colspan="2"><hr/></td></tr>
+
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLifetime'))</nobr></td>
+ <td class="value"><nobr>$Encoder.bodyEscape($CACHELIFETIME)</nobr> $Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.minutes'))</td>
+ </tr>
+ <tr>
+ <td class="description"><nobr>$Encoder.bodyEscape($ResourceBundle.getString('SharePointAuthority.CacheLRUSize'))</nobr></td>
+ <td class="value"><nobr>$Encoder.bodyEscape($CACHELRUSIZE)</nobr></td>
+ </tr>
+
</table>
diff --git a/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authorities/BaseAuthorityConnector.java b/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authorities/BaseAuthorityConnector.java
index 7c74027..304c919 100644
--- a/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authorities/BaseAuthorityConnector.java
+++ b/framework/pull-agent/src/main/java/org/apache/manifoldcf/authorities/authorities/BaseAuthorityConnector.java
@@ -34,6 +34,7 @@
{
public static final String _rcsid = "@(#)$Id: BaseAuthorityConnector.java 988245 2010-08-23 18:39:35Z kwright $";
+ // For repositories that have the ability to deny access based on a user's access tokens
protected static final AuthorizationResponse RESPONSE_UNREACHABLE = new AuthorizationResponse(new String[]{GLOBAL_DENY_TOKEN},
AuthorizationResponse.RESPONSE_UNREACHABLE);
protected static final AuthorizationResponse RESPONSE_USERNOTFOUND = new AuthorizationResponse(new String[]{GLOBAL_DENY_TOKEN},
@@ -41,6 +42,14 @@
protected static final AuthorizationResponse RESPONSE_USERUNAUTHORIZED = new AuthorizationResponse(new String[]{GLOBAL_DENY_TOKEN},
AuthorizationResponse.RESPONSE_USERUNAUTHORIZED);
+ // For repositories that DO NOT have the ability to deny access based on a user's access tokens
+ protected static final AuthorizationResponse RESPONSE_UNREACHABLE_ADDITIVE = new AuthorizationResponse(new String[0],
+ AuthorizationResponse.RESPONSE_UNREACHABLE);
+ protected static final AuthorizationResponse RESPONSE_USERNOTFOUND_ADDITIVE = new AuthorizationResponse(new String[0],
+ AuthorizationResponse.RESPONSE_USERNOTFOUND);
+ protected static final AuthorizationResponse RESPONSE_USERUNAUTHORIZED_ADDITIVE = new AuthorizationResponse(new String[0],
+ AuthorizationResponse.RESPONSE_USERUNAUTHORIZED);
+
/** Obtain the access tokens for a given user name.
*@param userName is the user name or identifier.
*@return the response tokens (according to the current authority).