Thursday, June 3, 2010

Can't map profile properties to AD fields in SharePoint? Read this!

If you've come across the error below, you are no doubt wondering what it actually means and more importantly how to fix it. Don't worry; you aren't alone.

Note: The selection of directory service properties may be disabled if the shared service provider is in an untrusted domain or if profile import is not configured.

Note: The selection of directory service properties is disabled because the portal is in an untrusted domain or no directory service import is configured yet.

Security Note: If you are using a high privilege account to import, you will be able to read and import directory attributes that are not normally accessible by users.

This one took me a while to figure out. The fix was rather simple in my case. It was a simple mismatch in Import Connections under the SSP User Profiles and Properties section. One of the connections was named after the NetBIOS name of the domain instead of the FQDN of the domain.

For example, the original connection was named domain when the domain's fully qualified name was users.domain.com. I created a new connection and named it users.domain.com and deleted the connection called domain. This was all done in the SSP's User Profiles and Properties section under Import Connections.

Once I created a new connection named after the domain's FQDN SharePoint decided it would let me map Active Directory fields to user profile fields.

All is well in the world again and I can continue with my late night work.

Monday, April 26, 2010

WinHTTP, .net, IE and Proxy Server Fun

Today, I was working on finalizing a solution for proxy auto configuration for the company I work for. The script that I had worked great with Firefox and Internet Explorer 6 and up. I found out quickly however, it did not work with WinHTTP or .net automatic proxy configuration. Anything dependent on either one of those got a proxy or went directly to the resource when it shouldn't have. Of course, this wouldn't fly.

After many hours of trial and error I came to the conclusion that WinHTTP and .net behave differently from their browser counterparts in a very significant way. When executing the script in a PAC file, browsers do not need to have the host wrapped in the dnsResolve function. WinHTTP and .net do need this however in order to properly determine when to use a proxy server.

Here is original proxy script I had that worked only with browsers:
function FindProxyForURL(url, host)
{
var myIPAddr = myIpAddress();

// Bypass proxy settings for internal domains and private IP ranges
if (isInNet(host, "10.0.0.0", "255.0.0.0") ||
isInNet(host, "192.168.0.0", "255.255.0.0") ||
isInNet(host, "172.16.0.0", "255.240.0.0") ||
isInNet(host, "127.0.0.1", "255.255.255.255") ||
isPlainHostName(host) ||
dnsDomainIs(host, ".domain-one.example.com") ||
dnsDomainIs(host, ".domain-two.example.com") ||
dnsDomainIs(host, ".domain-three.example.com") ||
dnsDomainIs(host, ".domain-four.example.com"))
{
return "DIRECT";
}
// Location 1 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.1.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.2.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.3.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.4.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.5.0.0", "255.255.0.0") )
{
return "PROXY PROXYSERV1:8080; DIRECT";
}
// Location 2 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.6.0.0", "255.255.0.0"))
{
return "PROXY PROXYSERV2:8080; DIRECT";
}
// Location 3 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.7.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.8.0.0", "255.255.0.0"))
{
return "PROXY PROXYSERV3:8080; DIRECT";
}

// Catch all for locations without proxy servers
else
{
return "DIRECT";
}
}

Here is the final PAC file that works with browsers, WinHTTP and .net:

function FindProxyForURL(url, host)
{
var ipAddr = dnsResolve (host);
var myIPAddr = myIpAddress();

// Bypass proxy settings for internal domains and private IP ranges
if (isInNet(ipAddr, "10.0.0.0", "255.0.0.0") ||
isInNet(ipAddr, "192.168.0.0", "255.255.0.0") ||
isInNet(ipAddr, "172.16.0.0", "255.240.0.0") ||
isInNet(ipAddr, "127.0.0.1", "255.255.255.255") ||
isPlainHostName(host) ||
dnsDomainIs(host, ".domain-one.example.com") ||
dnsDomainIs(host, ".domain-two.example.com") ||
dnsDomainIs(host, ".domain-three.example.com") ||
dnsDomainIs(host, ".domain-four.example.com"))
{
return "DIRECT";
}
// Location 1 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.1.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.2.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.3.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.4.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.5.0.0", "255.255.0.0") )
{
return "PROXY PROXYSERV1:8080; DIRECT";
}
// Location 2 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.6.0.0", "255.255.0.0"))
{
return "PROXY PROXYSERV2:8080; DIRECT";
}
// Location 3 - Use Proxy server first then use direct if necessary
else if (isInNet(myIPAddr, "10.7.0.0", "255.255.0.0") ||
isInNet(myIPAddr, "10.8.0.0", "255.255.0.0"))
{
return "PROXY PROXYSERV3:8080; DIRECT";
}

// Catch all for locations without proxy servers
else
{
return "DIRECT";
}
}

The differences are subtle but ever so important while implementing a proxy server auto configuration solution. Ensuring that WinHTTP and .net work like the browser should help ensure you don't get caught with servers/services and even client applications improperly using a proxy server. Of course with servers, the best option is to configure the WinHTTP options manually. This prevents the service from taking the performance penalty associated with automatic proxy discovery.

To manually configure the WinHTTP proxy server on computer you can either use proxycfg.exe or my preferred method of netsh. To set the proxy server and exclusions with netsh you can run the following command from the command prompt.

netsh winhttp set proxy proxyserver:8080 "<local>;server.domain.example.com"

The <local> entry tells WinHTTP to bypass the proxy for servers which use a relative name. Don't forget to run that command prompt as an administrator on Vista/7/2008/2008 R2 machines or you will get an access denied error.

If you ever need to clear out the WinHTTP proxy information you can run this command (again, as an administrator):

netsh winhttp reset proxy

And thus concludes my proxy server auto configuration odyssey.