]> git.saurik.com Git - apple/launchd.git/blobdiff - launchd/src/rpc_services.c
launchd-152.tar.gz
[apple/launchd.git] / launchd / src / rpc_services.c
diff --git a/launchd/src/rpc_services.c b/launchd/src/rpc_services.c
deleted file mode 100644 (file)
index 4336258..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990.  All rights reserved.
- *
- * rpc_services.c -- implementation of bootstrap rpc services
- */
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <syslog.h>
-#include <string.h>
-
-#include <bsm/audit.h>
-#include <bsm/libbsm.h>
-
-#include "bootstrap_internal.h"
-#include "lists.h"
-#include "bootstrap.h"
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-#ifndef NULL
-#define        NULL    ((void *)0)
-#endif NULL
-#define bsstatus(servicep) \
-       (((servicep)->isActive) ? BOOTSTRAP_STATUS_ACTIVE : \
-        (((servicep)->server && (servicep)->server->servertype == DEMAND) ? \
-               BOOTSTRAP_STATUS_ON_DEMAND : BOOTSTRAP_STATUS_INACTIVE))
-
-/* extern port_all_t backup_port; */
-
-/*
- * kern_return_t
- * bootstrap_create_server(mach_port_t bootstrap_port,
- *      cmd_t server_cmd,
- *      integer_t server_uid,
- *      boolean_t on_demand,
- *      mach_port_t *server_portp)
- *
- * Returns send rights to server_port of service.  At this point, the
- * server appears active, so nothing will try to launch it.  The server_port
- * can be used to delare services associated with this server by calling
- * bootstrap_create_service() and passing server_port as the bootstrap port.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_NOT_PRIVILEGED, if bootstrap port invalid.
- */
-__private_extern__ kern_return_t
-x_bootstrap_create_server(
-       mach_port_t bootstrapport,
-       cmd_t server_cmd,
-       uid_t server_uid,
-       boolean_t on_demand,
-       audit_token_t client_audit_token,
-       mach_port_t *server_portp)
-{
-       server_t *serverp;
-       struct auditinfo audit_info;
-       bootstrap_info_t *bootstrap;
-
-       uid_t client_euid;
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       syslog(LOG_DEBUG, "Server create attempt: \"%s\" bootstrap %x",
-             server_cmd, bootstrapport);
-
-       /* No forwarding allowed for this call - security risk (we run as root) */
-       if (!bootstrap || !active_bootstrap(bootstrap)) {
-               syslog(LOG_DEBUG, "Server create: \"%s\": invalid bootstrap %x",
-                       server_cmd, bootstrapport);
-               return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-
-       /* get the identity of the requestor and set up audit_info of server */
-       audit_token_to_au32(client_audit_token,
-                           &audit_info.ai_auid,
-                           &client_euid,
-                           NULL /* egid */,
-                           NULL /* ruid */,
-                           NULL /* rgid */,
-                           NULL /* pid */,
-                           &audit_info.ai_asid,
-                           &audit_info.ai_termid);
-
-       if (client_euid != 0 && client_euid != server_uid) {
-               syslog(LOG_NOTICE, "Server create: \"%s\": insufficient privilege for specified uid (euid-%d != requested-%d)",
-                       server_cmd, client_euid, server_uid);
-               return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-
-       serverp = new_server(
-                                       bootstrap,
-                                       server_cmd,
-                                       server_uid,
-                                       (on_demand) ? DEMAND : RESTARTABLE,
-                                       audit_info);
-       setup_server(serverp);
-
-       syslog(LOG_INFO, "New server %x in bootstrap %x: \"%s\"",
-                                       serverp->port, bootstrapport, server_cmd);
-       *server_portp = serverp->port;
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_unprivileged(mach_port_t bootstrapport,
- *                       mach_port_t *unprivportp)
- *
- * Given a bootstrap port, return its unprivileged equivalent.  If
- * the port is already unprivileged, another reference to the same
- * port is returned.
- *
- * This is most often used by servers, which are launched with their
- * bootstrap port set to the privileged port for the server, to get
- * an unprivileged version of the same port for use by its unprivileged
- * children (or any offspring that it does not want to count as part
- * of the "server" for mach_init registration and re-launch purposes).
- */
-__private_extern__ kern_return_t
-x_bootstrap_unprivileged(
-       mach_port_t bootstrapport,
-       mach_port_t *unprivportp)
-{
-       bootstrap_info_t *bootstrap;
-
-       syslog(LOG_DEBUG, "Get unprivileged attempt for bootstrap %x", bootstrapport);
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       if (!bootstrap) {
-               syslog(LOG_DEBUG, "Get unprivileged: invalid bootstrap %x", bootstrapport);
-               return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-
-       *unprivportp = bootstrap->bootstrap_port;
-
-       syslog(LOG_DEBUG, "Get unpriv bootstrap %x returned for bootstrap %x",
-              bootstrap->bootstrap_port, bootstrapport);
-       return BOOTSTRAP_SUCCESS;
-}
-
-  
-/*
- * kern_return_t
- * bootstrap_check_in(mach_port_t bootstrapport,
- *      name_t servicename,
- *      mach_port_t *serviceportp)
- *
- * Returns receive rights to service_port of service named by service_name.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- *             Returns BOOTSTRAP_SERVICE_NOT_DECLARED, if service not declared
- *                     in /etc/bootstrap.conf.
- *             Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
- *                     registered or checked-in.
- */
-__private_extern__ kern_return_t
-x_bootstrap_check_in(
-       mach_port_t     bootstrapport,
-       name_t          servicename,
-       mach_port_t     *serviceportp)
-{
-       kern_return_t result;
-       mach_port_t previous;
-       service_t *servicep;
-       server_t *serverp;
-       bootstrap_info_t *bootstrap;
-
-       serverp = lookup_server_by_port(bootstrapport);
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       syslog(LOG_DEBUG, "Service checkin attempt for service %s bootstrap %x",
-             servicename, bootstrapport);
-
-       servicep = lookup_service_by_name(bootstrap, servicename);
-       if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
-               syslog(LOG_DEBUG, "bootstrap_check_in service %s unknown%s", servicename,
-                       forward_ok ? " forwarding" : "");
-               return  forward_ok ?
-                       bootstrap_check_in(
-                                       inherited_bootstrap_port,
-                                       servicename,
-                                       serviceportp) :
-                       BOOTSTRAP_UNKNOWN_SERVICE;
-       }
-       if (servicep->server != NULL && servicep->server != serverp) {
-               syslog(LOG_DEBUG, "bootstrap_check_in service %s not privileged",
-                       servicename);
-                return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-       if (!canReceive(servicep->port)) {
-               ASSERT(servicep->isActive);
-               syslog(LOG_DEBUG, "bootstrap_check_in service %s already active",
-                       servicename);
-               return BOOTSTRAP_SERVICE_ACTIVE;
-       }
-       syslog(LOG_DEBUG, "Checkin service %s for bootstrap %x", servicename,
-             bootstrap->bootstrap_port);
-       ASSERT(servicep->isActive == FALSE);
-       servicep->isActive = TRUE;
-
-       if (servicep->server != NULL_SERVER) {
-               /* registered server - service needs backup */
-               serverp->activity++;
-               serverp->active_services++;
-               result = mach_port_request_notification(
-                                       mach_task_self(),
-                                       servicep->port,
-                                       MACH_NOTIFY_PORT_DESTROYED,
-                                       0,
-                                       backup_port,
-                                       MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                                       &previous);
-               if (result != KERN_SUCCESS)
-                       panic("mach_port_request_notification(): %s", mach_error_string(result));
-       } else {
-               /* one time use/created service */
-               servicep->servicetype = REGISTERED;
-               result = mach_port_request_notification(
-                                       mach_task_self(),
-                                       servicep->port,
-                                       MACH_NOTIFY_DEAD_NAME,
-                                       0,
-                                       notify_port,
-                                       MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                                       &previous);
-               if (result != KERN_SUCCESS)
-                       panic("mach_port_request_notification(): %s", mach_error_string(result));
-               else if (previous != MACH_PORT_NULL) {
-                       syslog(LOG_DEBUG, "deallocating old notification port (%x) for checked in service %x",
-                               previous, servicep->port);
-                       result = mach_port_deallocate(
-                                               mach_task_self(),
-                                               previous);
-                       if (result != KERN_SUCCESS)
-                               panic("mach_port_deallocate(): %s", mach_error_string(result));
-               }
-       }
-
-       syslog(LOG_INFO, "Check-in service %x in bootstrap %x: %s",
-             servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
-
-       *serviceportp = servicep->port;
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_register(mach_port_t bootstrapport,
- *     name_t servicename,
- *     mach_port_t serviceport)
- *
- * Registers send rights for the port service_port for the service named by
- * service_name.  Registering a declared service or registering a service for
- * which bootstrap has receive rights via a port backup notification is
- * allowed.
- * The previous service port will be deallocated.  Restarting services wishing
- * to resume service for previous clients must first attempt to checkin to the
- * service.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
- *                     unprivileged bootstrap port.
- *             Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
- *                     register or checked-in.
- */
-__private_extern__ kern_return_t
-x_bootstrap_register(
-       mach_port_t     bootstrapport,
-       name_t  servicename,
-       mach_port_t     serviceport)
-{
-       kern_return_t result;
-       service_t *servicep;
-       server_t *serverp;
-       bootstrap_info_t *bootstrap;
-       mach_port_t old_port;
-
-       syslog(LOG_DEBUG, "Register attempt for service %s port %x",
-             servicename, serviceport);
-
-       /*
-        * Validate the bootstrap.
-        */
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       if (!bootstrap || !active_bootstrap(bootstrap))
-               return BOOTSTRAP_NOT_PRIVILEGED;
-         
-       /*
-        * If this bootstrap port is for a server, or it's an unprivileged
-        * bootstrap can't register the port.
-        */
-       serverp = lookup_server_by_port(bootstrapport);
-       servicep = lookup_service_by_name(bootstrap, servicename);
-       if (servicep && servicep->server && servicep->server != serverp)
-               return BOOTSTRAP_NOT_PRIVILEGED;
-
-       if (servicep == NULL || servicep->bootstrap != bootstrap) {
-               servicep = new_service(bootstrap,
-                                      servicename,
-                                      serviceport,
-                                      ACTIVE,
-                                      REGISTERED,
-                                      NULL_SERVER);
-               syslog(LOG_DEBUG, "Registered new service %s", servicename);
-       } else {
-               if (servicep->isActive) {
-                       syslog(LOG_DEBUG, "Register: service %s already active, port %x",
-                             servicep->name, servicep->port);
-                       ASSERT(!canReceive(servicep->port));
-                       return BOOTSTRAP_SERVICE_ACTIVE;
-               }
-               old_port = servicep->port;
-               if (servicep->servicetype == DECLARED) {
-                       servicep->servicetype = REGISTERED;
-
-                       if (servicep->server) {
-                               ASSERT(servicep->server == serverp);
-                               ASSERT(active_server(serverp));
-                               servicep->server = NULL_SERVER;
-                               serverp->activity++;
-                       }
-
-                       result = mach_port_mod_refs(
-                                       mach_task_self(),
-                                       old_port,
-                                       MACH_PORT_RIGHT_RECEIVE, 
-                                       -1);
-                       if (result != KERN_SUCCESS)
-                               panic("mach_port_mod_refs(): %s", mach_error_string(result));
-               }
-               result = mach_port_deallocate(
-                               mach_task_self(),
-                               old_port);
-               if (result != KERN_SUCCESS)
-                       panic("mach_port_mod_refs(): %s", mach_error_string(result));
-               
-               servicep->port = serviceport;
-               servicep->isActive = TRUE;
-               syslog(LOG_DEBUG, "Re-registered inactive service %x bootstrap %x: %s",
-                       servicep->port, servicep->bootstrap->bootstrap_port, servicename);
-       }
-
-       /* detect the new service port going dead */
-       result = mach_port_request_notification(
-                       mach_task_self(),
-                       serviceport,
-                       MACH_NOTIFY_DEAD_NAME,
-                       0,
-                       notify_port,
-                       MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                       &old_port);
-       if (result != KERN_SUCCESS) {
-               syslog(LOG_DEBUG, "Can't request notification on service %x bootstrap %x: %s",
-                      service_port, servicep->bootstrap->bootstrap_port, "must be dead");
-               delete_service(servicep);
-               return BOOTSTRAP_SUCCESS;
-       } else if (old_port != MACH_PORT_NULL) {
-               syslog(LOG_DEBUG, "deallocating old notification port (%x) for service %x",
-                     old_port, serviceport);
-               result = mach_port_deallocate(
-                               mach_task_self(),
-                               old_port);
-               if (result != KERN_SUCCESS)
-                       panic("mach_port_deallocate(): %s", mach_error_string(result));
-       }
-       syslog(LOG_INFO, "Registered service %x bootstrap %x: %s",
-            servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_look_up(mach_port_t bootstrapport,
- *     name_t servicename,
- *     mach_port_t *serviceportp)
- *
- * Returns send rights for the service port of the service named by
- * service_name in *service_portp.  Service is not guaranteed to be active.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-__private_extern__ kern_return_t
-x_bootstrap_look_up(
-       mach_port_t     bootstrapport,
-       name_t  servicename,
-       mach_port_t     *serviceportp)
-{
-       service_t *servicep;
-       bootstrap_info_t *bootstrap;
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       servicep = lookup_service_by_name(bootstrap, servicename);
-       if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
-               if (forward_ok) {
-                       syslog(LOG_DEBUG, "bootstrap_look_up service %s forwarding",
-                               servicename);
-                       return bootstrap_look_up(inherited_bootstrap_port,
-                                               servicename,
-                                               serviceportp);
-               } else {
-                       syslog(LOG_DEBUG, "bootstrap_look_up service %s unknown",
-                               servicename);
-                       return BOOTSTRAP_UNKNOWN_SERVICE;
-               }
-       }
-       *serviceportp = servicep->port;
-       syslog(LOG_DEBUG, "Lookup returns port %x for service %s", servicep->port, servicep->name);
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_look_up_array(mach_port_t bootstrapport,
- *     name_array_t    servicenames,
- *     int             servicenames_cnt,
- *     mach_port_array_t       *serviceports,
- *     int             *serviceports_cnt,
- *     boolean_t       *allservices_known)
- *
- * Returns port send rights in corresponding entries of the array service_ports
- * for all services named in the array service_names.  Service_ports_cnt is
- * returned and will always equal service_names_cnt (assuming service_names_cnt
- * is greater than or equal to zero).
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_NO_MEMORY, if server couldn't obtain memory
- *                     for response.
- *             Unknown service names have the corresponding service
- *                     port set to MACH_PORT_NULL.
- *             If all services are known, all_services_known is true on
- *                     return,
- *             if any service is unknown, it's false.
- */
-__private_extern__ kern_return_t
-x_bootstrap_look_up_array(
-       mach_port_t     bootstrapport,
-       name_array_t    servicenames,
-       unsigned int    servicenames_cnt,
-       mach_port_array_t       *serviceportsp,
-       unsigned int    *serviceports_cnt,
-       boolean_t       *allservices_known)
-{
-       unsigned int i;
-       static mach_port_t service_ports[BOOTSTRAP_MAX_LOOKUP_COUNT];
-       
-       if (servicenames_cnt > BOOTSTRAP_MAX_LOOKUP_COUNT)
-               return BOOTSTRAP_BAD_COUNT;
-       *serviceports_cnt = servicenames_cnt;
-       *allservices_known = TRUE;
-       for (i = 0; i < servicenames_cnt; i++) {
-               if (   x_bootstrap_look_up(bootstrapport,
-                                         servicenames[i],
-                                         &service_ports[i])
-                   != BOOTSTRAP_SUCCESS)
-               {
-                       *allservices_known = FALSE;
-                       service_ports[i] = MACH_PORT_NULL;
-               }
-       }
-       syslog(LOG_DEBUG, "bootstrap_look_up_array returns %d ports", servicenames_cnt);
-       *serviceportsp = service_ports;
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_parent(mach_port_t bootstrapport,
- *                 mach_port_t *parentport);
- *
- * Given a bootstrap subset port, return the parent bootstrap port.
- * If the specified bootstrap port is already the root subset,
- * MACH_PORT_NULL will be returned.
- *
- * Errors:
- *     Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
- *     with an effective user id of root (as determined by the security
- *     token in the message trailer).
- */
-__private_extern__ kern_return_t
-x_bootstrap_parent(
-       mach_port_t bootstrapport,
-       security_token_t sectoken,
-       mach_port_t *parentport)
-{
-       bootstrap_info_t *bootstrap;
-
-       syslog(LOG_DEBUG, "Parent attempt for bootstrap %x", bootstrapport);
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       if (!bootstrap) { 
-               syslog(LOG_DEBUG, "Parent attempt for bootstrap %x: invalid bootstrap",
-                     bootstrapport);
-               return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-       if (sectoken.val[0]) {
-               syslog(LOG_NOTICE, "Bootstrap parent for bootstrap %x: invalid security token (%d)",
-                      bootstrapport, sectoken.val[0]);
-               return BOOTSTRAP_NOT_PRIVILEGED;
-       }
-       syslog(LOG_DEBUG, "Returning bootstrap parent %x for bootstrap %x",
-             bootstrap->parent->bootstrap_port, bootstrapport);
-       *parentport = bootstrap->parent->bootstrap_port;
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_status(mach_port_t bootstrapport,
- *     name_t servicename,
- *     bootstrap_status_t *serviceactive);
- *
- * Returns: service_active indicates if service is available.
- *                     
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
- */
-__private_extern__ kern_return_t
-x_bootstrap_status(
-       mach_port_t             bootstrapport,
-       name_t                  servicename,
-       bootstrap_status_t      *serviceactivep)
-{
-       service_t *servicep;
-       bootstrap_info_t *bootstrap;
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       servicep = lookup_service_by_name(bootstrap, servicename);
-       if (servicep == NULL) {
-               if (forward_ok) {
-                       syslog(LOG_DEBUG, "bootstrap_status forwarding status, server %s",
-                               servicename);
-                       return bootstrap_status(inherited_bootstrap_port,
-                                               servicename,
-                                               serviceactivep);
-               } else {
-                       syslog(LOG_DEBUG, "bootstrap_status service %s unknown",
-                               servicename);
-                       return BOOTSTRAP_UNKNOWN_SERVICE;
-               }
-       }
-       *serviceactivep = bsstatus(servicep);
-
-       syslog(LOG_DEBUG, "bootstrap_status server %s %sactive", servicename,
-               servicep->isActive ? "" : "in");
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_info(mach_port_t bootstrapport,
- *     name_array_t *servicenamesp,
- *     int *servicenames_cnt,
- *     name_array_t *servernamesp,
- *     int *servernames_cnt,
- *     bootstrap_status_array_t *serviceactivesp,
- *     int *serviceactive_cnt);
- *
- * Returns bootstrap status for all known services.
- *                     
- * Errors:     Returns appropriate kernel errors on rpc failure.
- */
-__private_extern__ kern_return_t
-x_bootstrap_info(
-       mach_port_t                     bootstrapport,
-       name_array_t                    *servicenamesp,
-       unsigned int                    *servicenames_cnt,
-       name_array_t                    *servernamesp,
-       unsigned int                    *servernames_cnt,
-       bootstrap_status_array_t        *serviceactivesp,
-       unsigned int                    *serviceactives_cnt)
-{
-       kern_return_t result;
-       unsigned int i, cnt;
-       service_t *servicep;
-       server_t *serverp;
-       bootstrap_info_t *bootstrap;
-       name_array_t service_names;
-       name_array_t server_names;
-       bootstrap_status_array_t service_actives;
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-
-       for (   cnt = i = 0, servicep = services.next
-            ; i < nservices
-            ; servicep = servicep->next, i++)
-       {
-           if (lookup_service_by_name(bootstrap, servicep->name) == servicep)
-           {
-               cnt++;
-           }
-       }
-       result = vm_allocate(mach_task_self(),
-                            (vm_address_t *)&service_names,
-                            cnt * sizeof(service_names[0]),
-                            ANYWHERE);
-       if (result != KERN_SUCCESS)
-               return BOOTSTRAP_NO_MEMORY;
-
-       result = vm_allocate(mach_task_self(),
-                            (vm_address_t *)&server_names,
-                            cnt * sizeof(server_names[0]),
-                            ANYWHERE);
-       if (result != KERN_SUCCESS) {
-               (void)vm_deallocate(mach_task_self(),
-                                   (vm_address_t)service_names,
-                                   cnt * sizeof(service_names[0]));
-               return BOOTSTRAP_NO_MEMORY;
-       }
-       result = vm_allocate(mach_task_self(),
-                            (vm_address_t *)&service_actives,
-                            cnt * sizeof(service_actives[0]),
-                            ANYWHERE);
-       if (result != KERN_SUCCESS) {
-               (void)vm_deallocate(mach_task_self(),
-                                   (vm_address_t)service_names,
-                                   cnt * sizeof(service_names[0]));
-               (void)vm_deallocate(mach_task_self(),
-                                   (vm_address_t)server_names,
-                                   cnt * sizeof(server_names[0]));
-               return BOOTSTRAP_NO_MEMORY;
-       }
-
-       for (  i = 0, servicep = services.next
-            ; i < cnt
-            ; servicep = servicep->next)
-       {
-           if (   lookup_service_by_name(bootstrap, servicep->name)
-               != servicep)
-               continue;
-           strncpy(service_names[i],
-                   servicep->name,
-                   sizeof(service_names[0]));
-           service_names[i][sizeof(service_names[0]) - 1] = '\0';
-           if (servicep->server) {
-                   serverp = servicep->server;
-                   strncpy(server_names[i],
-                           serverp->cmd,
-                           sizeof(server_names[0]));
-                   server_names[i][sizeof(server_names[0]) - 1] = '\0';
-                   syslog(LOG_DEBUG, "bootstrap info service %s server %s %sactive",
-                       servicep->name,
-                       serverp->cmd, servicep->isActive ? "" : "in"); 
-           } else {
-                   server_names[i][0] = '\0';
-                   syslog(LOG_DEBUG, "bootstrap info service %s %sactive",
-                       servicep->name, servicep->isActive ? "" : "in"); 
-           }
-           service_actives[i] = bsstatus(servicep);
-           i++;
-       }
-       *servicenamesp = service_names;
-       *servernamesp = server_names;
-       *serviceactivesp = service_actives;
-       *servicenames_cnt = *servernames_cnt = *serviceactives_cnt = cnt;
-
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_subset(mach_port_t bootstrapport,
- *                 mach_port_t requestorport,
- *                 mach_port_t *subsetport);
- *
- * Returns a new port to use as a bootstrap port.  This port behaves
- * exactly like the previous bootstrap_port, except that ports dynamically
- * registered via bootstrap_register() are available only to users of this
- * specific subset_port.  Lookups on the subset_port will return ports
- * registered with this port specifically, and ports registered with
- * ancestors of this subset_port.  Duplications of services already
- * registered with an ancestor port may be registered with the subset port
- * are allowed.  Services already advertised may then be effectively removed
- * by registering MACH_PORT_NULL for the service.
- * When it is detected that the requestor_port is destroied the subset
- * port and all services advertized by it are destroied as well.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- */
-__private_extern__ kern_return_t
-x_bootstrap_subset(
-       mach_port_t     bootstrapport,
-       mach_port_t     requestorport,
-       mach_port_t     *subsetportp)
-{
-       kern_return_t result;
-       bootstrap_info_t *bootstrap;
-       bootstrap_info_t *subset;
-       mach_port_t new_bootstrapport;
-       mach_port_t previous;
-
-       syslog(LOG_DEBUG, "Subset create attempt: bootstrap %x, requestor: %x",
-             bootstrapport, requestorport);
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       if (!bootstrap || !active_bootstrap(bootstrap))
-               return BOOTSTRAP_NOT_PRIVILEGED;
-
-       result = mach_port_allocate(
-                               mach_task_self(), 
-                               MACH_PORT_RIGHT_RECEIVE,
-                               &new_bootstrapport);
-       if (result != KERN_SUCCESS)
-               panic("mach_port_allocate(): %s", mach_error_string(result));
-
-       result = mach_port_insert_right(
-                               mach_task_self(),
-                               new_bootstrapport,
-                               new_bootstrapport,
-                               MACH_MSG_TYPE_MAKE_SEND);
-       if (result != KERN_SUCCESS)
-               panic("failed to insert send right(): %s", mach_error_string(result));
-
-       result = mach_port_insert_member(
-                               mach_task_self(),
-                               new_bootstrapport,
-                               bootstrap_port_set);
-       if (result != KERN_SUCCESS)
-               panic("port_set_add(): %s", mach_error_string(result));
-
-       subset = new_bootstrap(bootstrap, new_bootstrapport, requestorport);
-
-       result = mach_port_request_notification(
-                               mach_task_self(),
-                               requestorport,
-                               MACH_NOTIFY_DEAD_NAME,
-                               0,
-                               notify_port,
-                               MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                               &previous); 
-       if (result != KERN_SUCCESS) {
-               syslog(LOG_ERR, "mach_port_request_notification(): %s", mach_error_string(result));
-               mach_port_deallocate(mach_task_self(), requestorport);
-               subset->requestor_port = MACH_PORT_NULL;
-               deactivate_bootstrap(subset);
-       } else if (previous != MACH_PORT_NULL) {
-               syslog(LOG_DEBUG, "deallocating old notification port (%x) for requestor %x",
-                         previous, requestorport);
-               result = mach_port_deallocate(
-                               mach_task_self(),
-                               previous);
-               if (result != KERN_SUCCESS)
-                       panic("mach_port_deallocate(): %s", mach_error_string(result));
-       }
-
-       syslog(LOG_INFO, "Created bootstrap subset %x parent %x requestor %x", 
-               new_bootstrapport, bootstrapport, requestorport);
-       *subsetportp = new_bootstrapport;
-       return BOOTSTRAP_SUCCESS;
-}
-
-/*
- * kern_return_t
- * bootstrap_create_service(mach_port_t bootstrapport,
- *                   name_t servicename,
- *                   mach_port_t *serviceportp)
- *
- * Creates a service named "service_name" and returns send rights to that
- * port in "service_port."  The port may later be checked in as if this
- * port were configured in the bootstrap configuration file.
- *
- * Errors:     Returns appropriate kernel errors on rpc failure.
- *             Returns BOOTSTRAP_NAME_IN_USE, if service already exists.
- */
-__private_extern__ kern_return_t
-x_bootstrap_create_service(
-       mach_port_t bootstrapport,
-       name_t  servicename,
-       mach_port_t *serviceportp)
-{
-       server_t *serverp;
-       service_t *servicep;
-       bootstrap_info_t *bootstrap;
-       kern_return_t result;
-
-       bootstrap = lookup_bootstrap_by_port(bootstrapport);
-       if (!bootstrap || !active_bootstrap(bootstrap))
-               return BOOTSTRAP_NOT_PRIVILEGED;
-
-       syslog(LOG_DEBUG, "Service creation attempt for service %s bootstrap %x",
-             servicename, bootstrapport);
-
-       servicep = lookup_service_by_name(bootstrap, servicename);
-       if (servicep) {
-               syslog(LOG_DEBUG, "Service creation attempt for service %s failed, "
-                       "service already exists", servicename);
-               return BOOTSTRAP_NAME_IN_USE;
-       }
-
-       serverp = lookup_server_by_port(bootstrapport);
-
-       result = mach_port_allocate(mach_task_self(),
-                                   MACH_PORT_RIGHT_RECEIVE,
-                                   serviceportp);
-       if (result != KERN_SUCCESS)
-               panic("port_allocate(): %s", mach_error_string(result));
-       result = mach_port_insert_right(mach_task_self(),
-                                       *serviceportp, 
-                                       *serviceportp,
-                                       MACH_MSG_TYPE_MAKE_SEND);
-       if (result != KERN_SUCCESS)
-               panic("failed to insert send right(): %s", mach_error_string(result));
-
-       if (serverp)
-               serverp->activity++;
-
-       servicep = new_service(bootstrap,
-                               servicename,
-                               *serviceportp,
-                               !ACTIVE,
-                               DECLARED,
-                               serverp);
-
-       syslog(LOG_INFO, "Created new service %x in bootstrap %x: %s", 
-           servicep->port, bootstrap->bootstrap_port, servicename);
-
-       return BOOTSTRAP_SUCCESS;
-}