#ifndef __BOOTSTRAP_H__1#define __BOOTSTRAP_H__2/*3* Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.4*5* @APPLE_APACHE_LICENSE_HEADER_START@6*7* Licensed under the Apache License, Version 2.0 (the "License");8* you may not use this file except in compliance with the License.9* You may obtain a copy of the License at10*11* http://www.apache.org/licenses/LICENSE-2.012*13* Unless required by applicable law or agreed to in writing, software14* distributed under the License is distributed on an "AS IS" BASIS,15* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.16* See the License for the specific language governing permissions and17* limitations under the License.18*19* @APPLE_APACHE_LICENSE_HEADER_END@20*/2122/*23* bootstrap -- fundamental service initiator and port server24* Mike DeMoney, NeXT, Inc.25* Copyright, 1990. All rights reserved.26*/2728/*29* Interface: Bootstrap server30*31* The bootstrap server is the first user-mode task initiated by the Mach32* kernel at system boot time. The bootstrap server provides two services,33* it initiates other system tasks, and manages a table of name-port bindings34* for fundamental system services (e.g. lookupd, Window Manager, etc...).35*36* Name-port bindings can be established with the bootstrap server by either37* of two mechanisms:38*39* 1. The binding can be indicated, in advance of the service that backs it40* being available, via a "service create" request. In this case, bootstrap41* will immediately create a port and bind the indicated name with that port.42* At a later time, a service may "checkin" for the name-port43* binding and will be returned receive rights for the bound port. Lookup's44* on bindings created by this mechanism will return send rights to the port,45* even if no service has "checked-in". In this case, requests sent to the46* bound port will be queued until a server has checked-in and can satisfy the47* request.48*49* 2. Bindings can be established dynamically via a "register" request. In50* this case, the register request provides bootstrap with a name and send51* rights for a port. Bootstrap will provide send rights for the bound port52* to any requestor via the lookup request.53*54* Bootstrap provides its service port to descendant tasks via the Mach55* "bootstrap" special task port. All direct descendants of bootstrap receive56* a "privileged" bootstrap service port. System services that initiate57* untrusted tasks should replace the Mach bootstrap task special port with58* a subset bootstrap port to prevent them from infecting the namespace.59*60* The bootstrap server creates a "backup" port for each service that it61* creates. This is used to detect when a checked out service is no longer62* being served. The bootstrap server regains all rights to the port and63* it is marked available for check-out again. This allows crashed servers to64* resume service to previous clients. Lookup's on this named port will65* continue to be serviced by bootstrap while holding receive rights for the66* bound port. A client may detect that the service is inactive via the67* bootstrap status request. If an inactive service re-registers rather68* than "checking-in" the original bound port is destroyed.69*70* The status of a named service may be obtained via the "status" request.71* A service is "active" if a name-port binding exists and receive rights72* to the bound port are held by a task other than bootstrap.73*74* The bootstrap server may also (re)start server processes associated with75* with a set of services. The definition of the server process is done76* through the "create server" request. The server will be launched in the77* same bootstrap context in which it was registered.78*/79#include <AvailabilityMacros.h>80#include <mach/std_types.h>81#include <mach/message.h>82#include <sys/types.h>83#include <sys/cdefs.h>84#include <stdbool.h>8586__BEGIN_DECLS8788#pragma GCC visibility push(default)8990#define BOOTSTRAP_MAX_NAME_LEN 12891#define BOOTSTRAP_MAX_CMD_LEN 5129293typedef char name_t[BOOTSTRAP_MAX_NAME_LEN];94typedef char cmd_t[BOOTSTRAP_MAX_CMD_LEN];95typedef name_t *name_array_t;96typedef int bootstrap_status_t;97typedef bootstrap_status_t *bootstrap_status_array_t;98typedef unsigned int bootstrap_property_t;99typedef bootstrap_property_t * bootstrap_property_array_t;100101typedef boolean_t *bool_array_t;102103#define BOOTSTRAP_MAX_LOOKUP_COUNT 20104105#define BOOTSTRAP_SUCCESS 0106#define BOOTSTRAP_NOT_PRIVILEGED 1100107#define BOOTSTRAP_NAME_IN_USE 1101108#define BOOTSTRAP_UNKNOWN_SERVICE 1102109#define BOOTSTRAP_SERVICE_ACTIVE 1103110#define BOOTSTRAP_BAD_COUNT 1104111#define BOOTSTRAP_NO_MEMORY 1105112#define BOOTSTRAP_NO_CHILDREN 1106113114#define BOOTSTRAP_STATUS_INACTIVE 0115#define BOOTSTRAP_STATUS_ACTIVE 1116#define BOOTSTRAP_STATUS_ON_DEMAND 2117118/*119* After main() starts, it is safe to assume that this variable is always set.120*/121extern mach_port_t bootstrap_port;122123/*124* bootstrap_create_server()125*126* Declares a server that mach_init will re-spawn within the specified127* bootstrap context. The server is considered already "active"128* (i.e. will not be re-spawned) until the returned server_port is129* deallocated.130*131* In the meantime, services can be declared against the server,132* by using the server_port as the privileged bootstrap target of133* subsequent bootstrap_create_service() calls.134*135* When mach_init re-spawns the server, its task bootstrap port136* is set to the privileged sever_port. Through this special137* bootstrap port, it can access all of parent bootstrap's context138* (and all services are created in the parent's namespace). But139* all additional service declarations (and declaration removals)140* will be associated with this particular server.141*142* Only a holder of the server_port privilege bootstrap port can143* check in or register over those services.144*145* When all services associated with a server are deleted, and the server146* exits, it will automatically be deleted itself.147*148* If the server is declared "on_demand," then a non-running server149* will be re-launched on first use of one of the service ports150* registered against it. Otherwise, it will be re-launched151* immediately upon exiting (whether any client is actively using152* any of the service ports or not).153*154* Errors: Returns appropriate kernel errors on rpc failure.155* Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid.156*/157kern_return_t bootstrap_create_server(158mach_port_t bp,159cmd_t server_cmd,160uid_t server_uid,161boolean_t on_demand,162mach_port_t *server_port);163164/*165* bootstrap_subset()166*167* Returns a new port to use as a bootstrap port. This port behaves168* exactly like the previous bootstrap_port, except that ports dynamically169* registered via bootstrap_register() are available only to users of this170* specific subset_port. Lookups on the subset_port will return ports171* registered with this port specifically, and ports registered with172* ancestors of this subset_port. Duplications of services already173* registered with an ancestor port may be registered with the subset port174* are allowed. Services already advertised may then be effectively removed175* by registering PORT_NULL for the service.176* When it is detected that the requestor_port is destroyed the subset177* port and all services advertized by it are destroyed as well.178*179* Errors: Returns appropriate kernel errors on rpc failure.180*/181kern_return_t bootstrap_subset(182mach_port_t bp,183mach_port_t requestor_port,184mach_port_t *subset_port);185186/*187* bootstrap_unprivileged()188*189* Given a bootstrap port, return its unprivileged equivalent. If190* the port is already unprivileged, another reference to the same191* port is returned.192*193* This is most often used by servers, which are launched with their194* bootstrap port set to the privileged port for the server, to get195* an unprivileged version of the same port for use by its unprivileged196* children (or any offspring that it does not want to count as part197* of the "server" for mach_init registration and re-launch purposes).198*199* Native launchd jobs are always started with an unprivileged port.200*/201kern_return_t bootstrap_unprivileged(202mach_port_t bp,203mach_port_t *unpriv_port)204AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5;205206/*207* bootstrap_parent()208*209* Given a bootstrap subset port, return the parent bootstrap port.210* If the specified bootstrap port is already the root subset,211* the same port will be returned. Much like "." and ".." are the same212* in the file system name space for the root directory ("/").213*214* Errors:215* Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running216* with an effective user id of root (as determined by the security217* token in the message trailer).218*/219kern_return_t bootstrap_parent(220mach_port_t bp,221mach_port_t *parent_port);222223/*224* bootstrap_register()225*226* Registers a send right for service_port with the service identified by227* service_name. Attempts to register a service where an active binding228* already exists are rejected.229*230* If the service was previously declared with bootstrap_create_service(),231* but is not currently active, this call can be used to undeclare the232* service. The bootstrap port used must have sufficient privilege to233* do so. (Registering MACH_PORT_NULL is especially useful for shutting234* down declared services).235*236* This API is deprecated. Old scenarios and recommendations:237*238* 1) Code that used to call bootstrap_check_in() and then bootstrap_register()239* can now always call bootstrap_check_in().240*241* 2) If the code was registering a well known name, please switch to launchd.242*243* 3) If the code was registering a dynamically generated string and passing244* the string to other applications, please rewrite the code to send a Mach245* send-right directly.246*247* 4) If the launchd job maintained an optional Mach service, please reserve248* the name with launchd and control the presense of the service through249* ownership of the Mach receive right like so.250*251* <key>MachServices</key>252* <dict>253* <key>com.apple.windowserver</key>254* <true/>255* <key>com.apple.windowserver.active</key>256* <dict>257* <key>HideUntilCheckIn</key>258* <true/>259* </dict>260* </dict>261*262*263* Errors: Returns appropriate kernel errors on rpc failure.264* Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to265* bootstrap port without privilege.266* Returns BOOTSTRAP_NAME_IN_USE, if service has already been267* register or checked-in.268*/269AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5270kern_return_t271bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp);272273/*274* bootstrap_create_service()275*276* Creates a service named "service_name" and returns a send right to that277* port in "service_port." The port may later be checked in as if this278* port were configured in the bootstrap configuration file.279*280* This API is deprecated. Please call bootstrap_check_in() instead.281*282* Errors: Returns appropriate kernel errors on rpc failure.283* Returns BOOTSTRAP_SERVICE_ACTIVE, if service already exists.284*/285#ifdef AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6286AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6287#endif288kern_return_t289bootstrap_create_service(mach_port_t bp, name_t service_name, mach_port_t *sp);290291/*292* bootstrap_check_in()293*294* Returns the receive right for the service named by service_name. The295* service must have been declared in the launchd.plist(5) file associated296* with the job. Attempts to check_in a service which is already active297* are not allowed.298*299* If the service was declared as being associated with a server, the300* check_in must come from the server's privileged port (server_port).301*302* Errors: Returns appropriate kernel errors on rpc failure.303* Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.304* Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to305* bootstrap port without privilege.306* Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been307* registered or checked-in.308*/309kern_return_t bootstrap_check_in(310mach_port_t bp,311const name_t service_name,312mach_port_t *sp);313314/*315* bootstrap_look_up()316*317* Returns a send right for the service port declared/registered under the318* name service_name. The service is not guaranteed to be active. Use the319* bootstrap_status call to determine the status of the service.320*321* Errors: Returns appropriate kernel errors on rpc failure.322* Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.323*/324kern_return_t bootstrap_look_up(325mach_port_t bp,326const name_t service_name,327mach_port_t *sp);328329/*330* bootstrap_status()331*332* In practice, this call was used to preflight whether the following two333* APIs would succeed.334*335* bootstrap_look_up()336* bootstrap_check_in()337*338* Please don't bother. Just call the above two APIs directly and check339* for failure.340*/341kern_return_t bootstrap_status(342mach_port_t bp,343name_t service_name,344bootstrap_status_t *service_active)345AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5;346347/* bootstrap_strerror()348*349* Translate a return value from the bootstrap_*() APIs to a string.350*/351const char *bootstrap_strerror(kern_return_t r) __attribute__((__nothrow__, __pure__, __warn_unused_result__));352353#pragma GCC visibility pop354355__END_DECLS356357#endif /* __BOOTSTRAP_H__ */358359360