Solving timeout issues with ActiveDirectory
From Provider Wiki
Starting with 10.3 MacOS X has had the ability to connect to ActiveDirectory servers and use them as a source for user authorization/authentication. But this system does have a weakness if you have a user outside of your network who can resolve the IP address for your domain controllers, but can't connect to them (for example if there is a firewall in the way). The usual symptoms of this case are that the computer takes a very long time to get to a point where it allows logins, namely four minutes per domain controller that you have.
There are three solutions to this problem:
Contents |
Unplug the Network
MacOS X does have some good ideas built into its system to determin if it can see a domain controller. It knows that if there is no avalible networks that it should not look for the domain controller. So a solution that can work is to make sure that you startup the computer without any network available to it. The problem with this is it requires people who have wireless routers at home to remember when they are shutting down a computer that they will be starting it up at home and remember to shut down their AirPort connections. This is a real pain to do for most users, so this option should probably be avoided.
Split DNS
The first solution is to use "split DNS" servers: one that works internally for your network (everywhere that can connect to the domain controller, and one that serves the outside world. Then you simply make your domain controllers resolvable from inside your domain, but make sure that there is no entry available to those outside your domain.
Unfortunately this is probably not an option on PennNet, and requires a fairly knowledgeable admin to troubleshoot the problems this could cause.
Change the AD Timeout
The final solution to the problem is to change the timeout period to the ActiveDirectory servers from its 4 minute default value to something a bit shorter. As long as you give it a bit of time (5 seconds or more) this should not cause any problems with your system, but you might have to play with the values a bit.
The value is stored in the following file:/Library/Preferences/DirectoryService/ActiveDirectory.plistThe fields we are looking for are all of the ones labeled "LDAP Connection Timeout", and there can be a number of them. The initial value should be "240", and that number is the number of seconds that the system should wait after trying each of the listed servers (one after another). Once you have change that value you just need to either restart the computer, or you can:
sudo killall DirectoryServiceThe service will automatically restart within a few seconds of being killed, so this should work itself out.
For those of you who would like a more point-and-click version, I have created the following AppleScript. This script is heavily based on one from the MacEnterperise.org site, and in fact I have just wrapped their python script in an AppleScript:
-- this script borrows heavily (in fact the whole python portion) from the python script on MacEnterprise's site: http://macenterprise.org/content/view/248/84/
set errormessage to ""
try
set currentValue to do shell script "defaults read /Library/Preferences/DirectoryService/ActiveDirectory 'LDAP Connection Timeout'" with administrator privileges
on error
display alert "There has been an interneal error. Possibly there is no ActiveDirectory server setup for this computer, or you tried to run this script without Administrative Access." buttons {"Ok"}
return
end try
repeat
set theAnswer to display dialog errormessage & " Directory Services will currently wait " & currentValue & " seconds for a connection to the ActiveDirectory server(s). The default value is 240 seconds. What would you like to set it to?" default answer currentValue with title "Enter AD Timeout"
try
set timeOutValue to text returned of theAnswer as number
exit repeat
on error
beep
set errormessage to "Error: please enter only the number of seconds you would like DirectoryServices to wait.
"
end try
end repeat
--set timeOutValue to 10
set thisCommand to "#!/usr/bin/python
import plistlib
import sys
try:
plist = plistlib.Plist.fromFile('/Library/Preferences/DirectoryService/ActiveDirectory.plist')
for key in plist['AD Domain Node List']:
plist['AD Domain Node List'][key]['LDAP Connection Timeout'] = " & timeOutValue & "
plist['LDAP Connection Timeout'] = " & timeOutValue & "
plist.write('/Library/Preferences/DirectoryService/ActiveDirectory.plist')
except IOError, (strerror):
print strerror
except:
print 'Unexpected error:', sys.exc_info()[0]"
do shell script "echo " & quoted form of thisCommand & " | python" with administrator privileges
do shell script "killall DirectoryService" with administrator privileges
display alert "The new setting should be in effect."
Please note that the section inside the second starting with "#!/usr/bin/python" is white-space sensitive, so there needs to be one or two tabs in front of those areas. At some point some web-space will be made available for the purpose of posting scripts like this, but at the moment you can contact me at 'larkost AT isc DOT upenn DOT edu' for a packaged version of the script.
References
In writing this article the following site was used extensively, and the script is heavily based upon a script on it: [1] I also am drawing on knowledge gained from a lot of various emails from the MacEnterprise mailing list, OmiGroups mailing lists, and the Apple lists.
