[krbdev.mit.edu #6285] Provide SPI to switch the mach port lookup for kipc

Zhanna Tsitkova via RT rt-comment at krbdev.mit.edu
Thu Dec 4 13:44:42 EST 2008


diff -Nur -x '*~' -x '*.orig' -x '*.rej' -x '*.pbxbtree' -x '*.pbxindex' -x lha.mode1v3 -x lha.mode2v3 -x lha.pbxuser -x windows -x .DS_Store Kerberos.AEP-6.5b2.orig/KerberosFramework/Common/Projects/KerberosFramework.xcodeproj/project.pbxproj Kerberos.AEP-6.5b2/KerberosFramework/Common/Projects/KerberosFramework.xcodeproj/project.pbxproj
--- Kerberos.AEP-6.5b2.orig/KerberosFramework/Common/Projects/KerberosFramework.xcodeproj/project.pbxproj	2008-11-09 16:06:52.000000000 -0800
+++ Kerberos.AEP-6.5b2/KerberosFramework/Common/Projects/KerberosFramework.xcodeproj/project.pbxproj	2008-11-06 20:02:34.000000000 -0800
@@ -602,6 +602,15 @@
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 		};
+		EBF664F10EBAD3910046D1CA /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 7;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
@@ -1381,6 +1390,9 @@
 				A1FBC4E907AAF63900872683 /* Sources */,
 				A1FBC4EC07AAF63900872683 /* Frameworks */,
 				A1FBC50107AAF63900872683 /* ShellScript */,
+				EB88E9EF0EBAC9B1001E280A /* ShellScript */,
+				EBF664F70EBAD64A0046D1CA /* ShellScript */,
+				EBF664F10EBAD3910046D1CA /* CopyFiles */,
 				A13849830A23A11900E9FC8B /* CopyFiles */,
 				A1FBC50C07AAF63900872683 /* CopyFiles */,
 				A1FBC50207AAF63900872683 /* CopyFiles */,
@@ -1780,7 +1792,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "INTERMEDIATES_DIR=\"${BUILT_PRODUCTS_DIR}/Kerberos5.intermediates\"\nERROR_TABLES_DIR=\"${INTERMEDIATES_DIR}/ErrorTables\"\n\n# Currently only generating InfoPlist.strings\ncp \"${ERROR_TABLES_DIR}/Localizable.strings\" \"${INTERMEDIATES_DIR}/InfoPlist.strings\"\n";
+			shellScript = "INTERMEDIATES_DIR=\"${BUILT_PRODUCTS_DIR}/Kerberos5.intermediates\"\nERROR_TABLES_DIR=\"${INTERMEDIATES_DIR}/ErrorTables\"\n\n# Currently only generating InfoPlist.strings\ncp \"${ERROR_TABLES_DIR}/Localizable.strings\" \"${INTERMEDIATES_DIR}/Localizable.strings\"\n";
 		};
 		A1FBC50107AAF63900872683 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
@@ -1803,6 +1815,32 @@
 			shellPath = /bin/sh;
 			shellScript = "INSTALLED_EXECUTABLE=${INSTALL_PATH}/${PRODUCT_NAME}.${WRAPPER_EXTENSION}/${PRODUCT_NAME}\nUSRLIB=${DSTROOT}/usr/lib\n\n/bin/mkdir -p \"${USRLIB}\"\nfor LIBRARY in com_err des425 krb4 krb5 krb524 krb5support k5crypto gssapi_krb5\ndo\n\t/bin/rm -f \"${USRLIB}/lib${LIBRARY}.dylib\"\n\t/bin/ln -s \"${INSTALLED_EXECUTABLE}\" \"${USRLIB}/lib${LIBRARY}.dylib\"\ndone\n";
 		};
