Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8208295

Improve KDC Service Locator on Windows

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Fix
    • P4
    • None
    • 8u172
    • security-libs

    Description

      The method KrbServiceLocator located in sun.security.krb5.KrbServiceLocator can return wrong KDC on Windows.

      When we extract SRV records from the DNS, we order them using their priority for example. But on Windows and in large companies, the priority is set to zero. Therefore, the KDC list is not well ordered.

      However, a client can be in a "site". So when querying the KDC, it should first qurery its site, then query the domain. See https://servergurunow.wordpress.com/2017/10/14/dc-locator-process-2/

      Practically, this means that we could get this site and query it first in KrbServiceLocator. Today we do :
      String dnsUrl = "dns:///_kerberos." + protocol + "." + realmName;

      We could do :
      String dnsUrl = "dns:///_kerberos." + protocol + "." +dynamicSiteName+"._sites"+ realmName;

      The SRV record returned would be positioned first, and then do the query on the domain and place them after.

      Today, this issue is problematic because we are retrieving wrong KDC and the queries are not working. Thus we have to wait 3 retry of 30s timeout before the second KDC is tried.
      Our solution was to call JNA directly like that :
      /**
           * @return a Pair containing the realm as key and the domain controller
           * currently running the Kerberos Key Distribution Center service. The DC
           * can be null if an error occurs. The returning Pair may be null if the
           * DomainController can't be retrieved through Windows jna call.
           */
          public static Pair<String, String> getKDCInfo() {
              /**
               * This method can be seen here :
               * https://docs.microsoft.com/en-us/windows/desktop/api/dsgetdc/nf-dsgetdc-dsgetdcnamea
               * The flag values have been found here :
               * https://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/ComIntegration/SafeNativeMethods.cs,90bb64da066ab4fd
               */
              int DS_KDC_REQUIRED = 0x00000400;
              int DS_IP_REQUIRED = 0x00000200;
              int DS_TRY_NEXTCLOSEST_SITE = 0x00040000;
              int DS_FORCE_REDISCOVERY = 0x00000001;
              int DS_RETURN_DNS_NAME = 0x40000000;

              //Create a domainController that will be filled.
              PDOMAIN_CONTROLLER_INFO info = new PDOMAIN_CONTROLLER_INFO();
              //We specifically request for the KDC domain controller.
              Netapi32.INSTANCE.DsGetDcName(null, null, null, null, DS_KDC_REQUIRED | DS_IP_REQUIRED | DS_TRY_NEXTCLOSEST_SITE | DS_FORCE_REDISCOVERY | DS_RETURN_DNS_NAME, info);
              if (info.dci != null && info.dci.DomainName != null && info.dci.DomainControllerName != null) {
                  String domainName = info.dci.DomainName.toString();
                  String domainControllerName = info.dci.DomainControllerName.toString();
                  if (!domainName.isEmpty() && !domainControllerName.isEmpty()) {
                      // Kerberos realm (domain name) must be uppercase.
                      return new Pair<>(domainName.toUpperCase(), domainControllerName.replaceAll("\\\\", ""));
                  }
              }
              return null;
          }

      I'm opened to any suggestion, work-around and explanations as I'm not an expert on that subject.

      Attachments

        Issue Links

          Activity

            People

              weijun Weijun Wang
              shadzic Samir Hadzic
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: