1 /*
   2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.krb5;
  27 
  28 import java.io.IOException;
  29 import java.util.Collection;
  30 import java.util.Hashtable;
  31 import java.util.Vector;
  32 
  33 
  34 public class SCDynamicStoreConfig {
  35     private static native void installNotificationCallback();
  36     private static native Hashtable<String, Object> getKerberosConfig();
  37 
  38     static {
  39         java.security.AccessController.doPrivileged(new sun.security.action.LoadLibraryAction("osx"));
  40         installNotificationCallback();
  41     }
  42 
  43     private static Vector<String> unwrapHost(Collection<Hashtable<String, String>> c) {
  44         Vector<String> vector = new Vector<String>();
  45         for (Hashtable<String, String> m : c) {
  46             vector.add(m.get("host"));
  47         }
  48         return vector;
  49     }
  50 
  51     /**
  52      * convertRealmConfigs: Maps the Object graph that we get from JNI to the
  53      * object graph that Config expects. Also the items inside the kdc array
  54      * are wrapped inside Hashtables
  55      */
  56     @SuppressWarnings("unchecked")
  57     private static Hashtable<String, Object> convertRealmConfigs(Hashtable<String, ?> configs) {
  58         Hashtable<String, Object> realmsTable = new Hashtable<String, Object>();
  59 
  60         for (String realm : configs.keySet()) {
  61             // get the kdc
  62             Hashtable<String, Collection<?>> map = (Hashtable<String, Collection<?>>) configs.get(realm);
  63             Collection<Hashtable<String, String>> kdc = (Collection<Hashtable<String, String>>) map.get("kdc");
  64 
  65             // put the kdc into the realmMap
  66             Hashtable<String, Vector<String>> realmMap = new Hashtable<String, Vector<String>>();
  67             if (kdc != null) realmMap.put("kdc", unwrapHost(kdc));
  68 
  69             // put the admin server into the realmMap
  70             Collection<Hashtable<String, String>> kadmin = (Collection<Hashtable<String, String>>) map.get("kadmin");
  71             if (kadmin != null) realmMap.put("admin_server", unwrapHost(kadmin));
  72 
  73             // add the full entry to the realmTable
  74             realmsTable.put(realm, realmMap);
  75         }
  76 
  77         return realmsTable;
  78     }
  79 
  80     /**
  81      * Calls down to JNI to get the raw Kerberos Config and maps the object
  82      * graph to the one that Kerberos Config in Java expects
  83      *
  84      * @return
  85      * @throws IOException
  86      */
  87     @SuppressWarnings("unchecked")
  88     public static Hashtable<String, Object> getConfig() throws IOException {
  89         Hashtable<String, Object> stanzaTable = getKerberosConfig();
  90         if (stanzaTable == null) {
  91             throw new IOException("Could not load configuration from SCDynamicStore");
  92         }
  93         //System.out.println("Raw map from JNI: " + stanzaTable);
  94 
  95         // convert SCDynamicStore realm structure to Java realm structure
  96         Hashtable<String, ?> realms = (Hashtable<String, ?>) stanzaTable.get("realms");
  97         if (realms != null) {
  98             stanzaTable.remove("realms");
  99             Hashtable<String, Object> realmsTable = convertRealmConfigs(realms);
 100             stanzaTable.put("realms", realmsTable);
 101         }
 102 
 103        // System.out.println("stanzaTable : " + stanzaTable);
 104         return stanzaTable;
 105     }
 106 }