Who Moved My krb5.ini?

Java Kerberos 5, on Windows, looks for a config file named krb5.ini in the Windows directory, and a Windows directory is defined as the return value of the Win32 API GetWindowsDirectory(), which should normally return something like C:\\Windows.

But, since Windows Server 2003, something has changed. The Terminal Services Programming Guidelines has these words: In a Terminal Services environment, the Windows directory is guaranteed to be private for each user.

So this means if your (post Windows 2003) system has Terminal Services turned on, Java would look for krb5.ini inside %YOUR_HOME%\\Windows. This is bad, since we believe that the Kerberos 5 setting is a system-wide configuration, which should be setup once for all. To fix this problem, we make some changes in the OpenJDK codes. From now on, Java will look for krb5.ini in both GetWindowsDirectory() and GetSystemWindowsDirectory(),

FAQ:
  1. Why is GetWindowsDirectory() still called? why is it even preferred to GetSystemWindowsDirectory()?
    There are two reasons. First, compatibility matters. It is very possible that users out there have already noticed this issue and have put krb5.ini inside the user-private Windows directory instead of the system-wide one. For these users, JDK 7 should still work for them. Second, it's a common sense that user settings should override system settings. Therefore, user-private Windows is preferred to system-wide Windows.
  2. I'm still using JDK 6 and I don't like this user-private Windows directory, what shall I do?
    There are three solutions. First, you can provide the -Djava.security.krb5.conf=/path/to/my/krb5.ini option to your Java command line, or setup the environment variable _JAVA_OPTIONS to contain this value. Second, the most preferred Kerberos 5 config file is krb5.conf inside [JRE]/lib/security. Use this file is always safe (Note: it's krb5.conf, not krb5.ini). Third, you can trick the Windows to still return C:\\Windows for GetWindowsDirectory(). To do this, add a registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Compatibility\\Application\\JAVA, with a 32-bit DWORD value Flags=0x408. If you want to use Java's Kerberos command kinit, klist etc, provide keys with the name KINIT, KLIST etc.
P.S.: A minor Windows 2008 bug (or maybe not a bug, see below) makes this problem a little tougher. On Windows Server 2008, GetWindowsDirectory(NULL,0) returns the length of the system-wide directory, but not the user-private one. Thus our original trick of get-length-then-allocate-then-get-value fails, and JDK 6 cannot locate the correct user-private Windows directory. If you met this problem, you would have to choose one of the three workarounds above. MSDN never says the first parameter of this API can be NULL, although quite a lot of people are using the same trick.

The positive side is, we always print out the pathname of the krb5.ini file we're using in the debug output. Just add the -Dsun.security.krb5.debug=true option to your java command line to make sure it's using the krb5.ini of your intention.
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

This blog has a comments managing system that requires me to approve each comment manually. Please do not re-post and I will reply it (if I have an answer) when I get pinged.

Search

Top Tags
Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today