+		EB88E9EF0EBAC9B1001E280A /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\nINTERMEDIATES_DIR=\"${BUILT_PRODUCTS_DIR}/Kerberos5.intermediates\"\nL10NSTRINGS=${DSTROOT}/System/Library/Frameworks/Kerberos.framework/Resources/English.lproj\n\nmkdir \"${L10NSTRINGS}\"\ncp \"${INTERMEDIATES_DIR}/Localizable.strings\" \"${L10NSTRINGS}\"/\n";
+		};
+		EBF664F70EBAD64A0046D1CA /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\nSRC_DIR=\"${SRCROOT}/../../Kerberos5/Sources/util/mac/\"\nHEADERS=${DSTROOT}/System/Library/Frameworks/Kerberos.framework/PrivateHeaders\n\ncp \"${SRC_DIR}/krb5-ipc.h\" \"${HEADERS}\"/\n";
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
diff -Nur -x '*~' -x '*.orig' -x '*.rej' -x '*.pbxbtree' -x '*.pbxindex' -x lha.mode1v3 -x lha.mode2v3 -x lha.pbxuser -x windows -x .DS_Store Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Projects/krb5.pbexp Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Projects/krb5.pbexp
--- Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Projects/krb5.pbexp	2008-11-09 16:06:53.000000000 -0800
+++ Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Projects/krb5.pbexp	2008-11-06 20:02:34.000000000 -0800
@@ -344,3 +344,5 @@
 _krb5_cc_get_config
 _krb5_cc_set_config
 _krb5_is_config_principal
+_krb5_ipc_client_set_target_uid
+_krb5_ipc_client_clear_target
diff -Nur -x '*~' -x '*.orig' -x '*.rej' -x '*.pbxbtree' -x '*.pbxindex' -x lha.mode1v3 -x lha.mode2v3 -x lha.pbxuser -x windows -x .DS_Store Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Sources/util/mac/k5_mig_client.c Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Sources/util/mac/k5_mig_client.c
--- Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Sources/util/mac/k5_mig_client.c	2008-11-09 16:06:54.000000000 -0800
+++ Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Sources/util/mac/k5_mig_client.c	2008-11-09 15:46:30.000000000 -0800
@@ -27,18 +27,44 @@
 #ifndef LEAN_CLIENT
 
 #include "k5_mig_client.h"
+#include "krb5-ipc.h"
 #include "k5_mig_request.h"
 #include "k5_mig_replyServer.h"
 #include "k5-thread.h"
 
 #include <mach/mach.h>
+#include <mach/task_special_ports.h>
 #include <servers/bootstrap.h>
+#include <dlfcn.h>
 
 
+/* ------------------------------------------------------------------------ */
 
 /* Number of services available.  Update if modifying the lists below */
 #define KIPC_SERVICE_COUNT 2
 
+/* This struct exists to hold the per-thread connection port used for ipc
+ * messages to the server.  Each thread is issued a separate connection 
+ * port so that the server can distinguish between threads in the same 
+ * application. */
+
+typedef struct k5_ipc_connection {
+    const char *service_id;
+    mach_port_t port;
+} *k5_ipc_connection;
+
+typedef struct k5_ipc_connection_info {
+    struct k5_ipc_connection connections[KIPC_SERVICE_COUNT];
+    boolean_t server_died;
+    k5_ipc_stream reply_stream;
+} *k5_ipc_connection_info;
+
+/* initializer for k5_ipc_request_port to fill in server names in TLS */
+static const char *k5_ipc_known_services[KIPC_SERVICE_COUNT] = { 
+"edu.mit.Kerberos.CCacheServer",
+"edu.mit.Kerberos.KerberosAgent" };
+
+
 /* ------------------------------------------------------------------------ */
 
 /* This struct exists to store the global service port shared between all
@@ -57,28 +83,64 @@
 { "edu.mit.Kerberos.CCacheServer", MACH_PORT_NULL },
 { "edu.mit.Kerberos.KerberosAgent", MACH_PORT_NULL } };
 
-/* ------------------------------------------------------------------------ */
+static int use_uid = 0;
+static uid_t targetuid;
 
-/* This struct exists to hold the per-thread connection port used for ipc
- * messages to the server.  Each thread is issued a separate connection 
- * port so that the server can distinguish between threads in the same 
- * application. */
+static void
+clear_cache(void)
+{      
+    k5_ipc_connection_info cinfo;
+    int i;
+        
+    /* assume lock is taken */
+    for (i = 0; i < KIPC_SERVICE_COUNT; i++) {
+	if (MACH_PORT_VALID (g_service_ports[i].service_port)) {
+	    mach_port_destroy (mach_task_self (), 
+			       g_service_ports[i].service_port); 
+	    g_service_ports[i].service_port = MACH_PORT_NULL;
+	}
+    }
+
+    cinfo = k5_getspecific (K5_KEY_IPC_CONNECTION_INFO);
+    if (cinfo) {
+	for (i = 0; i < KIPC_SERVICE_COUNT; i++) {
+            if (MACH_PORT_VALID (cinfo->connections[i].port))
+		mach_port_deallocate(mach_task_self(), 
+				     cinfo->connections[i].port);
+	    cinfo->connections[i].port = MACH_PORT_NULL;
+	}
+    }
+}
 
