Configuration of People Picker Settings

The Windows SharePoint Services provisioning stack introduced in Hosted Messaging and Collaboration version 4.0 includes a SharePoint2007Provider, a ManagedSharepoint2007 namespace and a HostedSharePoint2007 namespaces. The API set provided across these layers is limited though in that it does not provide essential limitation of picking people cross different organization. In Hosted Messaging and Collaboration version 4.5 the ability to limit the people picker searching and picking people across different organization is introduced.

Setting ServiceAccountDirectoryPaths

The need to set ServiceAccountDirectoryPaths comes from the new way in which Windows SharePoint Services SP1 locks down its LDAP queries to a multi-valued list of paths. In some situations the Windows SharePoint Services need to enumerate the service accounts therefore these service accounts need to be within the scope of an LDAP query.

Users container under root domain path and other user containers specified by WSS Server administrator are added into the ServiceAccountDirectoryPaths of all web applications:

  1. Root domain path is retrived from rootDomainNamingContext property of RootDSE on managed layer.
  2. Other user containers are saved in web.config file on Windows SharePoint Server.

The format of web.config file looks like the following:

<?xml version="1.0"?>

<configuration>

  <appSettings>
	<!-- to turn on debugging, set this key to true -->
	<add key="writeDebug" value="false" />
	<!-- if debugging is on, this directory must exist (file will be created) -->
	<add key="logLocation" value="c:\debug\mpsadmin.log" />
	<!-- to add Domain Users Paths to Web Application Service Account Directory Paths.
		 serviceAccountDirectoryPaths: Service Account Paths can be added here, semi comma delimited.
		 Example:
		 <add key="serviceAccountDirectoryPaths" value="CN=Users,DC=US,DC=Fabrikam,DC=Com;CN=Users,DC=UK,DC=Fabrikam,DC=Com"/>
	-->
	<add key="serviceAccountDirectoryPaths" value=""/>
  </appSettings>
  <connectionStrings/>

  <system.web>
	<!-- 
			Set compilation debug="true" to insert debugging 
			symbols into the compiled page. Because this 
			affects performance, set this value to true only 
			during development.
		-->
	<compilation debug="false" />
	<!--
			The <authentication> section enables configuration 
			of the security authentication mode used by 
			ASP.NET to identify an incoming user. 
		-->
	<authentication mode="Windows" />
	<!--
			The <customErrors> section enables configuration 
			of what to do if/when an unhandled error occurs 
			during the execution of a request. Specifically, 
			it enables developers to configure html error pages 
			to be displayed in place of a error stack trace.

		<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
			<error statusCode="403" redirect="NoAccess.htm" />
			<error statusCode="404" redirect="FileNotFound.htm" />
		</customErrors>
		-->
	<customErrors mode="Off" />
   
	<trust level="Full" originUrl="" />

  </system.web>
</configuration>

Note

The default path for the web.config file is C:\Program Files\Microsoft Hosting\Provisioning\SharePoint Provider\Web Service\web.config. The web.config file is deployed during SPCA installation and can be modified by WSS Server administrator. If the WSS Server administrator wants to add WSS administrator user containers to WSS WebApplications, he must modify the web.config file manually.

Loading ServiceAccountDirectoryPaths from web.config file

Utilities is a common class in SPCA, and it is a static class. All the web service classes' constructors call methods in Utilities. ServiceAccountDirectoryPaths in web.config is loaded in the constructor of Utilities to guarantee it is loaded before all the SPCA web service is started and only loaded once.

The serviceAccountDirectoryPaths is saved in a string array Utilitites::serviceAccountDirectoryPaths, which will be initialized in the constructor.

Utilities::InitializeServiceAccountDirectoryPaths() is called by the constructor of Utilities and loads all the customized ServiceAccountDirectoryPath in the web.config file.

		private static void InitializeServiceAccountDirectoryPaths()
		{
			AppSettingsReader reader = new AppSettingsReader();
			string appServiceAccountDirectoryPaths = (string)reader.GetValue("serviceAccountDirectoryPaths", typeof(string));

			if (!string.IsNullOrEmpty(appServiceAccountDirectoryPaths))
			{
				appServiceAccountDirectoryPaths = appServiceAccountDirectoryPaths.Trim();

				serviceAccountDirectoryPaths = appServiceAccountDirectoryPaths.Split(';');
		}
	}

Setting ServiceAccountDirectoryPaths to Web Applications

We only set the ServiceAccountDirectoryPaths to Web Applications when CreateSite or ModifyCustomerSite is called. The root user container is passed in as an optional parameter of CreateSite or ModifyCustomerSite. Combined with root user container, the other user containers in the Utilitites::serviceAccountDirectoryPaths are set to Web Applications in Utilities:: UpdateServiceAccountDirectoryPaths:

internal static void UpdateServiceAccountDirectoryPaths(string rootServiceAccountDirectoryPath)
		{
			SPFarm farm = SPFarm.Local;

			if (farm == null)
			{
				return;
		}

			SPWebService wssService = farm.Services.GetValue<SPWebService>("");

			SPWebApplicationCollection webApps = wssService.WebApplications;

			foreach (SPWebApplication webApp in webApps)
			{ 		
				webApp.PeoplePickerSettings.ServiceAccountDirectoryPaths.Clear();

				if (!string.IsNullOrEmpty(rootServiceAccountDirectoryPath))
				{
					webApp.PeoplePickerSettings.ServiceAccountDirectoryPaths.Add(rootServiceAccountDirectoryPath);
			}

				if (serviceAccountDirectoryPaths != null)
				{
					foreach (string path in serviceAccountDirectoryPaths)
					{
						if (!string.IsNullOrEmpty(path))
						{
							webApp.PeoplePickerSettings.ServiceAccountDirectoryPaths.Add(path);
					}
				}
			} 

				webApp.Update();
		}
	}

Note

This mothod is called by CreateSite and ModifySite and rootServiceAccountDirectoryPath is passed in.

ServiceAccountDirectoryPaths Behaviors

The behavior of setting ServiceAccountDirectoryPaths can be described as the following:

  1. In the default scenario, there is only one domain in Hosted Messaging and Collaboration version 4.0. So, the web.config file need not be modified. SPCA does not load any user containers in the web.config file. Once a CreateSite or ModifyCustomerSite request with serviceAccountDirectoryPath is received by SPCA, SPCA updates ServiceAccountDirectoryPaths in all the Web Applications.
  2. If there are child domains in Hosted Messaging and Collaboration solution, administrator user containers in child domains should be added into the web.config file after deploying SPCA. After the web.config file is modified, administrator must restart the SPCA to load the ServiceAccountDirectoryPaths into web.config. Once a CreateSite or ModifyCustomerSite request with serviceAccountDirectoryPath is received by SPCA, SPCA updates ServiceAccountDirectoryPaths in all the Web Applications.