/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The bootstrap server is the first user-mode task initiated by the Mach
* kernel at system boot time. The bootstrap server provides two services,
* it initiates other system tasks, and manages a table of name-port bindings
- * for fundamental system services (e.g. the NetMsgServer, and the Unix
- * emulation service).
- *
- * The file /etc/bootstrap.conf is read by bootstrap to determine other system
- * services to initiate at system boot time. The format of this file is
- * described later.
+ * for fundamental system services (e.g. lookupd, Window Manager, etc...).
*
* Name-port bindings can be established with the bootstrap server by either
* of two mechanisms:
*
- * 1. The binding can be indicated in the file /etc/bootstrap.conf. In this
- * case, bootstrap will immediately create a port and bind the indicated name
- * with that port. At a later time, a service may "checkin" for the name-port
+ * 1. The binding can be indicated, in advance of the service that backs it
+ * being available, via a "service create" request. In this case, bootstrap
+ * will immediately create a port and bind the indicated name with that port.
+ * At a later time, a service may "checkin" for the name-port
* binding and will be returned receive rights for the bound port. Lookup's
* on bindings created by this mechanism will return send rights to the port,
* even if no service has "checked-in". In this case, requests sent to the
* it is marked available for check-out again. This allows crashed servers to
* resume service to previous clients. Lookup's on this named port will
* continue to be serviced by bootstrap while holding receive rights for the
- * bound port. A client may detect that the service is inactive via the.
- * bootstrap status request. If the service re-registers rather than
- * "checking-in" the original bound port is destroyed.
+ * bound port. A client may detect that the service is inactive via the
+ * bootstrap status request. If an inactive service re-registers rather
+ * than "checking-in" the original bound port is destroyed.
*
* The status of a named service may be obtained via the "status" request.
* A service is "active" if a name-port binding exists and receive rights
* to the bound port are held by a task other than bootstrap.
*
- * Bootstrap initiates server tasks and creates initial name-port bindings as
- * directed by the configuration file /etc/bootstrap.conf. This file has
- * entries with the following formats:
- *
- * services [ SERVICE_NAME ]+ ;
- *
- * E.g:
- * services OldService=1 SomeService;
- *
- * Creates a port and binds the name "OldService" to it.
- * For compatability, assigns the port via mach_ports_register to
- * slot 1. Also creates a port and binds the name "SomeService".
- *
- * self [ SERVICE_NAME ]+ ;
- *
- * E.g:
- * self BootStrapService;
- *
- * Provides a binding to bootstrap's own service port named
- * "BootStrapService".
- *
- * [restartable] server SERVER_FILE_AND_ARGS [ services ... ] ;
- *
- * E.g:
- * server "/usr/etc/sigserver -i" services UnixSignalService;
- *
- * Initiates the server task "/usr/etc/sigserver" with
- * command-line argument "-i", and also creates a name-port
- * binding for the name UnixSignalService. Checkin requests for
- * UnixSignalService are only accepted via the bootstrap service
- * port passed to/usr/etc/sigserver. If the "restartable" option
- * had been specified, bootstrap will reinitiate the server task
- * if it receives notification that all of the server's service
- * ports have been destroyed or deallocated. The server command
- * may be specified without surrounding quotes if it does not
- * include blanks.
- *
- * init SERVER_FILE_AND_ARGS [ services ... ] ;
- *
- * E.g:
- * init /etc/init services NetMsgService=0 PSWindowService=4;
- *
- * Functions like "server" request above, except process is
- * started as pid 1. Illegal if bootstrap itself was not
- * initiated as pid 1.
- *
- * forward;
- *
- * If present, bootstrap will forward unknown lookup requests to
- * its bootstrap service port (if not PORT_NULL), and forward any
- * reply to the original requester.
- *
- * # Comment string up to end of line.
- *
- * A line terminated comment starts with a sharp sign (#).
- *
- * Lexical notes: Strings are either enclosed in double quotes ("), or must
- * start with a letter or underscore (_) and followed by a string of
- * alphanumerics and underscores; backslash (\) escapes the following
- * character. Strings are limited to a (large) length. Numbers must be
- * decimal. Blanks and newlines may be freely used outside of strings.
+ * The bootstrap server may also (re)start server processes associated with
+ * with a set of services. The definition of the server process is done
+ * through the "create server" request. The server will be launched in the
+ * same bootstrap context in which it was registered.
*/
#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
import <servers/bootstrap_defs.h>;
-type name_t = c_string[128];
-type name_array_t = ^array [] of name_t;
-type bool_array_t = ^array [] of boolean_t;
+type cmd_t = c_string[512];
+type name_t = c_string[128];
+type cmd_array_t = ^array [] of cmd_t;
+type name_array_t = ^array [] of name_t;
+type bootstrap_status_t = integer_t;
+type bootstrap_status_array_t = ^array [] of bootstrap_status_t;
serverprefix x_;
-/* old service_checkin */
-skip;
-/* old service_status */
-skip;
+/*
+ * kern_return_t
+ * bootstrap_create_server(mach_port_t bootstrap_port,
+ * cmd_t server_command,
+ * integer_t server_uid,
+ * boolean_t on_demand,
+ * mach_port_t *server_port)
+ *
+ * Declares a server that mach_init will re-spawn within the specified
+ * bootstrap context. The server is considered already "active"
+ * (i.e. will not be re-spawned) until the returned server_port is
+ * deallocated.
+ *
+ * In the meantime, services can be declared against the server,
+ * by using the server_port as the privileged bootstrap target of
+ * subsequent bootstrap_create_service() calls.
+ *
+ * When mach_init re-spawns the server, its task bootstrap port
+ * is set to the privileged sever_port. Through this special
+ * bootstrap port, it can access all of parent bootstrap's context
+ * (and all services are created in the parent's namespace). But
+ * all additional service declarations (and declaration removals)
+ * will be associated with this particular server.
+ *
+ * Only a holder of the server_port privilege bootstrap port can
+ * check in or register over those services.
+ *
+ * When all services associated with a server are deleted, and the server
+ * exits, it will automatically be deleted itself.
+ *
+ * If the server is declared "on_demand," then a non-running server
+ * will be re-launched on first use of one of the service ports
+ * registered against it. Otherwise, it will be re-launched
+ * immediately upon exiting (whether any client is actively using
+ * any of the service ports or not).
+ *
+ * Errors: Returns appropriate kernel errors on rpc failure.
+ * Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid.
+ */
+routine bootstrap_create_server(
+ bootstrap_port : mach_port_t;
+ server_cmd : cmd_t;
+ server_uid : integer_t;
+ on_demand : boolean_t;
+ ServerAuditToken token : audit_token_t;
+ out server_port : mach_port_make_send_t);
+
+/*
+ * kern_return_t
+ * bootstrap_unprivileged(mach_port_t bootstrap_port,
+ * mach_port_t *unpriv_port)
+ *
+ * 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).
+ */
+routine bootstrap_unprivileged(
+ bootstrap_port : mach_port_t;
+ out unpriv_port : mach_port_t);
/*
* kern_return_t
* bootstrap_check_in(mach_port_t bootstrap_port,
* name_t service_name,
- * port_all_t *service_port)
+ * mach_port_t *service_port)
*
- * Returns all rights to service_port of service named by service_name.
+ * Returns the receive right for the service named by service_name. The
+ * service must have previously been declared in this bootstrap context via
+ * a call to bootstrap_create_service(). Attempts to check_in a service
+ * which is already active are not allowed.
+ *
+ * If the service was declared as being associated with a server, the
+ * check_in must come from the server's privileged port (server_port).
*
* Errors: Returns appropriate kernel errors on rpc failure.
* Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
* name_t service_name,
* mach_port_t service_port)
*
- * Registers send rights for the port service_port for the service named by
- * service_name. Attempts to registering a service where an active binding
- * already exists are rejected. On the otherhand, registering a service where
- * and inactive binding exists (i.e. bootstrap currently holds receive rights
- * for the service port) is allowed; in this case the previous service port
- * will be deallocated. Restarting services wishing to resume service for
- * previous clients must first attempt to checkin to the service in order to
- * recover the previous service port.
+ * Registers a send right for service_port with the service identified by
+ * service_name. Attempts to register a service where an active binding
+ * already exists are rejected.
+ *
+ * If the service was previously declared with bootstrap_create_service(),
+ * but is not currently active, this call can be used to undeclare the
+ * service. The bootstrap port used must have sufficient privilege to
+ * do so. (Registering MACH_PORT_NULL is especially useful for shutting
+ * down declared services).
*
* Errors: Returns appropriate kernel errors on rpc failure.
* Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
* name_t service_name,
* mach_port_t *service_port)
*
- * Returns send rights for the service port of the service named by
- * service_name in service_port. Service is not guaranteed to be active.
+ * Returns a send right for the service port declared/registered under the
+ * name service_name. The service is not guaranteed to be active. Use the
+ * bootstrap_status call to determine the status of the service.
*
* Errors: Returns appropriate kernel errors on rpc failure.
* Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
out service_ports : mach_port_array_t;
out all_services_known: boolean_t);
-/* old bootstrap_get_unpriv_port */
-skip;
+/*
+ * kern_return_t
+ * bootstrap_parent(mach_port_t bootstrap_port,
+ * mach_port_t *parent_port);
+ *
+ * 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).
+ */
+routine bootstrap_parent(
+ bootstrap_port : mach_port_t;
+ ServerSecToken token : security_token_t;
+ out parent_port : mach_port_make_send_t);
/*
* kern_return_t
* bootstrap_status(mach_port_t bootstrap_port,
* name_t service_name,
- * boolean_t *service_active);
+ * bootstrap_status_t *service_active);
*
- * Returns: service_active is true if service is available.
+ * Returns: service_active indicates if service is active, inactive, or
+ * associated with a launch-on-demand server.
*
* Errors: Returns appropriate kernel errors on rpc failure.
* Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
routine bootstrap_status(
bootstrap_port : mach_port_t;
service_name : name_t;
- out service_active : boolean_t);
+ out service_active : bootstrap_status_t);
/*
* kern_return_t
bootstrap_port : mach_port_t;
out service_names : name_array_t, dealloc;
out server_names : name_array_t, dealloc;
- out service_active : bool_array_t, dealloc);
+ out service_active : bootstrap_status_array_t, dealloc);
/*
* kern_return_t
* registered with an ancestor port may be registered with the subset port
* are allowed. Services already advertised may then be effectively removed
* by registering PORT_NULL for the service.
- * When it is detected that the requestor_port is destroied the subset
+ * When it is detected that the requestor_port is destroyed the subset
* port and all services advertized by it are destroied as well.
*
* Errors: Returns appropriate kernel errors on rpc failure.
bootstrap_port : mach_port_t;
service_name : name_t;
out service_port : mach_port_t);
+