-typedef struct k5_ipc_connection {
-    const char *service_id;
-    mach_port_t port;
-} *k5_ipc_connection;
 
-typedef struct k5_ipc_connection_info {
-    struct k5_ipc_connection connections[KIPC_SERVICE_COUNT];
-    boolean_t server_died;
-    k5_ipc_stream reply_stream;
-} *k5_ipc_connection_info;
+void
+krb5_ipc_client_set_target_uid(uid_t uid)
+{
+    int err;
+
+    err = k5_mutex_lock (&g_service_ports_mutex);
+    if (!err) {
+	use_uid = 1;
+	targetuid = uid;
+	clear_cache();
+        k5_mutex_unlock (&g_service_ports_mutex);
+    }
+}
+
+void
+krb5_ipc_client_clear_target(void)
+{
+    int err;
+
+    err = k5_mutex_lock (&g_service_ports_mutex);
+    if (!err) {
+	use_uid = 0;
+	clear_cache();
+        k5_mutex_unlock (&g_service_ports_mutex);
+    }
+}
+
 
-/* initializer for k5_ipc_request_port to fill in server names in TLS */
-static const char *k5_ipc_known_services[KIPC_SERVICE_COUNT] = { 
-"edu.mit.Kerberos.CCacheServer",
-"edu.mit.Kerberos.KerberosAgent" };
 
 /* ------------------------------------------------------------------------ */
 
@@ -164,15 +226,7 @@
     err = k5_mutex_lock (&g_service_ports_mutex);
 
     if (!err) {
-        int i;
-        
-        for (i = 0; i < KIPC_SERVICE_COUNT; i++) {
-            if (MACH_PORT_VALID (g_service_ports[i].service_port)) {
-                mach_port_destroy (mach_task_self (), 
-                                   g_service_ports[i].service_port); 
-                g_service_ports[i].service_port = MACH_PORT_NULL;
-            }
-        }
+	clear_cache();
         k5_mutex_unlock (&g_service_ports_mutex);
     }
     
@@ -180,6 +234,53 @@
     k5_mutex_destroy (&g_service_ports_mutex);
 }
 
+/* SPI */ kern_return_t
+bootstrap_look_up_per_user(mach_port_t, name_t, uid_t, mach_port_t *);
+
+
+static int
+get_service_port(char *service, mach_port_t *sport)
+{
+    int ret;
+
+    if (use_uid) {
+	mach_port_t rootbs;
+
+        ret = task_get_bootstrap_port(mach_task_self(), &rootbs);
+	if (ret)
+	    return ret;
+
+	/* search up the namespace tree to the root */
+	while (1) {
+	    kern_return_t kr;
+	    mach_port_t parent;
+	    kr = bootstrap_parent(rootbs, &parent);
+
+	    if (kr == KERN_SUCCESS) {
+		if (parent == MACH_PORT_NULL || parent == rootbs)
+		    break;
+	    } else
+		break;
+	    mach_port_deallocate(mach_task_self(), rootbs);
+	    rootbs = parent;
+	}
+
+	ret = bootstrap_look_up_per_user(rootbs, service, targetuid,
+					 sport);
+	mach_port_deallocate(mach_task_self(), rootbs);
+    } else {
+	mach_port_t boot_port;
+
+        ret = task_get_bootstrap_port(mach_task_self(), &boot_port);
+	if (ret)
+	    return ret;
+	ret = bootstrap_look_up (boot_port, service, sport);
+	mach_port_deallocate(mach_task_self(), boot_port);
+    }
+
+    return ret;
+}
+
 #pragma mark -
 
 /* ------------------------------------------------------------------------ */
@@ -195,6 +296,8 @@
     boolean_t found_entry = 0;
     int i;
     
+    in_launch_if_necessary = 1;
+
     if (!in_service_id   ) { err = EINVAL; }
     if (!out_service_port) { err = EINVAL; }
     
