summaryrefslogtreecommitdiffstats
path: root/src/util/mac
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2008-09-28 19:43:47 +0000
committerAlexandra Ellwood <lxs@mit.edu>2008-09-28 19:43:47 +0000
commitb5dce4285a9330d25542528030ce93da78e36375 (patch)
treec8cbd6a729cddb99bda84991e1c7c231449434f2 /src/util/mac
parent01a5986cbf7afdba2b805bdd16893b6b52c87f42 (diff)
downloadkrb5-b5dce4285a9330d25542528030ce93da78e36375.tar.gz
krb5-b5dce4285a9330d25542528030ce93da78e36375.tar.xz
krb5-b5dce4285a9330d25542528030ce93da78e36375.zip
Create common stream and ipc layer for CCAPI and KIM.
Will switch CCAPI to this new code later though, so as not to destabilize KfM and the Windows builds. ticket: 6055 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20769 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/util/mac')
-rw-r--r--src/util/mac/k5_mig.defs54
-rw-r--r--src/util/mac/k5_mig_client.c292
-rw-r--r--src/util/mac/k5_mig_client.h36
-rw-r--r--src/util/mac/k5_mig_reply.defs58
-rw-r--r--src/util/mac/k5_mig_request.defs62
-rw-r--r--src/util/mac/k5_mig_server.c233
-rw-r--r--src/util/mac/k5_mig_server.h53
-rw-r--r--src/util/mac/k5_mig_types.h55
8 files changed, 843 insertions, 0 deletions
diff --git a/src/util/mac/k5_mig.defs b/src/util/mac/k5_mig.defs
new file mode 100644
index 000000000..6349eb877
--- /dev/null
+++ b/src/util/mac/k5_mig.defs
@@ -0,0 +1,54 @@
+/* $Copyright:
+ *
+ * Copyright 2004-2006 by the 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 MIT 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Individual source code files are copyright MIT, Cygnus Support,
+ * OpenVision, Oracle, Sun Soft, FundsXpress, and others.
+ *
+ * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
+ * and Zephyr are trademarks of the Massachusetts Institute of Technology
+ * (MIT). No commercial use of these trademarks may be made without prior
+ * written permission of MIT.
+ *
+ * "Commercial use" means use of a name in a product or other for-profit
+ * manner. It does NOT prevent a commercial firm from referring to the MIT
+ * trademarks in order to convey information (although in doing so,
+ * recognition of their trademark status should be given).
+ * $
+ */
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+import "k5_mig_types.h";
+
+/* Note the 1024 must be the same as K5_IPC_MAX_MSG_SIZE */
+type k5_ipc_inl_request_t = array [ * : 1024 ] of char;
+type k5_ipc_ool_request_t = array [] of char;
+
+type k5_ipc_inl_reply_t = array [ * : 1024 ] of char;
+type k5_ipc_ool_reply_t = array [] of char;
diff --git a/src/util/mac/k5_mig_client.c b/src/util/mac/k5_mig_client.c
new file mode 100644
index 000000000..5ffe7deb8
--- /dev/null
+++ b/src/util/mac/k5_mig_client.c
@@ -0,0 +1,292 @@
+/*
+ * $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 "k5_mig_client.h"
+
+#include <Kerberos/kipc_client.h>
+#include "k5_mig_request.h"
+#include "k5_mig_replyServer.h"
+#include "k5-thread.h"
+
+MAKE_INIT_FUNCTION(k5_cli_ipc_thread_init);
+MAKE_FINI_FUNCTION(k5_cli_ipc_thread_fini);
+
+/* ------------------------------------------------------------------------ */
+
+static int k5_cli_ipc_thread_init (void)
+{
+ int err = 0;
+
+ err = k5_key_register (K5_KEY_IPC_REQUEST_PORT, free);
+
+ if (!err) {
+ err = k5_key_register (K5_KEY_IPC_REPLY_STREAM, NULL);
+ }
+
+ if (!err) {
+ err = k5_key_register (K5_KEY_IPC_SERVER_DIED, NULL);
+ }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void k5_cli_ipc_thread_fini (void)
+{
+ k5_key_delete (K5_KEY_IPC_REQUEST_PORT);
+ k5_key_delete (K5_KEY_IPC_REPLY_STREAM);
+ k5_key_delete (K5_KEY_IPC_SERVER_DIED);
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+static boolean_t k5_ipc_reply_demux (mach_msg_header_t *request,
+ mach_msg_header_t *reply)
+{
+ boolean_t handled = 0;
+
+ if (CALL_INIT_FUNCTION (k5_cli_ipc_thread_init) != 0) {
+ return 0;
+ }
+
+ if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
+ int32_t *server_died = k5_getspecific (K5_KEY_IPC_SERVER_DIED);
+ if (!server_died) {
+ *server_died = 1;
+ }
+
+ handled = 1; /* server died */
+ }
+
+ if (!handled) {
+ handled = k5_ipc_reply_server (request, reply);
+ }
+
+ return handled;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t k5_ipc_client_reply (mach_port_t in_reply_port,
+ k5_ipc_inl_reply_t in_inl_reply,
+ mach_msg_type_number_t in_inl_replyCnt,
+ k5_ipc_ool_reply_t in_ool_reply,
+ mach_msg_type_number_t in_ool_replyCnt)
+{
+ kern_return_t err = KERN_SUCCESS;
+ k5_ipc_stream reply_stream = NULL;
+
+ if (!err) {
+ err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init);
+ }
+
+ if (!err) {
+ reply_stream = k5_getspecific (K5_KEY_IPC_REPLY_STREAM);
+ if (!reply_stream) { err = EINVAL; }
+ }
+
+ if (!err) {
+ if (in_inl_replyCnt) {
+ err = k5_ipc_stream_write (reply_stream, in_inl_reply, in_inl_replyCnt);
+
+ } else if (in_ool_replyCnt) {
+ err = k5_ipc_stream_write (reply_stream, in_ool_reply, in_ool_replyCnt);
+
+ } else {
+ err = EINVAL;
+ }
+ }
+
+ if (in_ool_replyCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_reply, in_ool_replyCnt); }
+
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+int32_t k5_ipc_send_request (int32_t in_launch_server,
+ k5_ipc_stream in_request_stream,
+ k5_ipc_stream *out_reply_stream)
+{
+ int err = 0;
+ int32_t done = 0;
+ int32_t try_count = 0;
+ int32_t server_died = 0;
+ mach_port_t server_port = MACH_PORT_NULL;
+ mach_port_t *request_port = NULL;
+ mach_port_t reply_port = MACH_PORT_NULL;
+ const char *inl_request = NULL; /* char * so we can pass the buffer in directly */
+ mach_msg_type_number_t inl_request_length = 0;
+ k5_ipc_ool_request_t ool_request = NULL;
+ mach_msg_type_number_t ool_request_length = 0;
+ k5_ipc_stream reply_stream = NULL;
+
+ if (!in_request_stream) { err = EINVAL; }
+ if (!out_reply_stream ) { err = EINVAL; }
+
+ if (!err) {
+ err = CALL_INIT_FUNCTION (k5_cli_ipc_thread_init);
+ }
+
+ if (!err) {
+ /* depending on how big the message is, use the fast inline buffer or
+ * the slow dynamically allocated buffer */
+ mach_msg_type_number_t request_length = k5_ipc_stream_size (in_request_stream);
+
+ if (request_length > K5_IPC_MAX_MSG_SIZE) {
+ //dprintf ("%s choosing out of line buffer (size is %d)",
+ // __FUNCTION__, request_length);
+
+ err = vm_read (mach_task_self (),
+ (vm_address_t) k5_ipc_stream_data (in_request_stream), request_length,
+ (vm_address_t *) &ool_request, &ool_request_length);
+ } else {
+ //dprintf ("%s choosing in line buffer (size is %d)",
+ // __FUNCTION__, request_length);
+
+ inl_request_length = request_length;
+ inl_request = k5_ipc_stream_data (in_request_stream);
+ }
+ }
+
+ if (!err) {
+ request_port = k5_getspecific (K5_KEY_IPC_REQUEST_PORT);
+
+ if (!request_port) {
+ request_port = malloc (sizeof (mach_port_t));
+ if (!request_port) { err = ENOMEM; }
+
+ if (!err) {
+ *request_port = MACH_PORT_NULL;
+ err = k5_setspecific (K5_KEY_IPC_REQUEST_PORT, request_port);
+ }
+ }
+ }
+
+ if (!err) {
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &reply_port);
+ }
+
+ if (!err) {
+ err = kipc_client_lookup_server (K5_IPC_SERVER_ID,
+ in_launch_server, TRUE, &server_port);
+ }
+
+ while (!err && !done) {
+ if (!err && !MACH_PORT_VALID (*request_port)) {
+ err = k5_ipc_client_create_client_connection (server_port, request_port);
+ }
+
+ if (!err) {
+ err = k5_ipc_client_request (*request_port, reply_port,
+ inl_request, inl_request_length,
+ ool_request, ool_request_length);
+
+ }
+
+ if (err == MACH_SEND_INVALID_DEST) {
+ if (try_count < 2) {
+ try_count++;
+ err = 0;
+ }
+
+ if (request_port && MACH_PORT_VALID (*request_port)) {
+ mach_port_mod_refs (mach_task_self(), *request_port, MACH_PORT_RIGHT_SEND, -1 );
+ *request_port = MACH_PORT_NULL;
+ }
+
+ /* Look up server name again without using the cached copy */
+ err = kipc_client_lookup_server (K5_IPC_SERVER_ID,
+ in_launch_server, FALSE, &server_port);
+
+ } else {
+ /* Talked to server, though we may have gotten an error */
+ done = 1;
+
+ /* Because we use ",dealloc" ool_request will be freed by mach.
+ * Don't double free it. */
+ ool_request = NULL;
+ ool_request_length = 0;
+ }
+ }
+
+ if (!err) {
+ err = k5_ipc_stream_new (&reply_stream);
+ }
+
+ if (!err) {
+ err = k5_setspecific (K5_KEY_IPC_REPLY_STREAM, reply_stream);
+ }
+
+ if (!err) {
+ err = k5_setspecific (K5_KEY_IPC_SERVER_DIED, &server_died);
+ }
+
+ if (!err) {
+ mach_port_t old_notification_target = MACH_PORT_NULL;
+
+ /* request no-senders notification so we can get a message when server dies */
+ err = mach_port_request_notification (mach_task_self (), reply_port,
+ MACH_NOTIFY_NO_SENDERS, 1, reply_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ &old_notification_target);
+
+ if (!err && old_notification_target != MACH_PORT_NULL) {
+ mach_port_deallocate (mach_task_self (), old_notification_target);
+ }
+ }
+
+ if (!err) {
+ err = mach_msg_server_once (k5_ipc_reply_demux, kkipc_max_message_size,
+ reply_port, MACH_MSG_TIMEOUT_NONE);
+ }
+
+ if (!err && server_died) {
+ err = ENOTCONN;
+ }
+
+ if (err == BOOTSTRAP_UNKNOWN_SERVICE && !in_launch_server) {
+ err = 0; /* If the server is not running just return an empty stream. */
+ }
+
+ if (!err) {
+ *out_reply_stream = reply_stream;
+ reply_stream = NULL;
+ }
+
+ k5_setspecific (K5_KEY_IPC_REPLY_STREAM, NULL);
+ k5_setspecific (K5_KEY_IPC_SERVER_DIED, NULL);
+ if (reply_port != MACH_PORT_NULL) { mach_port_destroy (mach_task_self (), reply_port); }
+ if (ool_request_length ) { vm_deallocate (mach_task_self (), (vm_address_t) ool_request, ool_request_length); }
+ if (reply_stream ) { k5_ipc_stream_release (reply_stream); }
+
+ return err;
+}
diff --git a/src/util/mac/k5_mig_client.h b/src/util/mac/k5_mig_client.h
new file mode 100644
index 000000000..b5eefdc3a
--- /dev/null
+++ b/src/util/mac/k5_mig_client.h
@@ -0,0 +1,36 @@
+/*
+ * $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 K5_MIG_CLIENT_H
+#define K5_MIG_CLIENT_H
+
+#include "k5-ipc_stream.h"
+
+int32_t k5_ipc_send_request (int32_t in_launch_server,
+ k5_ipc_stream in_request_stream,
+ k5_ipc_stream *out_reply_stream);
+
+#endif /* K5_MIG_CLIENT_H */
diff --git a/src/util/mac/k5_mig_reply.defs b/src/util/mac/k5_mig_reply.defs
new file mode 100644
index 000000000..301778e15
--- /dev/null
+++ b/src/util/mac/k5_mig_reply.defs
@@ -0,0 +1,58 @@
+/* $Copyright:
+ *
+ * Copyright 2004-2006 by the 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 MIT 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Individual source code files are copyright MIT, Cygnus Support,
+ * OpenVision, Oracle, Sun Soft, FundsXpress, and others.
+ *
+ * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
+ * and Zephyr are trademarks of the Massachusetts Institute of Technology
+ * (MIT). No commercial use of these trademarks may be made without prior
+ * written permission of MIT.
+ *
+ * "Commercial use" means use of a name in a product or other for-profit
+ * manner. It does NOT prevent a commercial firm from referring to the MIT
+ * trademarks in order to convey information (although in doing so,
+ * recognition of their trademark status should be given).
+ * $
+ */
+
+#include "k5_mig.defs"
+
+subsystem k5_ipc_reply 200;
+
+serverprefix k5_ipc_client_;
+userprefix k5_ipc_server_;
+
+/* ",dealloc" means that the vm_read() memory will be moved to
+ * the other process rather than copied. This is necessary on the
+ * client side because we can't know when server has copied our
+ * buffers so we can't vm_deallocate() them ourselves. */
+
+simpleroutine reply (in_reply_port : mach_port_move_send_once_t;
+ in_inl_reply : k5_ipc_inl_reply_t;
+ in_ool_reply : k5_ipc_ool_reply_t, dealloc);
diff --git a/src/util/mac/k5_mig_request.defs b/src/util/mac/k5_mig_request.defs
new file mode 100644
index 000000000..bbb23f0e3
--- /dev/null
+++ b/src/util/mac/k5_mig_request.defs
@@ -0,0 +1,62 @@
+/* $Copyright:
+ *
+ * Copyright 2004-2006 by the 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 MIT 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Individual source code files are copyright MIT, Cygnus Support,
+ * OpenVision, Oracle, Sun Soft, FundsXpress, and others.
+ *
+ * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
+ * and Zephyr are trademarks of the Massachusetts Institute of Technology
+ * (MIT). No commercial use of these trademarks may be made without prior
+ * written permission of MIT.
+ *
+ * "Commercial use" means use of a name in a product or other for-profit
+ * manner. It does NOT prevent a commercial firm from referring to the MIT
+ * trademarks in order to convey information (although in doing so,
+ * recognition of their trademark status should be given).
+ * $
+ */
+
+#include "k5_mig.defs"
+
+subsystem k5_ipc_request 100;
+
+serverprefix k5_ipc_server_;
+userprefix k5_ipc_client_;
+
+routine create_client_connection (in_server_port : mach_port_t;
+ out out_connection_port : mach_port_t = MACH_MSG_TYPE_MAKE_SEND);
+
+/* ",dealloc" means that the vm_read() memory will be moved to
+ * the other process rather than copied. This is necessary on the
+ * server side because we can't know when client has copied our
+ * buffers so we can't vm_deallocate() them ourselves. */
+
+simpleroutine request (in_connection_port : mach_port_t;
+ in_reply_port : mach_port_make_send_once_t;
+ in_inl_request : k5_ipc_inl_request_t;
+ in_ool_request : k5_ipc_ool_request_t, dealloc);
diff --git a/src/util/mac/k5_mig_server.c b/src/util/mac/k5_mig_server.c
new file mode 100644
index 000000000..ddf81ce0b
--- /dev/null
+++ b/src/util/mac/k5_mig_server.c
@@ -0,0 +1,233 @@
+/*
+ * $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 "k5_mig_server.h"
+
+#include <syslog.h>
+#include <Kerberos/kipc_server.h>
+#include "k5_mig_requestServer.h"
+#include "k5_mig_reply.h"
+
+
+/* ------------------------------------------------------------------------ */
+
+static boolean_t k5_ipc_request_demux (mach_msg_header_t *request,
+ mach_msg_header_t *reply)
+{
+ boolean_t handled = false;
+
+ if (!handled) {
+ handled = k5_ipc_request_server (request, reply);
+ }
+
+ if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
+ kern_return_t err = KERN_SUCCESS;
+
+ err = k5_ipc_server_remove_client (request->msgh_local_port);
+
+ if (!err) {
+ /* Check here for a client in our table and free rights associated with it */
+ err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+ }
+
+ if (!err) {
+ handled = 1; /* was a port we are tracking */
+ }
+ }
+
+ return handled;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t k5_ipc_server_create_client_connection (mach_port_t in_server_port,
+ mach_port_t *out_connection_port)
+{
+ kern_return_t err = KERN_SUCCESS;
+ mach_port_t connection_port = MACH_PORT_NULL;
+ mach_port_t old_notification_target = MACH_PORT_NULL;
+
+ if (!err) {
+ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port);
+ }
+
+ if (!err) {
+ err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ());
+ }
+
+ if (!err) {
+ /* request no-senders notification so we can tell when client quits/crashes */
+ err = mach_port_request_notification (mach_task_self (), connection_port,
+ MACH_NOTIFY_NO_SENDERS, 1, connection_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target );
+ }
+
+ if (!err) {
+ err = k5_ipc_server_add_client (connection_port);
+ }
+
+ if (!err) {
+ *out_connection_port = connection_port;
+ connection_port = MACH_PORT_NULL;
+ }
+
+ if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); }
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+kern_return_t k5_ipc_server_request (mach_port_t in_connection_port,
+ mach_port_t in_reply_port,
+ k5_ipc_inl_request_t in_inl_request,
+ mach_msg_type_number_t in_inl_requestCnt,
+ k5_ipc_ool_request_t in_ool_request,
+ mach_msg_type_number_t in_ool_requestCnt)
+{
+ kern_return_t err = KERN_SUCCESS;
+ k5_ipc_stream request_stream = NULL;
+
+ if (!err) {
+ err = k5_ipc_stream_new (&request_stream);
+ }
+
+ if (!err) {
+ if (in_inl_requestCnt) {
+ err = k5_ipc_stream_write (request_stream, in_inl_request, in_inl_requestCnt);
+
+ } else if (in_ool_requestCnt) {
+ err = k5_ipc_stream_write (request_stream, in_ool_request, in_ool_requestCnt);
+
+ } else {
+ err = EINVAL;
+ }
+ }
+
+ if (!err) {
+ err = k5_ipc_server_handle_request (in_connection_port, in_reply_port, request_stream);
+ }
+
+ k5_ipc_stream_release (request_stream);
+ if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); }
+
+ return err;
+}
+
+#pragma mark -
+
+/* ------------------------------------------------------------------------ */
+
+int32_t k5_ipc_server_initialize (int argc, const char *argv[])
+{
+ int32_t err = 0;
+
+ openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH);
+ syslog (LOG_INFO, "Starting up.");
+
+ syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int32_t k5_ipc_server_cleanup (int argc, const char *argv[])
+{
+ int32_t err = 0;
+
+ openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH);
+ syslog (LOG_INFO, "Starting up.");
+
+ syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err);
+
+ return err;
+}
+
+/* ------------------------------------------------------------------------ */
+
+int32_t k5_ipc_server_listen_loop (void)
+{
+ /* Run the Mach IPC listen loop.
+ * This will call k5_ipc_server_create_client_connection for new clients
+ * and k5_ipc_server_request for existing clients */
+
+ return kipc_server_run_server (k5_ipc_request_demux);
+}
+
+/* ------------------------------------------------------------------------ */
+
+int32_t k5_ipc_server_send_reply (mach_port_t in_reply_port,
+ k5_ipc_stream in_reply_stream)
+{
+ kern_return_t err = KERN_SUCCESS;
+ k5_ipc_inl_reply_t inl_reply;
+ mach_msg_type_number_t inl_reply_length = 0;
+ k5_ipc_ool_reply_t ool_reply = NULL;
+ mach_msg_type_number_t ool_reply_length = 0;
+
+ if (!MACH_PORT_VALID (in_reply_port)) { err = EINVAL; }
+ if (!in_reply_stream ) { err = EINVAL; }
+
+ if (!err) {
+ /* depending on how big the message is, use the fast inline buffer or
+ * the slow dynamically allocated buffer */
+ mach_msg_type_number_t reply_length = k5_ipc_stream_size (in_reply_stream);
+
+ if (reply_length > K5_IPC_MAX_MSG_SIZE) {
+ //dprintf ("%s choosing out of line buffer (size is %d)",
+ // __FUNCTION__, reply_length);
+
+ err = vm_read (mach_task_self (),
+ (vm_address_t) k5_ipc_stream_data (in_reply_stream), reply_length,
+ (vm_address_t *) &ool_reply, &ool_reply_length);
+
+ } else {
+ //cci_debug_printf ("%s choosing in line buffer (size is %d)",
+ // __FUNCTION__, reply_length);
+
+ inl_reply_length = reply_length;
+ memcpy (inl_reply, k5_ipc_stream_data (in_reply_stream), reply_length);
+ }
+ }
+
+ if (!err) {
+ err = k5_ipc_server_reply (in_reply_port,
+ inl_reply, inl_reply_length,
+ ool_reply, ool_reply_length);
+ }
+
+ if (!err) {
+ /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */
+ ool_reply = NULL;
+ ool_reply_length = 0;
+ }
+
+ if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); }
+
+ return err;
+}
diff --git a/src/util/mac/k5_mig_server.h b/src/util/mac/k5_mig_server.h
new file mode 100644
index 000000000..c98d1dc4b
--- /dev/null
+++ b/src/util/mac/k5_mig_server.h
@@ -0,0 +1,53 @@
+/*
+ * $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 K5_MIG_SERVER
+#define K5_MIG_SERVER
+
+#include "k5-ipc_stream.h"
+
+/* Defined by caller */
+
+int32_t k5_ipc_server_add_client (mach_port_t in_client_port);
+
+int32_t k5_ipc_server_remove_client (mach_port_t in_client_port);
+
+int32_t k5_ipc_server_handle_request (mach_port_t in_connection_port,
+ mach_port_t in_reply_port,
+ k5_ipc_stream in_request_stream);
+
+/* Server control functions */
+
+int32_t k5_ipc_server_initialize (int argc, const char *argv[]);
+
+int32_t k5_ipc_server_cleanup (int argc, const char *argv[]);
+
+int32_t k5_ipc_server_listen_loop (void);
+
+int32_t k5_ipc_server_send_reply (mach_port_t in_reply_pipe,
+ k5_ipc_stream in_reply_stream);
+
+#endif /* K5_MIG_SERVER */
diff --git a/src/util/mac/k5_mig_types.h b/src/util/mac/k5_mig_types.h
new file mode 100644
index 000000000..4c8ddb73b
--- /dev/null
+++ b/src/util/mac/k5_mig_types.h
@@ -0,0 +1,55 @@
+/* $Copyright:
+*
+* Copyright 2004-2006 by the 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 MIT 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+*
+* Individual source code files are copyright MIT, Cygnus Support,
+* OpenVision, Oracle, Sun Soft, FundsXpress, and others.
+*
+* Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
+* and Zephyr are trademarks of the Massachusetts Institute of Technology
+* (MIT). No commercial use of these trademarks may be made without prior
+* written permission of MIT.
+*
+* "Commercial use" means use of a name in a product or other for-profit
+* manner. It does NOT prevent a commercial firm from referring to the MIT
+* trademarks in order to convey information (although in doing so,
+* recognition of their trademark status should be given).
+* $
+*/
+
+#ifndef K5_MIG_TYPES_H
+#define K5_MIG_TYPES_H
+
+
+#define K5_IPC_MAX_MSG_SIZE 1024
+
+typedef const char k5_ipc_inl_request_t[K5_IPC_MAX_MSG_SIZE];
+typedef const char *k5_ipc_ool_request_t;
+typedef char k5_ipc_inl_reply_t[K5_IPC_MAX_MSG_SIZE];
+typedef char *k5_ipc_ool_reply_t;
+
+#endif /* K5_MIG_TYPES_H */