8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / lib / nwamd / door_if.c
blob6f3c76b478277dcb4209711c83c45412e8d9aa94
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <auth_attr.h>
27 #include <auth_list.h>
28 #include <bsm/adt.h>
29 #include <bsm/adt_event.h>
30 #include <door.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <libnwam_priv.h>
34 #include <libuutil.h>
35 #include <pthread.h>
36 #include <pwd.h>
37 #include <stdlib.h>
38 #include <sys/stat.h>
40 #include <sys/mman.h>
41 #include <syslog.h>
42 #include <unistd.h>
44 #include "conditions.h"
45 #include "events.h"
46 #include "ncp.h"
47 #include "ncu.h"
48 #include "objects.h"
49 #include "util.h"
52 * door_if.c
53 * This file contains functions which implement the command interface to
54 * nwam via the door NWAM_DOOR. Doors provide a LPC mechanism that allows
55 * for threads in one process to cause code to execute in another process.
56 * Doors also provide the ability to pass data and file descriptors. See
57 * libdoor(3LIB) for more information.
59 * This file exports two functions, nwamd_door_initialize() (which sets up
60 * the door) and nwamd_door_fini(), which removes it.
62 * It sets up the static routine nwamd_door_switch() to be called when a client
63 * calls the door (via door_call(3C)). The structure nwam_request_t is
64 * passed as data and contains data to specify the type of action requested
65 * and any data need to meet that request. A table consisting of entries
66 * for each door request, the associated authorization and the function to
67 * process that request is used to handle the various requests.
70 struct nwamd_door_req_entry
72 int ndre_type;
73 char *ndre_auth;
74 nwam_error_t (*ndre_fn)(nwamd_door_arg_t *, ucred_t *, struct passwd *);
77 static nwam_error_t nwamd_door_req_event_register(nwamd_door_arg_t *,
78 ucred_t *, struct passwd *);
79 static nwam_error_t nwamd_door_req_event_unregister(nwamd_door_arg_t *,
80 ucred_t *, struct passwd *);
81 static nwam_error_t nwamd_door_req_wlan_scan(nwamd_door_arg_t *,
82 ucred_t *, struct passwd *);
83 static nwam_error_t nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *,
84 ucred_t *, struct passwd *);
85 static nwam_error_t nwamd_door_req_wlan_select(nwamd_door_arg_t *,
86 ucred_t *, struct passwd *);
87 static nwam_error_t nwamd_door_req_wlan_set_key(nwamd_door_arg_t *,
88 ucred_t *, struct passwd *);
89 static nwam_error_t nwamd_door_req_action(nwamd_door_arg_t *,
90 ucred_t *, struct passwd *);
91 static nwam_error_t nwamd_door_req_state(nwamd_door_arg_t *,
92 ucred_t *, struct passwd *);
93 static nwam_error_t nwamd_door_req_priority_group(nwamd_door_arg_t *,
94 ucred_t *, struct passwd *);
97 * This table defines the set of door commands available, the required
98 * authorizations for each command, and the function that carries out
99 * each command.
101 struct nwamd_door_req_entry door_req_table[] =
104 { NWAM_REQUEST_TYPE_EVENT_REGISTER, AUTOCONF_READ_AUTH,
105 nwamd_door_req_event_register },
106 { NWAM_REQUEST_TYPE_EVENT_UNREGISTER, AUTOCONF_READ_AUTH,
107 nwamd_door_req_event_unregister },
108 { NWAM_REQUEST_TYPE_WLAN_SCAN, AUTOCONF_WLAN_AUTH,
109 nwamd_door_req_wlan_scan },
110 { NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS, AUTOCONF_READ_AUTH,
111 nwamd_door_req_wlan_scan_results },
112 { NWAM_REQUEST_TYPE_WLAN_SELECT, AUTOCONF_WLAN_AUTH,
113 nwamd_door_req_wlan_select },
114 { NWAM_REQUEST_TYPE_WLAN_SET_KEY, AUTOCONF_WLAN_AUTH,
115 nwamd_door_req_wlan_set_key },
116 /* Requires WRITE, SELECT or WLAN auth depending on action */
117 { NWAM_REQUEST_TYPE_ACTION, NULL, nwamd_door_req_action },
118 { NWAM_REQUEST_TYPE_STATE, AUTOCONF_READ_AUTH,
119 nwamd_door_req_state },
120 { NWAM_REQUEST_TYPE_PRIORITY_GROUP, AUTOCONF_READ_AUTH,
121 nwamd_door_req_priority_group },
124 int doorfd = -1;
126 /* ARGSUSED */
127 static nwam_error_t
128 nwamd_door_req_event_register(nwamd_door_arg_t *req, ucred_t *ucr,
129 struct passwd *pwd)
131 nwam_error_t err;
133 err = nwam_event_queue_init
134 (req->nwda_data.nwdad_register_info.nwdad_name);
135 if (err != NWAM_SUCCESS) {
136 nlog(LOG_ERR, "nwamd_door_req_event_register: "
137 "could not register events for %s",
138 req->nwda_data.nwdad_register_info.nwdad_name);
141 return (err);
144 /* ARGSUSED */
145 static nwam_error_t
146 nwamd_door_req_event_unregister(nwamd_door_arg_t *req, ucred_t *ucr,
147 struct passwd *pwd)
149 nwam_event_queue_fini(req->nwda_data.nwdad_register_info.nwdad_name);
151 return (NWAM_SUCCESS);
154 /* ARGSUSED1 */
155 static nwam_error_t
156 nwamd_door_req_wlan_scan(nwamd_door_arg_t *req, ucred_t *ucr,
157 struct passwd *pwd)
159 nlog(LOG_DEBUG,
160 "nwamd_door_req_wlan_scan: processing WLAN scan request: "
161 "link %s", req->nwda_data.nwdad_wlan_info.nwdad_name);
163 return (nwamd_wlan_scan(req->nwda_data.nwdad_wlan_info.nwdad_name));
166 /* ARGSUSED */
167 static nwam_error_t
168 nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *req, ucred_t *ucr,
169 struct passwd *pwd)
171 nwamd_object_t obj;
172 nwamd_ncu_t *ncu;
173 nwamd_link_t *link;
174 uint_t num_wlans;
176 nlog(LOG_DEBUG, "nwamd_door_req_wlan_scan_results: processing WLAN "
177 "scan results request: link %s",
178 req->nwda_data.nwdad_wlan_info.nwdad_name);
180 obj = nwamd_ncu_object_find(NWAM_NCU_TYPE_LINK,
181 req->nwda_data.nwdad_wlan_info.nwdad_name);
182 if (obj == NULL) {
183 nlog(LOG_ERR,
184 "nwamd_door_req_wlan_scan_results: link %s not found",
185 req->nwda_data.nwdad_wlan_info.nwdad_name);
186 return (NWAM_ENTITY_NOT_FOUND);
189 ncu = obj->nwamd_object_data;
190 link = &ncu->ncu_link;
191 num_wlans = link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr_num;
193 if (num_wlans > 0) {
194 (void) memcpy
195 (req->nwda_data.nwdad_wlan_info.nwdad_wlans,
196 link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr,
197 num_wlans * sizeof (nwam_wlan_t));
199 req->nwda_data.nwdad_wlan_info.nwdad_num_wlans = num_wlans;
200 nlog(LOG_DEBUG,
201 "nwamd_door_req_wlan_scan_results: returning %d scan results",
202 num_wlans);
203 nwamd_object_release(obj);
205 return (NWAM_SUCCESS);
208 /* ARGSUSED */
209 static nwam_error_t
210 nwamd_door_req_wlan_select(nwamd_door_arg_t *req, ucred_t *ucr,
211 struct passwd *pwd)
213 nlog(LOG_DEBUG,
214 "nwamd_door_req_wlan_select: processing WLAN selection : "
215 "link %s ESSID %s , BSSID %s",
216 req->nwda_data.nwdad_wlan_info.nwdad_name,
217 req->nwda_data.nwdad_wlan_info.nwdad_essid,
218 req->nwda_data.nwdad_wlan_info.nwdad_bssid);
219 return (nwamd_wlan_select
220 (req->nwda_data.nwdad_wlan_info.nwdad_name,
221 req->nwda_data.nwdad_wlan_info.nwdad_essid,
222 req->nwda_data.nwdad_wlan_info.nwdad_bssid,
223 req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
224 req->nwda_data.nwdad_wlan_info.nwdad_add_to_known_wlans));
227 /* ARGSUSED */
228 static nwam_error_t
229 nwamd_door_req_wlan_set_key(nwamd_door_arg_t *req, ucred_t *ucr,
230 struct passwd *pwd)
232 nlog(LOG_DEBUG,
233 "nwamd_door_req_wlan_set_key: processing WLAN key input : "
234 "link %s ESSID %s BSSID %s",
235 req->nwda_data.nwdad_wlan_info.nwdad_name,
236 req->nwda_data.nwdad_wlan_info.nwdad_essid,
237 req->nwda_data.nwdad_wlan_info.nwdad_bssid);
238 return (nwamd_wlan_set_key
239 (req->nwda_data.nwdad_wlan_info.nwdad_name,
240 req->nwda_data.nwdad_wlan_info.nwdad_essid,
241 req->nwda_data.nwdad_wlan_info.nwdad_bssid,
242 req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
243 req->nwda_data.nwdad_wlan_info.nwdad_keyslot,
244 req->nwda_data.nwdad_wlan_info.nwdad_key));
247 static nwam_error_t
248 nwamd_door_req_action(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
250 char name[NWAM_MAX_NAME_LEN];
251 char parent[NWAM_MAX_NAME_LEN];
252 nwam_action_t action = req->nwda_data.nwdad_object_action.nwdad_action;
253 nwam_object_type_t object_type =
254 req->nwda_data.nwdad_object_action.nwdad_object_type;
255 char *obj_type_str = (char *)nwam_object_type_to_string(object_type);
256 nwam_error_t err;
258 /* Check for name, parent overrun */
259 if (strlcpy(name, req->nwda_data.nwdad_object_action.nwdad_name,
260 sizeof (name)) == NWAM_MAX_NAME_LEN ||
261 strlcpy(parent, req->nwda_data.nwdad_object_action.nwdad_parent,
262 sizeof (parent)) == NWAM_MAX_NAME_LEN)
263 return (NWAM_INVALID_ARG);
266 * Check authorizations against actions.
267 * - ENABLE/DISABLE requires SELECT auth
268 * - ADD/DESTROY/REFRESH on Known WLANs requires WLAN auth
269 * - ADD/DESTROY on other objects requires WRITE auth
270 * - REFRESH on other objects requires either WRITE or SELECT auth
272 if (action == NWAM_ACTION_ENABLE || action == NWAM_ACTION_DISABLE) {
273 if (chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
274 nwam_record_audit_event(ucr,
275 action == NWAM_ACTION_ENABLE ?
276 ADT_nwam_enable : ADT_nwam_disable, name,
277 obj_type_str, ADT_FAILURE, ADT_FAIL_VALUE_AUTH);
278 nlog(LOG_ERR, "nwamd_door_req_action: "
279 "need %s for %s action", AUTOCONF_SELECT_AUTH,
280 nwam_action_to_string(action));
281 return (NWAM_PERMISSION_DENIED);
283 } else if (object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN) {
284 if (chkauthattr(AUTOCONF_WLAN_AUTH, pwd->pw_name) == 0) {
285 nlog(LOG_ERR, "nwamd_door_req_action: "
286 "need %s for %s action on Known WLAN",
287 AUTOCONF_WLAN_AUTH, nwam_action_to_string(action));
288 return (NWAM_PERMISSION_DENIED);
290 } else if (action == NWAM_ACTION_ADD || action == NWAM_ACTION_DESTROY) {
291 if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0) {
292 nlog(LOG_ERR, "nwamd_door_req_action: "
293 "need %s for %s action", AUTOCONF_WRITE_AUTH,
294 nwam_action_to_string(action));
295 return (NWAM_PERMISSION_DENIED);
297 } else if (action == NWAM_ACTION_REFRESH) {
298 if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0 &&
299 chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
300 nlog(LOG_ERR, "nwamd_door_req_action: "
301 "need either %s or %s for %s action",
302 AUTOCONF_WRITE_AUTH, AUTOCONF_SELECT_AUTH,
303 nwam_action_to_string(action));
304 return (NWAM_PERMISSION_DENIED);
306 } else {
307 nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
308 "action %d (%s)", action, nwam_action_to_string(action));
309 return (NWAM_INVALID_ARG);
312 switch (action) {
313 case NWAM_ACTION_ENABLE:
314 case NWAM_ACTION_DISABLE:
315 nwam_record_audit_event(ucr,
316 action == NWAM_ACTION_ENABLE ?
317 ADT_nwam_enable : ADT_nwam_disable, name,
318 obj_type_str, ADT_SUCCESS, ADT_SUCCESS);
320 nlog(LOG_DEBUG, "nwamd_door_req_action: %s %s",
321 action == NWAM_ACTION_ENABLE ? "enabling" : "disabling",
322 name);
324 switch (object_type) {
325 case NWAM_OBJECT_TYPE_ENM:
326 err = nwamd_enm_action(name, action);
327 break;
328 case NWAM_OBJECT_TYPE_LOC:
329 err = nwamd_loc_action(name, action);
330 break;
331 case NWAM_OBJECT_TYPE_NCU:
332 err = nwamd_ncu_action(name, parent, action);
333 break;
334 case NWAM_OBJECT_TYPE_NCP:
335 if (action == NWAM_ACTION_DISABLE) {
336 nlog(LOG_ERR, "nwamd_door_req_action: "
337 "NCPs cannot be disabled");
338 err = NWAM_INVALID_ARG;
339 } else {
340 err = nwamd_ncp_action(name, action);
342 break;
343 default:
344 nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
345 "object type %d (%s)", object_type,
346 nwam_object_type_to_string(object_type));
347 return (NWAM_INVALID_ARG);
349 break;
351 case NWAM_ACTION_ADD:
352 case NWAM_ACTION_REFRESH:
354 * Called whenever an object is committed in the library.
355 * Reread that committed object into nwamd.
357 nlog(LOG_DEBUG, "door_switch: refreshing %s", name);
359 switch (object_type) {
360 case NWAM_OBJECT_TYPE_ENM:
361 err = nwamd_enm_action(name, action);
362 break;
363 case NWAM_OBJECT_TYPE_LOC:
364 err = nwamd_loc_action(name, action);
365 break;
366 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
367 err = nwamd_known_wlan_action(name, action);
368 break;
369 case NWAM_OBJECT_TYPE_NCU:
370 err = nwamd_ncu_action(name, parent, action);
371 break;
372 case NWAM_OBJECT_TYPE_NCP:
373 err = nwamd_ncp_action(name, action);
374 break;
375 default:
376 nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
377 "object type %d (%s)", object_type,
378 nwam_object_type_to_string(object_type));
379 err = NWAM_INVALID_ARG;
380 break;
382 break;
384 case NWAM_ACTION_DESTROY:
385 /* Object was destroyed, remove from nwamd */
386 nlog(LOG_DEBUG, "door_switch: removing %s", name);
388 switch (object_type) {
389 case NWAM_OBJECT_TYPE_ENM:
390 err = nwamd_enm_action(name, NWAM_ACTION_DESTROY);
391 break;
392 case NWAM_OBJECT_TYPE_LOC:
393 err = nwamd_loc_action(name, NWAM_ACTION_DESTROY);
394 break;
395 case NWAM_OBJECT_TYPE_KNOWN_WLAN:
396 err = nwamd_known_wlan_action(name,
397 NWAM_ACTION_DESTROY);
398 break;
399 case NWAM_OBJECT_TYPE_NCU:
400 err = nwamd_ncu_action(name, parent,
401 NWAM_ACTION_DESTROY);
402 break;
403 case NWAM_OBJECT_TYPE_NCP:
404 (void) pthread_mutex_lock(&active_ncp_mutex);
405 if (strcmp(name, active_ncp) == 0) {
406 nlog(LOG_ERR, "nwamd_door_req_action: %s is "
407 "active, cannot destroy", parent);
408 err = NWAM_ENTITY_IN_USE;
409 } else {
410 err = nwamd_ncp_action(name,
411 NWAM_ACTION_DESTROY);
413 (void) pthread_mutex_unlock(&active_ncp_mutex);
414 break;
415 default:
416 nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
417 "object type %d (%s)", object_type,
418 nwam_object_type_to_string(object_type));
419 err = NWAM_INVALID_ARG;
420 break;
422 break;
424 default:
425 nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
426 "action %d (%s)", action, nwam_action_to_string(action));
427 err = NWAM_INVALID_ARG;
428 break;
431 if (err == NWAM_SUCCESS) {
433 * At this point, we've successfully carried out an action.
434 * Configuration may have changed, so we need to recheck
435 * conditions, however we want to avoid a flurry of condition
436 * check events, so we enqueue a triggered condition check
437 * if none is due in the next few seconds.
439 nwamd_create_triggered_condition_check_event(NEXT_FEW_SECONDS);
440 } else {
441 nlog(LOG_ERR, "nwamd_door_req_action: could not carry out "
442 "%s action on %s: %s", nwam_action_to_string(action),
443 name, nwam_strerror(err));
446 return (err);
449 /* ARGSUSED */
450 static nwam_error_t
451 nwamd_door_req_state(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
453 char name[NWAM_MAX_NAME_LEN];
454 nwamd_object_t obj;
455 nwam_object_type_t object_type =
456 req->nwda_data.nwdad_object_state.nwdad_object_type;
457 boolean_t is_active = B_FALSE;
459 /* Check for name, parent overrun */
460 if (strlcpy(name, req->nwda_data.nwdad_object_state.nwdad_name,
461 sizeof (name)) == NWAM_MAX_NAME_LEN)
462 return (NWAM_INVALID_ARG);
464 switch (object_type) {
465 case NWAM_OBJECT_TYPE_NCP:
466 (void) pthread_mutex_lock(&active_ncp_mutex);
467 is_active = (strcmp(active_ncp, name) == 0);
468 (void) pthread_mutex_unlock(&active_ncp_mutex);
469 if (is_active) {
470 req->nwda_data.nwdad_object_state.nwdad_state =
471 NWAM_STATE_ONLINE;
472 req->nwda_data.nwdad_object_state.
473 nwdad_aux_state = NWAM_AUX_STATE_ACTIVE;
474 nlog(LOG_DEBUG,
475 "nwamd_door_req_state: NCP %s is active", name);
476 } else {
477 req->nwda_data.nwdad_object_state.nwdad_state =
478 NWAM_STATE_DISABLED;
479 req->nwda_data.nwdad_object_state.
480 nwdad_aux_state =
481 NWAM_AUX_STATE_MANUAL_DISABLE;
482 nlog(LOG_DEBUG, "nwamd_door_req_state: "
483 "NCP %s is inactive", name);
485 break;
487 case NWAM_OBJECT_TYPE_LOC:
488 case NWAM_OBJECT_TYPE_NCU:
489 case NWAM_OBJECT_TYPE_ENM:
490 obj = nwamd_object_find(object_type, name);
491 if (obj == NULL) {
492 nlog(LOG_ERR, "nwamd_door_req_state: %s %s not found",
493 nwam_object_type_to_string(object_type), name);
494 return (NWAM_ENTITY_NOT_FOUND);
496 nlog(LOG_DEBUG, "nwamd_door_req_state: %s %s is %s",
497 nwam_object_type_to_string(object_type), name,
498 nwam_state_to_string(obj->nwamd_object_state));
499 req->nwda_data.nwdad_object_state.nwdad_state =
500 obj->nwamd_object_state;
501 req->nwda_data.nwdad_object_state.nwdad_aux_state =
502 obj->nwamd_object_aux_state;
503 nwamd_object_release(obj);
504 break;
506 default:
507 nlog(LOG_ERR, "nwamd_door_req_state: received invalid "
508 "object type %d (%s)", object_type,
509 nwam_object_type_to_string(object_type));
510 req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
511 return (NWAM_INVALID_ARG);
514 return (NWAM_SUCCESS);
517 /* ARGSUSED */
518 static nwam_error_t
519 nwamd_door_req_priority_group(nwamd_door_arg_t *req, ucred_t *ucr,
520 struct passwd *pwd)
522 (void) pthread_mutex_lock(&active_ncp_mutex);
523 nlog(LOG_DEBUG, "nwamd_door_req_priority_group: "
524 "retrieving active priority-group: %d",
525 current_ncu_priority_group);
526 req->nwda_data.nwdad_priority_group_info.nwdad_priority =
527 current_ncu_priority_group;
528 (void) pthread_mutex_unlock(&active_ncp_mutex);
530 return (NWAM_SUCCESS);
533 /* ARGSUSED */
534 static void
535 nwamd_door_switch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
536 uint_t n_desc)
538 nwamd_door_arg_t *req;
539 ucred_t *ucr = NULL;
540 uid_t uid;
541 struct passwd *pwd = NULL;
542 boolean_t found = B_FALSE;
543 int i;
545 /* LINTED E_BAD_PTR_CAST_ALIGN */
546 req = (nwamd_door_arg_t *)argp;
547 req->nwda_error = NWAM_SUCCESS;
549 if (door_ucred(&ucr) != 0) {
550 nlog(LOG_ERR, "nwamd_door_switch: door_ucred failed: %s",
551 strerror(errno));
552 req->nwda_error = NWAM_ERROR_INTERNAL;
553 req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
554 goto done;
556 uid = ucred_getruid(ucr);
558 if ((pwd = getpwuid(uid)) == NULL) {
559 nlog(LOG_ERR, "nwamd_door_switch: getpwuid failed: %s",
560 strerror(errno));
561 endpwent();
562 req->nwda_error = NWAM_ERROR_INTERNAL;
563 req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
564 goto done;
568 * Find door request entry in table, check auths and call the function
569 * handling the request.
571 for (i = 0;
572 i < sizeof (door_req_table) / sizeof (struct nwamd_door_req_entry);
573 i++) {
574 if (req->nwda_type != door_req_table[i].ndre_type)
575 continue;
577 found = B_TRUE;
579 if (door_req_table[i].ndre_auth != NULL &&
580 chkauthattr(door_req_table[i].ndre_auth,
581 pwd->pw_name) == 0) {
582 nlog(LOG_ERR,
583 "nwamd_door_switch: need %s for request type %d",
584 door_req_table[i].ndre_auth, req->nwda_type);
585 req->nwda_error = NWAM_PERMISSION_DENIED;
586 break;
588 req->nwda_error = door_req_table[i].ndre_fn(req, ucr, pwd);
589 break;
591 if (!found) {
592 nlog(LOG_ERR,
593 "nwamd_door_switch: received unknown request type %d",
594 req->nwda_type);
595 req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
596 } else {
597 if (req->nwda_error == NWAM_SUCCESS)
598 req->nwda_status = NWAM_REQUEST_STATUS_OK;
599 else
600 req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
603 done:
604 ucred_free(ucr);
605 endpwent();
607 if (door_return((char *)req, sizeof (nwamd_door_arg_t), NULL, 0)
608 == -1) {
609 nlog(LOG_ERR, "door_switch: type %d door_return failed: %s",
610 req->nwda_type, strerror(errno));
615 * We initialize the nwamd door here. Failure to have this happen is critical
616 * to the daemon so we log a message and pass up notice to the caller who
617 * will most likely abort trying to start. This routine is meant to only
618 * be called once.
620 void
621 nwamd_door_init(void)
623 const int door_mode = 0644;
624 struct stat buf;
626 if ((doorfd = door_create(nwamd_door_switch, NULL,
627 DOOR_NO_CANCEL | DOOR_REFUSE_DESC)) == -1)
628 pfail("Unable to create door: %s", strerror(errno));
630 if (stat(NWAM_DOOR, &buf) < 0) {
631 int nwam_door_fd;
633 if ((nwam_door_fd = creat(NWAM_DOOR, door_mode)) < 0) {
634 int err = errno;
635 (void) door_revoke(doorfd);
636 doorfd = -1;
637 pfail("Couldn't create door: %s", strerror(err));
639 (void) close(nwam_door_fd);
640 } else {
641 if (buf.st_mode != door_mode) {
642 if (chmod(NWAM_DOOR, door_mode) == -1) {
643 nlog(LOG_ERR, "couldn't change mode of %s: %s",
644 NWAM_DOOR, strerror(errno));
648 /* cleanup anything hanging around from a previous invocation */
649 (void) fdetach(NWAM_DOOR);
651 /* Place our door in the file system so that others can find us. */
652 if (fattach(doorfd, NWAM_DOOR) < 0) {
653 int err = errno;
654 (void) door_revoke(doorfd);
655 doorfd = -1;
656 pfail("Couldn't attach door: %s", strerror(err));
660 void
661 nwamd_door_fini(void)
663 if (doorfd != -1) {
664 nlog(LOG_DEBUG, "nwamd_door_fini: closing door");
665 (void) door_revoke(doorfd);
666 doorfd = -1;
668 (void) unlink(NWAM_DOOR);