summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2006-06-09 22:01:11 +0000
committerAlexandra Ellwood <lxs@mit.edu>2006-06-09 22:01:11 +0000
commit6f294bfe674c557255eca075d2fa2f3064ce4ff5 (patch)
tree8781c38f0e73aa27716706f0b7f4ee0c90f5f372
parent3b5e562ae1fca86bb7396ecb0eaf5a7d3a40acfd (diff)
Temporarily copied KerberosIPC libary from the KfM repository for
testing purposes. Note that this will be removed when the CCAPI branch is merged onto the trunk. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/ccapi@18100 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h47
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h76
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h54
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h59
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/README3
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c86
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c93
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c313
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c141
-rw-r--r--src/lib/ccapi/common/mac/KerberosIPC/notify.defs36
10 files changed, 908 insertions, 0 deletions
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h
new file mode 100644
index 0000000000..89923eb16a
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_client.h
@@ -0,0 +1,47 @@
+/*
+ * kipc_client.h
+ *
+ * $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 KIPC_CLIENT_H
+#define KIPC_CLIENT_H
+
+#include <Kerberos/kipc_common.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+kipc_err_t
+kipc_client_lookup_server (const char *in_service_id,
+ boolean_t in_launch_if_necessary,
+ mach_port_t *out_service_port);
+
+#if __cplusplus
+}
+#endif
+
+#endif /* KIPC_CLIENT_H */
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h
new file mode 100644
index 0000000000..361f7f5764
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_common.h
@@ -0,0 +1,76 @@
+/*
+ * KerberosIPCCommon.h
+ *
+ * $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 KIPC_COMMON_H
+#define KIPC_COMMON_H
+
+//#include <Kerberos/KerberosDebug.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <mach/mach.h>
+#include <mach/boolean.h>
+#include <mach/mach_error.h>
+#include <mach/notify.h>
+#include <servers/bootstrap.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+#if __cplusplus
+extern "C" {
+#endif
+
+typedef kern_return_t kipc_err_t;
+typedef boolean_t kipc_boolean_t;
+typedef char *kipc_string;
+
+#define kkipc_max_message_size 2048 + MAX_TRAILER_SIZE
+#define kkipc_timeout 200
+
+// Debugging API used by library
+kipc_err_t __kipc_err (kipc_err_t inError, const char *function, const char *file, int line);
+#define kipc_err(err) __kipc_err(err, __FUNCTION__, __FILE__, __LINE__)
+
+const char *kipc_error_string (kipc_err_t in_error);
+
+kipc_err_t kipc_get_lookup_name (char **out_lookup_name, const char *in_service_id);
+kipc_err_t kipc_get_service_name (char **out_service_name, const char *in_service_id);
+
+void kipc_free_string (char *io_string);
+
+#if __cplusplus
+}
+#endif
+
+#endif /* KIPC_COMMON_H */
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h
new file mode 100644
index 0000000000..5d97547583
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_server.h
@@ -0,0 +1,54 @@
+/*
+ * kipc_server.h
+ *
+ * $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 KIPC_SERVER_H
+#define KIPC_SERVER_H
+
+#include <Kerberos/kipc_common.h>
+
+#define kKerberosIPCMaxMsgSize 2048 + MAX_TRAILER_SIZE
+#define kKerberosIPCTimeout 200
+
+#if __cplusplus
+extern "C" {
+#endif
+
+typedef kipc_boolean_t (*kipc_demux_proc) (mach_msg_header_t *, mach_msg_header_t *);
+
+
+kipc_err_t kipc_server_run_server (kipc_demux_proc in_demux_proc);
+
+mach_port_t kipc_server_get_service_port ();
+
+kipc_boolean_t kipc_server_quit (void);
+
+#if __cplusplus
+}
+#endif
+
+#endif /* KIPC_SERVER_H */
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h
new file mode 100644
index 0000000000..3f259561e3
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/Kerberos/kipc_session.h
@@ -0,0 +1,59 @@
+/*
+ * kipc_session.h
+ *
+ * $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 KIPC_SESSION_H
+#define KIPC_SESSION_H
+
+#include <Kerberos/kipc_common.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define kkipc_session_has_gui_access 0x00000001
+#define kkipc_session_caller_uses_gui 0x00000002
+#define kkipc_session_has_cli_access 0x00000004
+
+typedef u_int32_t kipc_session_attributes_t;
+
+
+kipc_boolean_t kipc_session_is_root_session (void);
+
+kipc_session_attributes_t kipc_session_get_attributes (void);
+
+kipc_string kipc_get_session_id_string (void);
+
+uid_t kipc_session_get_session_uid (void);
+
+uid_t kipc_session_get_server_uid (void);
+
+#if __cplusplus
+}
+#endif
+
+#endif /* KIPC_SESSION_H */
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/README b/src/lib/ccapi/common/mac/KerberosIPC/README
new file mode 100644
index 0000000000..2e2d70d4db
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/README
@@ -0,0 +1,3 @@
+This is a temporary copy of the KfM KerberosIPC library sources.
+Once this gets merged onto the trunk the KfM build will use the
+KerberosIPC library instead.
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c
new file mode 100644
index 0000000000..2e48c42cd6
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_client.c
@@ -0,0 +1,86 @@
+/*
+ * kipc_client.c
+ *
+ * $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.
+ */
+
+#include <Kerberos/kipc_client.h>
+
+// ---------------------------------------------------------------------------
+
+kipc_err_t
+kipc_client_lookup_server (const char *in_service_id,
+ boolean_t in_launch_if_necessary,
+ mach_port_t *out_service_port)
+{
+ kipc_err_t err = 0;
+ mach_port_t boot_port = MACH_PORT_NULL;
+ char *service_name = NULL;
+
+ if (in_service_id == NULL) { err = kipc_err (EINVAL); }
+ if (out_service_port == NULL) { err = kipc_err (EINVAL); }
+
+ if (!err) {
+ // Get our bootstrap port
+ err = task_get_bootstrap_port (mach_task_self (), &boot_port);
+ }
+
+ if (!err && !in_launch_if_necessary) {
+ char *lookup_name = NULL;
+ mach_port_t lookup_port = MACH_PORT_NULL;
+
+ err = kipc_get_lookup_name (&lookup_name, in_service_id);
+
+ 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_name, &lookup_port);
+ //dprintf ("%s(): bootstrap_look_up('%s'): port is %x (err = %d '%s')",
+ // __FUNCTION__, lookup_name, lookup_port, err, mach_error_string (err));
+ }
+
+ if (lookup_name != NULL ) { kipc_free_string (lookup_name); }
+ if (lookup_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), lookup_port); }
+ }
+
+ if (!err) {
+ err = kipc_get_service_name (&service_name, in_service_id);
+ }
+
+ if (!err) {
+ err = bootstrap_look_up (boot_port, service_name, out_service_port);
+ //dprintf ("%s(): bootstrap_look_up('%s'): port is %x (err = %d '%s')",
+ // __FUNCTION__, service_name, *out_service_port, err, mach_error_string (err));
+ }
+
+ if (service_name != NULL ) { kipc_free_string (service_name); }
+ if (boot_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), boot_port); }
+
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE) {
+ return err; // Avoid spewing to the log file
+ } else {
+ return kipc_err (err);
+ }
+}
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c
new file mode 100644
index 0000000000..438650f2ab
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_common.c
@@ -0,0 +1,93 @@
+/*
+ * kipc_common.c
+ *
+ * $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.
+ */
+
+#include <Kerberos/kipc_common.h>
+#include <Kerberos/kipc_session.h>
+
+
+// ---------------------------------------------------------------------------
+
+kipc_err_t __kipc_err (kipc_err_t in_error, const char *in_function, const char *in_file, int in_line)
+{
+ if (in_error && (ddebuglevel () > 0)) {
+ dprintf ("%s() got %d ('%s') at %s: %d",
+ in_function, in_error, mach_error_string (in_error), in_file, in_line);
+ dprintsession ();
+ //dprintbootstrap (mach_task_self ());
+ }
+ return in_error;
+}
+// ---------------------------------------------------------------------------
+
+
+const char *kipc_error_string (kipc_err_t in_error)
+{
+ return mach_error_string (in_error);
+}
+
+// ---------------------------------------------------------------------------
+
+kipc_err_t kipc_get_service_name (char **out_service_name, const char *in_service_id)
+{
+ kipc_err_t err = 0;
+
+ if (out_service_name == NULL) { err = EINVAL; }
+ if (in_service_id == NULL) { err = EINVAL; }
+
+ if (!err) {
+ int wrote = asprintf (out_service_name, "%s%s", in_service_id, ".ipcService");
+ if (wrote < 0) { err = ENOMEM; }
+ }
+
+ return kipc_err (err);
+}
+
+// ---------------------------------------------------------------------------
+
+kipc_err_t kipc_get_lookup_name (char **out_lookup_name, const char *in_service_id)
+{
+ kipc_err_t err = 0;
+
+ if (out_lookup_name == NULL) { err = EINVAL; }
+ if (in_service_id == NULL) { err = EINVAL; }
+
+ if (!err) {
+ int wrote = asprintf (out_lookup_name, "%s%s", in_service_id, ".ipcLookup");
+ if (wrote < 0) { err = ENOMEM; }
+ }
+
+ return kipc_err (err);
+}
+
+// ---------------------------------------------------------------------------
+
+void kipc_free_string (char *io_string)
+{
+ free (io_string);
+}
+
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c
new file mode 100644
index 0000000000..c7c973beec
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_server.c
@@ -0,0 +1,313 @@
+/*
+ * kipc_server.c
+ *
+ * $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.
+ */
+
+#include <Kerberos/kipc_server.h>
+#include <Kerberos/kipc_session.h>
+#include "notifyServer.h"
+
+// Global variables for servers (used by demux)
+static mach_port_t g_service_port = MACH_PORT_NULL;
+static kipc_boolean_t g_ready_to_quit = FALSE;
+static kipc_demux_proc g_demux_proc = NULL;
+
+#pragma mark -
+
+// ---------------------------------------------------------------------------
+
+mach_port_t
+kipc_server_get_service_port ()
+{
+ return g_service_port;
+}
+
+#pragma mark -
+
+// ---------------------------------------------------------------------------
+
+kipc_boolean_t
+kipc_server_quit (void)
+{
+ // Do not unregister our port because then we won't get automatically launched again.
+ dprintf ("mach_server_quit_self(): quitting...");
+ g_ready_to_quit = true;
+ return g_ready_to_quit;
+}
+
+#pragma mark -
+
+// ---------------------------------------------------------------------------
+
+static kipc_boolean_t
+kipc_server_demux (mach_msg_header_t *request, mach_msg_header_t *reply)
+{
+ if (mach_notify_server (request, reply) != false) {
+ return true;
+ } else {
+ return g_demux_proc (request, reply);
+ }
+ return false;
+}
+
+#pragma mark -
+
+// ---------------------------------------------------------------------------
+
+static kipc_err_t
+kipc_get_server_id (char **out_server_id)
+{
+ kern_return_t err = KERN_SUCCESS;
+ CFBundleRef bundle = NULL;
+ CFStringRef id_string = NULL;
+ CFIndex id_length = 0;
+ char *server_id = NULL;
+
+ if (out_server_id == NULL) { err = kipc_err (EINVAL); }
+
+ if (!err) {
+ bundle = CFBundleGetMainBundle ();
+ if (bundle == NULL) { err = ENOENT; }
+ }
+
+ if (!err) {
+ id_string = CFBundleGetIdentifier (bundle);
+ if (id_string == NULL) { err = ENOMEM; }
+ }
+
+ if (!err) {
+ id_length = CFStringGetMaximumSizeForEncoding (CFStringGetLength (id_string),
+ CFStringGetSystemEncoding ()) + 1;
+ server_id = calloc (id_length, sizeof (char));
+ if (server_id == NULL) { err = errno; }
+ }
+
+ if (!err) {
+ if (!CFStringGetCString (id_string, server_id, id_length, CFStringGetSystemEncoding ())) {
+ err = ENOMEM;
+ }
+ }
+
+ if (!err) {
+ *out_server_id = server_id;
+ server_id = NULL;
+ }
+
+ if (server_id != NULL) { kipc_free_string (server_id); }
+
+ return kipc_err (err);
+}
+
+// ---------------------------------------------------------------------------
+
+kipc_err_t
+kipc_server_run_server (kipc_demux_proc in_demux_proc)
+{
+ kern_return_t err = KERN_SUCCESS;
+ char *server_id = NULL;
+ char *service_name = NULL;
+ char *lookup_name = NULL;
+ mach_port_t boot_port = MACH_PORT_NULL;
+ mach_port_t lookup_port = MACH_PORT_NULL;
+ mach_port_t notify_port = MACH_PORT_NULL;
+ mach_port_t previous_notify_port = MACH_PORT_NULL;
+ mach_port_t listen_port_set = MACH_PORT_NULL;
+
+ if (in_demux_proc == NULL) { err = kipc_err (EINVAL); }
+
+ // Shed root privileges if any
+ if (!err && (geteuid () == 0)) {
+ uid_t new_uid = kipc_session_get_server_uid ();
+ if (setuid (new_uid) < 0) {
+ dprintf ("%s(): setuid(%d) failed (euid is %d)", __FUNCTION__, new_uid, geteuid ());
+ }
+ }
+
+ if (!err) {
+ // Set up the globals so the demux can find them
+ g_demux_proc = in_demux_proc;
+ }
+
+ if (!err) {
+ err = kipc_get_server_id (&server_id);
+ }
+
+ if (!err) {
+ err = kipc_get_service_name (&service_name, server_id);
+ }
+
+ if (!err) {
+ err = kipc_get_lookup_name (&lookup_name, server_id);
+ }
+
+ if (!err) {
+ // Get the bootstrap port
+ err = task_get_bootstrap_port (mach_task_self (), &boot_port);
+ dprintf ("%s(): task_get_bootstrap_port(): port is %x (err = %d '%s')",
+ __FUNCTION__, boot_port, err, mach_error_string (err));
+ }
+
+ if (!err) {
+ // Create the lookup port:
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &lookup_port);
+ }
+
+ if (!err) {
+ err = mach_port_insert_right (mach_task_self (), lookup_port, lookup_port, MACH_MSG_TYPE_MAKE_SEND);
+ }
+
+ if (!err) {
+ // Register the lookup port so others can tell whether or not we are running
+ err = bootstrap_register (boot_port, lookup_name, lookup_port);
+ dprintf ("%s(): bootstrap_register('%s', %x): (err = %d '%s')",
+ __FUNCTION__, lookup_name, lookup_port, err, mach_error_string (err));
+ }
+
+ if (!err) {
+ // We are an on-demand server so our port already exists. Just ask for it.
+ err = bootstrap_check_in (boot_port, (char *) service_name, &g_service_port);
+ dprintf ("%s(): bootstrap_check_in('%s'): port is %d (err = %d '%s')",
+ __FUNCTION__, service_name, g_service_port, err, mach_error_string (err));
+ }
+
+ if (!err) {
+ // Create the notification port:
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &notify_port);
+ }
+
+ if (!err) {
+ // Ask for notification when the server port has no more senders
+ // A send-once right != a send right so our send-once right will not interfere with the notification
+ err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS, true,
+ notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous_notify_port);
+ dprintf ("%s(): requesting notification for no senders of %x returned '%s', err = %d\n",
+ __FUNCTION__, g_service_port, mach_error_string (err), err);
+ }
+
+ if (!err) {
+ // Create the port set that the server will listen on
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, &listen_port_set);
+ }
+
+ if (!err) {
+ // Add the service port to the port set
+ err = mach_port_move_member (mach_task_self (), g_service_port, listen_port_set);
+ }
+
+ if (!err) {
+ // Add the notify port to the port set
+ err = mach_port_move_member (mach_task_self (), notify_port, listen_port_set);
+ }
+
+ if (!err) {
+ dprintf ("%s(): \"%s\": starting up. service port = %x, bootstrap port = %x\n",
+ __FUNCTION__, service_name, g_service_port, boot_port);
+ }
+
+ while (!err && !g_ready_to_quit) {
+ // Handle one message at a time so we can check to see if the server wants to quit
+ err = mach_msg_server_once (kipc_server_demux, kkipc_max_message_size, listen_port_set, MACH_MSG_OPTION_NONE);
+ }
+
+ // Regardless of whether there was an error, unregister ourselves from no senders notifications
+ // so we don't get launched again by the notification message when we quit
+ // A send-once right != a send right so our send-once right will not interfere with the notification
+ if (g_service_port != MACH_PORT_NULL) {
+ err = mach_port_request_notification (mach_task_self (), g_service_port, MACH_NOTIFY_NO_SENDERS,
+ true, MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &previous_notify_port);
+ dprintf ("%s(): removing notification for no senders of %x returned '%s', err = %d\n",
+ __FUNCTION__, previous_notify_port, mach_error_string (err), err);
+ }
+
+ // Clean up the ports and strings
+ if (lookup_port != MACH_PORT_NULL) {
+ kipc_err_t terr = bootstrap_register (boot_port, lookup_name, MACH_PORT_NULL);
+ dprintf ("%s(): bootstrap_register('%s', MACH_PORT_NULL): (err = %d '%s')",
+ __FUNCTION__, lookup_name, terr, mach_error_string (terr));
+ mach_port_deallocate (mach_task_self (), lookup_port);
+ }
+ if (notify_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), notify_port); }
+ if (listen_port_set != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), listen_port_set); }
+ if (boot_port != MACH_PORT_NULL) { mach_port_deallocate (mach_task_self (), boot_port); }
+ if (lookup_name != NULL ) { kipc_free_string (lookup_name); }
+ if (service_name != NULL ) { kipc_free_string (service_name); }
+ if (server_id != NULL ) { kipc_free_string (server_id); }
+
+ return kipc_err (err);
+}
+
+#pragma mark -
+
+// ---------------------------------------------------------------------------
+
+kern_return_t
+do_mach_notify_port_deleted (mach_port_t notify, mach_port_name_t name)
+{
+ dprintf ("Received MACH_NOTIFY_PORT_DELETED... quitting self");
+ kipc_server_quit ();
+ return KERN_SUCCESS;
+}
+
+// ---------------------------------------------------------------------------
+
+kern_return_t
+do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights)
+{
+ dprintf ("Received MACH_NOTIFY_PORT_DESTROYED... quitting self");
+ kipc_server_quit ();
+ return KERN_SUCCESS;
+}
+
+// ---------------------------------------------------------------------------
+
+kern_return_t
+do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount)
+{
+ dprintf ("Received MACH_NOTIFY_NO_SENDERS... quitting self");
+ kipc_server_quit ();
+ return KERN_SUCCESS;
+}
+
+// ---------------------------------------------------------------------------
+
+kern_return_t
+do_mach_notify_send_once (mach_port_t notify)
+{
+ dprintf ("Received MACH_NOTIFY_SEND_ONCE");
+ return KERN_SUCCESS;
+}
+
+// ---------------------------------------------------------------------------
+
+kern_return_t
+do_mach_notify_dead_name (mach_port_t notify, mach_port_name_t name)
+{
+ dprintf ("Received MACH_NOTIFY_DEAD_NAME... quitting self");
+ kipc_server_quit ();
+ return KERN_SUCCESS;
+}
+
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c b/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c
new file mode 100644
index 0000000000..c08e1bc323
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/kipc_session.c
@@ -0,0 +1,141 @@
+/*
+ * kipc_session.c
+ *
+ * $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.
+ */
+
+#include <Security/AuthSession.h>
+#include <pwd.h>
+#include <Kerberos/kipc_session.h>
+
+// ---------------------------------------------------------------------------
+
+kipc_boolean_t kipc_session_is_root_session (void)
+{
+ kipc_err_t err = 0;
+ kipc_boolean_t is_root_session = TRUE; // safer to assume root session
+ SessionAttributeBits sattrs = 0L;
+
+ err = SessionGetInfo (callerSecuritySession, NULL, &sattrs);
+
+ if (!err) {
+ is_root_session = (sattrs & sessionIsRoot);
+ dprintf ("%s(): running in %s session",
+ __FUNCTION__, is_root_session ? "the root" : "a user");
+ } else {
+ dprintf ("%s(): SessionGetInfo() failed with %d", __FUNCTION__, err);
+ }
+
+ return is_root_session;
+}
+
+// ---------------------------------------------------------------------------
+
+kipc_session_attributes_t kipc_session_get_attributes (void)
+{
+ kipc_session_attributes_t attributes = 0L;
+ SessionAttributeBits sattrs = 0L;
+ int fd_stdin = fileno (stdin);
+ int fd_stdout = fileno (stdout);
+ char *fd_stdin_name = ttyname (fd_stdin);
+
+ if ((SessionGetInfo (callerSecuritySession, NULL, &sattrs) == noErr) && (sattrs & sessionHasGraphicAccess)) {
+ dprintf ("%s(): Session has graphic access.", __FUNCTION__);
+ attributes |= kkipc_session_has_gui_access;
+
+ // Check for the HIToolbox (Carbon) or AppKit (Cocoa). If either is loaded, we are a GUI app!
+ CFBundleRef hiToolBoxBundle = CFBundleGetBundleWithIdentifier (CFSTR ("com.apple.HIToolbox"));
+ if (hiToolBoxBundle != NULL && CFBundleIsExecutableLoaded (hiToolBoxBundle)) {
+ dprintf ("%s(): Carbon Toolbox is loaded.", __FUNCTION__);
+ attributes |= kkipc_session_caller_uses_gui;
+ }
+
+ CFBundleRef appKitBundle = CFBundleGetBundleWithIdentifier (CFSTR ("com.apple.AppKit"));
+ if (appKitBundle != NULL && CFBundleIsExecutableLoaded (appKitBundle)) {
+ dprintf ("%s(): AppKit is loaded.", __FUNCTION__);
+ attributes |= kkipc_session_caller_uses_gui;
+ }
+ }
+
+ // Session info isn't reliable for remote sessions.
+ // Check manually for terminal access with file descriptors
+ if (isatty (fd_stdin) && isatty (fd_stdout) && (fd_stdin_name != NULL)) {
+ dprintf ("%s(): Terminal '%s' of type '%s' exists.",
+ __FUNCTION__, fd_stdin_name, getenv ("TERM"));
+ attributes |= kkipc_session_has_cli_access;
+ }
+
+ dprintf ("%s(): Attributes are %x", __FUNCTION__, attributes);
+ return attributes;
+}
+
+// ---------------------------------------------------------------------------
+
+kipc_string kipc_get_session_id_string (void)
+{
+ // Session ID is a 32 bit quanitity, so the longest string is 0xFFFFFFFF
+ static char s_session_name[16];
+ SecuritySessionId id;
+
+ s_session_name[0] = '\0';
+
+ if (SessionGetInfo (callerSecuritySession, &id, NULL) == noErr) {
+ snprintf (s_session_name, sizeof (s_session_name), "0x%lx", id);
+ }
+
+ return s_session_name;
+}
+
+// ---------------------------------------------------------------------------
+
+uid_t kipc_session_get_session_uid (void)
+{
+ // Get the uid of the user that the server will be run and named for.
+ uid_t uid = geteuid ();
+
+ // Avoid root because the client can later go back to the real uid
+ if (uid == 0 /* root */) {
+ dprintf ("%s(): geteuid returned UID %d, trying getuid...\n", __FUNCTION__, uid);
+ uid = getuid ();
+ }
+
+ return uid;
+}
+
+// ---------------------------------------------------------------------------
+
+uid_t kipc_session_get_server_uid (void)
+{
+ uid_t server_uid = 92;
+
+ struct passwd *pw = getpwnam ("securityagent");
+ if (pw != NULL) {
+ server_uid = pw->pw_uid;
+ } else {
+ dprintf ("%s: getpwnam(securityagent) failed, using hardcoded value.", __FUNCTION__);
+ }
+
+ return server_uid;
+}
diff --git a/src/lib/ccapi/common/mac/KerberosIPC/notify.defs b/src/lib/ccapi/common/mac/KerberosIPC/notify.defs
new file mode 100644
index 0000000000..fea03c9d5d
--- /dev/null
+++ b/src/lib/ccapi/common/mac/KerberosIPC/notify.defs
@@ -0,0 +1,36 @@
+/*
+ * mach_notify.defs
+ *
+ * $Header$
+ *
+ * Copyright 2003 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.
+ */
+
+/*
+ * This is totally disgusting.
+ * Rename the demux function so we don't collide with other libraries using this.
+ */
+
+#define notify_server mach_notify_server
+
+#include <mach/notify.defs>