@@ -214,12 +317,8 @@
     }
     
     if (!err && (!MACH_PORT_VALID (k5_service_port) || !in_use_cached_port)) {
-        mach_port_t boot_port = MACH_PORT_NULL;
         char *service = NULL;
         
-        /* Get our bootstrap port */
-        err = task_get_bootstrap_port (mach_task_self (), &boot_port);
-        
         if (!err && !in_launch_if_necessary) {
             char *lookup = NULL;
             mach_port_t lookup_port = MACH_PORT_NULL;
@@ -228,13 +327,13 @@
                               in_service_id, K5_MIG_LOOKUP_SUFFIX);
             if (w < 0) { err = ENOMEM; }
             
+	    /* Use the lookup name because the service name will return 
+	     * a valid port even if the server isn't running */
             if (!err) {
-                /* Use the lookup name because the service name will return 
-                 * a valid port even if the server isn't running */
-                err = bootstrap_look_up (boot_port, lookup, &lookup_port);
+		err = get_service_port (lookup, &lookup_port);
+		free (lookup);
             }
             
-            free (lookup);
             if (MACH_PORT_VALID (lookup_port)) { 
                 mach_port_deallocate (mach_task_self (), lookup_port); 
             }
@@ -247,7 +346,8 @@
         }
         
         if (!err) {
-            err = bootstrap_look_up (boot_port, service, &k5_service_port);
+	    err = get_service_port (service, &k5_service_port);
+	    free (service);
             
             if (!err && found_entry) {
                 /* Free old port if it is valid */
@@ -259,10 +359,6 @@
                 g_service_ports[i].service_port = k5_service_port;
             }
         }
-        
-        free (service);
-        if (MACH_PORT_VALID (boot_port)) { mach_port_deallocate (mach_task_self (), 
-                                                                 boot_port); }
     }
     
     if (!err) {
@@ -422,19 +518,22 @@
     }
     
     if (!err) {
-        err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, 
-                                           TRUE, &server_port);
-    }
-
-    if (!err) {
         err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, 
                                   &reply_port);
     }
     
     while (!err && !done) {
         if (!err && !MACH_PORT_VALID (connection->port)) {
-            err = k5_ipc_client_create_client_connection (server_port, 
-                                                          &connection->port);
+	    err = k5_ipc_client_lookup_server (in_service_id, in_launch_server, 
+					       try_count == 0 ? TRUE : FALSE,
+					       &server_port);
+	    if (err)
+		continue;
+
+	    err = k5_ipc_client_create_client_connection(server_port, 
+							 &connection->port);
+	    if (err)
+		continue;
         }
         
         if (!err) {
@@ -455,12 +554,7 @@
                                     MACH_PORT_RIGHT_SEND, -1 );
                 connection->port = MACH_PORT_NULL;
             }    
-            
-            /* Look up server name again without using the cached copy */
-            err = k5_ipc_client_lookup_server (in_service_id,  
-                                               in_launch_server, 
-                                               FALSE, &server_port);
-            
+
         } else {
             /* Talked to server, though we may have gotten an error */
             done = 1;
diff -Nur -x '*~' -x '*.orig' -x '*.rej' -x '*.pbxbtree' -x '*.pbxindex' -x lha.mode1v3 -x lha.mode2v3 -x lha.pbxuser -x windows -x .DS_Store Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Sources/util/mac/krb5-ipc.h Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Sources/util/mac/krb5-ipc.h
--- Kerberos.AEP-6.5b2.orig/KerberosFramework/Kerberos5/Sources/util/mac/krb5-ipc.h	1969-12-31 16:00:00.000000000 -0800
+++ Kerberos.AEP-6.5b2/KerberosFramework/Kerberos5/Sources/util/mac/krb5-ipc.h	2008-11-06 20:10:38.000000000 -0800
@@ -0,0 +1,33 @@
+/*
+ * $Header$
+ *
+ * Copyright 2006 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef KRB5_IPC_CLIENT_H
+#define KRB5_IPC_CLIENT_H
+
+void	krb5_ipc_client_set_target_uid(uid_t);
+void	krb5_ipc_client_clear_target(void);
+
+#endif /* KRB5_IPC_CLIENT_H */




More information about the krb5-bugs mailing list