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]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <auth_attr.h>
27 #include <auth_list.h>
29 #include <bsm/adt_event.h>
33 #include <libnwam_priv.h>
44 #include "conditions.h"
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
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
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
},
128 nwamd_door_req_event_register(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
);
146 nwamd_door_req_event_unregister(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
149 nwam_event_queue_fini(req
->nwda_data
.nwdad_register_info
.nwdad_name
);
151 return (NWAM_SUCCESS
);
156 nwamd_door_req_wlan_scan(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
));
168 nwamd_door_req_wlan_scan_results(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
);
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
;
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
;
201 "nwamd_door_req_wlan_scan_results: returning %d scan results",
203 nwamd_object_release(obj
);
205 return (NWAM_SUCCESS
);
210 nwamd_door_req_wlan_select(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
));
229 nwamd_door_req_wlan_set_key(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
));
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
);
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
);
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
);
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",
324 switch (object_type
) {
325 case NWAM_OBJECT_TYPE_ENM
:
326 err
= nwamd_enm_action(name
, action
);
328 case NWAM_OBJECT_TYPE_LOC
:
329 err
= nwamd_loc_action(name
, action
);
331 case NWAM_OBJECT_TYPE_NCU
:
332 err
= nwamd_ncu_action(name
, parent
, action
);
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
;
340 err
= nwamd_ncp_action(name
, action
);
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
);
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
);
363 case NWAM_OBJECT_TYPE_LOC
:
364 err
= nwamd_loc_action(name
, action
);
366 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
367 err
= nwamd_known_wlan_action(name
, action
);
369 case NWAM_OBJECT_TYPE_NCU
:
370 err
= nwamd_ncu_action(name
, parent
, action
);
372 case NWAM_OBJECT_TYPE_NCP
:
373 err
= nwamd_ncp_action(name
, action
);
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
;
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
);
392 case NWAM_OBJECT_TYPE_LOC
:
393 err
= nwamd_loc_action(name
, NWAM_ACTION_DESTROY
);
395 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
396 err
= nwamd_known_wlan_action(name
,
397 NWAM_ACTION_DESTROY
);
399 case NWAM_OBJECT_TYPE_NCU
:
400 err
= nwamd_ncu_action(name
, parent
,
401 NWAM_ACTION_DESTROY
);
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
;
410 err
= nwamd_ncp_action(name
,
411 NWAM_ACTION_DESTROY
);
413 (void) pthread_mutex_unlock(&active_ncp_mutex
);
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
;
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
;
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
);
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
));
451 nwamd_door_req_state(nwamd_door_arg_t
*req
, ucred_t
*ucr
, struct passwd
*pwd
)
453 char name
[NWAM_MAX_NAME_LEN
];
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
);
470 req
->nwda_data
.nwdad_object_state
.nwdad_state
=
472 req
->nwda_data
.nwdad_object_state
.
473 nwdad_aux_state
= NWAM_AUX_STATE_ACTIVE
;
475 "nwamd_door_req_state: NCP %s is active", name
);
477 req
->nwda_data
.nwdad_object_state
.nwdad_state
=
479 req
->nwda_data
.nwdad_object_state
.
481 NWAM_AUX_STATE_MANUAL_DISABLE
;
482 nlog(LOG_DEBUG
, "nwamd_door_req_state: "
483 "NCP %s is inactive", name
);
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
);
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
);
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
);
519 nwamd_door_req_priority_group(nwamd_door_arg_t
*req
, ucred_t
*ucr
,
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
);
535 nwamd_door_switch(void *cookie
, char *argp
, size_t arg_size
, door_desc_t
*dp
,
538 nwamd_door_arg_t
*req
;
541 struct passwd
*pwd
= NULL
;
542 boolean_t found
= B_FALSE
;
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",
552 req
->nwda_error
= NWAM_ERROR_INTERNAL
;
553 req
->nwda_status
= NWAM_REQUEST_STATUS_FAILED
;
556 uid
= ucred_getruid(ucr
);
558 if ((pwd
= getpwuid(uid
)) == NULL
) {
559 nlog(LOG_ERR
, "nwamd_door_switch: getpwuid failed: %s",
562 req
->nwda_error
= NWAM_ERROR_INTERNAL
;
563 req
->nwda_status
= NWAM_REQUEST_STATUS_FAILED
;
568 * Find door request entry in table, check auths and call the function
569 * handling the request.
572 i
< sizeof (door_req_table
) / sizeof (struct nwamd_door_req_entry
);
574 if (req
->nwda_type
!= door_req_table
[i
].ndre_type
)
579 if (door_req_table
[i
].ndre_auth
!= NULL
&&
580 chkauthattr(door_req_table
[i
].ndre_auth
,
581 pwd
->pw_name
) == 0) {
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
;
588 req
->nwda_error
= door_req_table
[i
].ndre_fn(req
, ucr
, pwd
);
593 "nwamd_door_switch: received unknown request type %d",
595 req
->nwda_status
= NWAM_REQUEST_STATUS_UNKNOWN
;
597 if (req
->nwda_error
== NWAM_SUCCESS
)
598 req
->nwda_status
= NWAM_REQUEST_STATUS_OK
;
600 req
->nwda_status
= NWAM_REQUEST_STATUS_FAILED
;
607 if (door_return((char *)req
, sizeof (nwamd_door_arg_t
), NULL
, 0)
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
621 nwamd_door_init(void)
623 const int door_mode
= 0644;
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) {
633 if ((nwam_door_fd
= creat(NWAM_DOOR
, door_mode
)) < 0) {
635 (void) door_revoke(doorfd
);
637 pfail("Couldn't create door: %s", strerror(err
));
639 (void) close(nwam_door_fd
);
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) {
654 (void) door_revoke(doorfd
);
656 pfail("Couldn't attach door: %s", strerror(err
));
661 nwamd_door_fini(void)
664 nlog(LOG_DEBUG
, "nwamd_door_fini: closing door");
665 (void) door_revoke(doorfd
);
668 (void) unlink(NWAM_DOOR
);