xref: /trueos/include/servers/bootstrap.h (revision 0f8eb4123024ffec2f2cfcdb493793aea43f0cac)
1 #ifndef __BOOTSTRAP_H__
2 #define __BOOTSTRAP_H__
3 /*
4  * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
5  *
6  * @APPLE_APACHE_LICENSE_HEADER_START@
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * @APPLE_APACHE_LICENSE_HEADER_END@
21  */
22 
23 /*
24  * bootstrap -- fundamental service initiator and port server
25  * Mike DeMoney, NeXT, Inc.
26  * Copyright, 1990.  All rights reserved.
27  */
28 
29 /*
30  *	Interface:	Bootstrap server
31  *
32  *  The bootstrap server is the first user-mode task initiated by the Mach
33  *  kernel at system boot time.  The bootstrap server provides two services,
34  *  it initiates other system tasks, and manages a table of name-port bindings
35  *  for fundamental system services  (e.g. lookupd, Window Manager, etc...).
36  *
37  *  Name-port bindings can be established with the bootstrap server by either
38  *  of two mechanisms:
39  *
40  *  1.  The binding can be indicated, in advance of the service that backs it
41  *  being available, via a "service create" request.  In this case, bootstrap
42  *  will immediately create a port and bind the indicated name with that port.
43  *  At a later time, a service may "checkin" for the name-port
44  *  binding and will be returned receive rights for the bound port.  Lookup's
45  *  on bindings created by this mechanism will return send rights to the port,
46  *  even if no service has "checked-in".  In this case, requests sent to the
47  *  bound port will be queued until a server has checked-in and can satisfy the
48  *  request.
49  *
50  *  2.  Bindings can be established dynamically via a "register" request.  In
51  *  this case, the register request provides bootstrap with a name and send
52  *  rights for a port.  Bootstrap will provide send rights for the bound port
53  *  to any requestor via the lookup request.
54  *
55  *  Bootstrap provides its service port to descendant tasks via the Mach
56  *  "bootstrap" special task port.  All direct descendants of bootstrap receive
57  *  a "privileged" bootstrap service port.  System services that initiate
58  *  untrusted tasks should replace the Mach bootstrap task special port with
59  *  a subset bootstrap port to prevent them from infecting the namespace.
60  *
61  *  The bootstrap server creates a "backup" port for each service that it
62  *  creates.  This is used to detect when a checked out service is no longer
63  *  being served.  The bootstrap server regains all rights to the port and
64  *  it is marked available for check-out again.  This allows crashed servers to
65  *  resume service to previous clients.  Lookup's on this named port will
66  *  continue to be serviced by bootstrap while holding receive rights for the
67  *  bound port.  A client may detect that the service is inactive via the
68  *  bootstrap status request.  If an inactive service re-registers rather
69  *  than "checking-in" the original bound port is destroyed.
70  *
71  *  The status of a named service may be obtained via the "status" request.
72  *  A service is "active" if a name-port binding exists and receive rights
73  *  to the bound port are held by a task other than bootstrap.
74  *
75  *  The bootstrap server may also (re)start server processes associated with
76  *  with a set of services. The definition of the server process is done
77  *  through the "create server" request.  The server will be launched in the
78  *  same bootstrap context in which it was registered.
79  */
80 #include <AvailabilityMacros.h>
81 #include <mach/std_types.h>
82 #include <mach/message.h>
83 #include <sys/types.h>
84 #include <sys/cdefs.h>
85 #include <stdbool.h>
86 
87 __BEGIN_DECLS
88 
89 #pragma GCC visibility push(default)
90 
91 #define	BOOTSTRAP_MAX_NAME_LEN			128
92 #define	BOOTSTRAP_MAX_CMD_LEN			512
93 
94 typedef char name_t[BOOTSTRAP_MAX_NAME_LEN];
95 typedef char cmd_t[BOOTSTRAP_MAX_CMD_LEN];
96 typedef name_t *name_array_t;
97 typedef int bootstrap_status_t;
98 typedef bootstrap_status_t *bootstrap_status_array_t;
99 typedef unsigned int bootstrap_property_t;
100 typedef bootstrap_property_t * bootstrap_property_array_t;
101 
102 typedef boolean_t *bool_array_t;
103 
104 #define	BOOTSTRAP_MAX_LOOKUP_COUNT		20
105 
106 #define	BOOTSTRAP_SUCCESS				0
107 #define	BOOTSTRAP_NOT_PRIVILEGED		1100
108 #define	BOOTSTRAP_NAME_IN_USE			1101
109 #define	BOOTSTRAP_UNKNOWN_SERVICE		1102
110 #define	BOOTSTRAP_SERVICE_ACTIVE		1103
111 #define	BOOTSTRAP_BAD_COUNT				1104
112 #define	BOOTSTRAP_NO_MEMORY				1105
113 #define BOOTSTRAP_NO_CHILDREN			1106
114 
115 #define BOOTSTRAP_STATUS_INACTIVE		0
116 #define BOOTSTRAP_STATUS_ACTIVE			1
117 #define BOOTSTRAP_STATUS_ON_DEMAND		2
118 
119 /*
120  * After main() starts, it is safe to assume that this variable is always set.
121  */
122 extern mach_port_t bootstrap_port;
123 
124 /*
125  * bootstrap_create_server()
126  *
127  * Declares a server that mach_init will re-spawn within the specified
128  * bootstrap context.  The server is considered already "active"
129  * (i.e. will not be re-spawned) until the returned server_port is
130  * deallocated.
131  *
132  * In the meantime, services can be declared against the server,
133  * by using the server_port as the privileged bootstrap target of
134  * subsequent bootstrap_create_service() calls.
135  *
136  * When mach_init re-spawns the server, its task bootstrap port
137  * is set to the privileged sever_port.  Through this special
138  * bootstrap port, it can access all of parent bootstrap's context
139  * (and all services are created in the parent's namespace). But
140  * all additional service declarations (and declaration removals)
141  * will be associated with this particular server.
142  *
143  * Only a holder of the server_port privilege bootstrap port can
144  * check in or register over those services.
145  *
146  * When all services associated with a server are deleted, and the server
147  * exits, it will automatically be deleted itself.
148  *
149  * If the server is declared "on_demand," then a non-running server
150  * will be re-launched on first use of one of the service ports
151  * registered against it.  Otherwise, it will be re-launched
152  * immediately upon exiting (whether any client is actively using
153  * any of the service ports or not).
154  *
155  * Errors:	Returns appropriate kernel errors on rpc failure.
156  *		Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid.
157  */
158 kern_return_t bootstrap_create_server(
159 		mach_port_t bp,
160 		cmd_t server_cmd,
161 		uid_t server_uid,
162 		boolean_t on_demand,
163 		mach_port_t *server_port);
164 
165 /*
166  * bootstrap_subset()
167  *
168  * Returns a new port to use as a bootstrap port.  This port behaves
169  * exactly like the previous bootstrap_port, except that ports dynamically
170  * registered via bootstrap_register() are available only to users of this
171  * specific subset_port.  Lookups on the subset_port will return ports
172  * registered with this port specifically, and ports registered with
173  * ancestors of this subset_port.  Duplications of services already
174  * registered with an ancestor port may be registered with the subset port
175  * are allowed.  Services already advertised may then be effectively removed
176  * by registering PORT_NULL for the service.
177  * When it is detected that the requestor_port is destroyed the subset
178  * port and all services advertized by it are destroyed as well.
179  *
180  * Errors:	Returns appropriate kernel errors on rpc failure.
181  */
182 kern_return_t bootstrap_subset(
183 		mach_port_t bp,
184 		mach_port_t requestor_port,
185 		mach_port_t *subset_port);
186 
187 /*
188  * bootstrap_unprivileged()
189  *
190  * Given a bootstrap port, return its unprivileged equivalent.  If
191  * the port is already unprivileged, another reference to the same
192  * port is returned.
193  *
194  * This is most often used by servers, which are launched with their
195  * bootstrap port set to the privileged port for the server, to get
196  * an unprivileged version of the same port for use by its unprivileged
197  * children (or any offspring that it does not want to count as part
198  * of the "server" for mach_init registration and re-launch purposes).
199  *
200  * Native launchd jobs are always started with an unprivileged port.
201  */
202 kern_return_t bootstrap_unprivileged(
203 		mach_port_t bp,
204 		mach_port_t *unpriv_port)
205 		AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5;
206 
207 /*
208  * bootstrap_parent()
209  *
210  * Given a bootstrap subset port, return the parent bootstrap port.
211  * If the specified bootstrap port is already the root subset,
212  * the same port will be returned. Much like "." and ".." are the same
213  * in the file system name space for the root directory ("/").
214  *
215  * Errors:
216  *	Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
217  *	with an effective user id of root (as determined by the security
218  *	token in the message trailer).
219  */
220 kern_return_t bootstrap_parent(
221 		mach_port_t bp,
222 		mach_port_t *parent_port);
223 
224 /*
225  * bootstrap_register()
226  *
227  * Registers a send right for service_port with the service identified by
228  * service_name.  Attempts to register a service where an active binding
229  * already exists are rejected.
230  *
231  * If the service was previously declared with bootstrap_create_service(),
232  * but is not currently active, this call can be used to undeclare the
233  * service. The bootstrap port used must have sufficient privilege to
234  * do so.  (Registering MACH_PORT_NULL is especially useful for shutting
235  * down declared services).
236  *
237  * This API is deprecated. Old scenarios and recommendations:
238  *
239  * 1) Code that used to call bootstrap_check_in() and then bootstrap_register()
240  *    can now always call bootstrap_check_in().
241  *
242  * 2) If the code was registering a well known name, please switch to launchd.
243  *
244  * 3) If the code was registering a dynamically generated string and passing
245  *    the string to other applications, please rewrite the code to send a Mach
246  *    send-right directly.
247  *
248  * 4) If the launchd job maintained an optional Mach service, please reserve
249  *    the name with launchd and control the presense of the service through
250  *    ownership of the Mach receive right like so.
251  *
252  *	<key>MachServices</key>
253  *	<dict>
254  *		<key>com.apple.windowserver</key>
255  *		<true/>
256  *		<key>com.apple.windowserver.active</key>
257  *		<dict>
258  *			<key>HideUntilCheckIn</key>
259  *			<true/>
260  *		</dict>
261  *	</dict>
262  *
263  *
264  * Errors:	Returns appropriate kernel errors on rpc failure.
265  *		Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
266  *			bootstrap port without privilege.
267  *		Returns BOOTSTRAP_NAME_IN_USE, if service has already been
268  *			register or checked-in.
269  */
270 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5
271 kern_return_t
272 bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp);
273 
274 /*
275  * bootstrap_create_service()
276  *
277  * Creates a service named "service_name" and returns a send right to that
278  * port in "service_port."  The port may later be checked in as if this
279  * port were configured in the bootstrap configuration file.
280  *
281  * This API is deprecated. Please call bootstrap_check_in() instead.
282  *
283  * Errors:	Returns appropriate kernel errors on rpc failure.
284  *		Returns BOOTSTRAP_SERVICE_ACTIVE, if service already exists.
285  */
286 #ifdef AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6
287 AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6
288 #endif
289 kern_return_t
290 bootstrap_create_service(mach_port_t bp, name_t service_name, mach_port_t *sp);
291 
292 /*
293  * bootstrap_check_in()
294  *
295  * Returns the receive right for the service named by service_name. The
296  * service must have been declared in the launchd.plist(5) file associated
297  * with the job.  Attempts to check_in a service which is already active
298  * are not allowed.
299  *
300  * If the service was declared as being associated with a server, the
301  * check_in must come from the server's privileged port (server_port).
302  *
303  * Errors:	Returns appropriate kernel errors on rpc failure.
304  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
305  *		Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
306  *			bootstrap port without privilege.
307  *		Returns BOOTSTRAP_SERVICE_ACTIVE, if service has already been
308  *			registered or checked-in.
309  */
310 kern_return_t bootstrap_check_in(
311 		mach_port_t bp,
312 		const name_t service_name,
313 		mach_port_t *sp);
314 
315 /*
316  * bootstrap_look_up()
317  *
318  * Returns a send right for the service port declared/registered under the
319  * name service_name. The service is not guaranteed to be active.  Use the
320  * bootstrap_status call to determine the status of the service.
321  *
322  * Errors:	Returns appropriate kernel errors on rpc failure.
323  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
324  */
325 kern_return_t bootstrap_look_up(
326 		mach_port_t bp,
327 		const name_t service_name,
328 		mach_port_t *sp);
329 
330 /*
331  * bootstrap_status()
332  *
333  * In practice, this call was used to preflight whether the following two
334  * APIs would succeed.
335  *
336  * bootstrap_look_up()
337  * bootstrap_check_in()
338  *
339  * Please don't bother. Just call the above two APIs directly and check
340  * for failure.
341  */
342 kern_return_t bootstrap_status(
343 		mach_port_t bp,
344 		name_t service_name,
345 		bootstrap_status_t *service_active)
346 		AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5;
347 
348 /* bootstrap_strerror()
349  *
350  * Translate a return value from the bootstrap_*() APIs to a string.
351  */
352 const char *bootstrap_strerror(kern_return_t r) __attribute__((__nothrow__, __pure__, __warn_unused_result__));
353 
354 #pragma GCC visibility pop
355 
356 __END_DECLS
357 
358 #endif /* __BOOTSTRAP_H__ */
359