16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
23f6da83d4SAnurag S. Maskey  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
246ba597c5SAnurag S. Maskey  */
256ba597c5SAnurag S. Maskey 
266ba597c5SAnurag S. Maskey #include <auth_attr.h>
276ba597c5SAnurag S. Maskey #include <auth_list.h>
286ba597c5SAnurag S. Maskey #include <bsm/adt.h>
296ba597c5SAnurag S. Maskey #include <bsm/adt_event.h>
306ba597c5SAnurag S. Maskey #include <door.h>
316ba597c5SAnurag S. Maskey #include <errno.h>
326ba597c5SAnurag S. Maskey #include <fcntl.h>
336ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
346ba597c5SAnurag S. Maskey #include <libuutil.h>
356ba597c5SAnurag S. Maskey #include <pthread.h>
366ba597c5SAnurag S. Maskey #include <pwd.h>
376ba597c5SAnurag S. Maskey #include <stdlib.h>
386ba597c5SAnurag S. Maskey #include <sys/stat.h>
396ba597c5SAnurag S. Maskey 
406ba597c5SAnurag S. Maskey #include <sys/mman.h>
416ba597c5SAnurag S. Maskey #include <syslog.h>
426ba597c5SAnurag S. Maskey #include <unistd.h>
436ba597c5SAnurag S. Maskey 
446ba597c5SAnurag S. Maskey #include "conditions.h"
456ba597c5SAnurag S. Maskey #include "events.h"
466ba597c5SAnurag S. Maskey #include "ncp.h"
476ba597c5SAnurag S. Maskey #include "ncu.h"
486ba597c5SAnurag S. Maskey #include "objects.h"
496ba597c5SAnurag S. Maskey #include "util.h"
506ba597c5SAnurag S. Maskey 
516ba597c5SAnurag S. Maskey /*
526ba597c5SAnurag S. Maskey  * door_if.c
536ba597c5SAnurag S. Maskey  * This file contains functions which implement the command interface to
546ba597c5SAnurag S. Maskey  * nwam via the door NWAM_DOOR.  Doors provide a LPC mechanism that allows
556ba597c5SAnurag S. Maskey  * for threads in one process to cause code to execute in another process.
566ba597c5SAnurag S. Maskey  * Doors also provide the ability to pass data and file descriptors.  See
576ba597c5SAnurag S. Maskey  * libdoor(3LIB) for more information.
586ba597c5SAnurag S. Maskey  *
596ba597c5SAnurag S. Maskey  * This file exports two functions, nwamd_door_initialize() (which sets up
606ba597c5SAnurag S. Maskey  * the door) and nwamd_door_fini(), which removes it.
616ba597c5SAnurag S. Maskey  *
626ba597c5SAnurag S. Maskey  * It sets up the static routine nwamd_door_switch() to be called when a client
636ba597c5SAnurag S. Maskey  * calls the door (via door_call(3C)).  The structure nwam_request_t is
646ba597c5SAnurag S. Maskey  * passed as data and contains data to specify the type of action requested
656ba597c5SAnurag S. Maskey  * and any data need to meet that request.  A table consisting of entries
666ba597c5SAnurag S. Maskey  * for each door request, the associated authorization and the function to
676ba597c5SAnurag S. Maskey  * process that request is used to handle the various requests.
686ba597c5SAnurag S. Maskey  */
696ba597c5SAnurag S. Maskey 
706ba597c5SAnurag S. Maskey struct nwamd_door_req_entry
716ba597c5SAnurag S. Maskey {
726ba597c5SAnurag S. Maskey 	int ndre_type;
736ba597c5SAnurag S. Maskey 	char *ndre_auth;
746ba597c5SAnurag S. Maskey 	nwam_error_t (*ndre_fn)(nwamd_door_arg_t *, ucred_t *, struct passwd *);
756ba597c5SAnurag S. Maskey };
766ba597c5SAnurag S. Maskey 
776ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_event_register(nwamd_door_arg_t *,
786ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
796ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_event_unregister(nwamd_door_arg_t *,
806ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
816ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_wlan_scan(nwamd_door_arg_t *,
826ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
836ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *,
846ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
856ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_wlan_select(nwamd_door_arg_t *,
866ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
876ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_wlan_set_key(nwamd_door_arg_t *,
886ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
896ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_action(nwamd_door_arg_t *,
906ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
916ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_state(nwamd_door_arg_t *,
926ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
936ba597c5SAnurag S. Maskey static nwam_error_t nwamd_door_req_priority_group(nwamd_door_arg_t *,
946ba597c5SAnurag S. Maskey 	ucred_t *, struct passwd *);
956ba597c5SAnurag S. Maskey 
966ba597c5SAnurag S. Maskey /*
976ba597c5SAnurag S. Maskey  * This table defines the set of door commands available, the required
986ba597c5SAnurag S. Maskey  * authorizations for each command, and the function that carries out
996ba597c5SAnurag S. Maskey  * each command.
1006ba597c5SAnurag S. Maskey  */
1016ba597c5SAnurag S. Maskey struct nwamd_door_req_entry door_req_table[] =
1026ba597c5SAnurag S. Maskey {
1036ba597c5SAnurag S. Maskey 
1046ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_EVENT_REGISTER, AUTOCONF_READ_AUTH,
1056ba597c5SAnurag S. Maskey 	nwamd_door_req_event_register },
1066ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_EVENT_UNREGISTER, AUTOCONF_READ_AUTH,
1076ba597c5SAnurag S. Maskey 	nwamd_door_req_event_unregister },
1086ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_WLAN_SCAN, AUTOCONF_WLAN_AUTH,
1096ba597c5SAnurag S. Maskey 	nwamd_door_req_wlan_scan },
1106ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS, AUTOCONF_READ_AUTH,
1116ba597c5SAnurag S. Maskey 	nwamd_door_req_wlan_scan_results },
1126ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_WLAN_SELECT, AUTOCONF_WLAN_AUTH,
1136ba597c5SAnurag S. Maskey 	nwamd_door_req_wlan_select },
1146ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_WLAN_SET_KEY, AUTOCONF_WLAN_AUTH,
1156ba597c5SAnurag S. Maskey 	nwamd_door_req_wlan_set_key },
1166ba597c5SAnurag S. Maskey 	/* Requires WRITE, SELECT or WLAN auth depending on action */
1176ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_ACTION, NULL, nwamd_door_req_action },
1186ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_STATE, AUTOCONF_READ_AUTH,
1196ba597c5SAnurag S. Maskey 	nwamd_door_req_state },
1206ba597c5SAnurag S. Maskey 	{ NWAM_REQUEST_TYPE_PRIORITY_GROUP, AUTOCONF_READ_AUTH,
1216ba597c5SAnurag S. Maskey 	nwamd_door_req_priority_group },
1226ba597c5SAnurag S. Maskey };
1236ba597c5SAnurag S. Maskey 
1246ba597c5SAnurag S. Maskey int doorfd = -1;
1256ba597c5SAnurag S. Maskey 
1266ba597c5SAnurag S. Maskey /* ARGSUSED */
1276ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_event_register(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)1286ba597c5SAnurag S. Maskey nwamd_door_req_event_register(nwamd_door_arg_t *req, ucred_t *ucr,
1296ba597c5SAnurag S. Maskey     struct passwd *pwd)
1306ba597c5SAnurag S. Maskey {
1316ba597c5SAnurag S. Maskey 	nwam_error_t err;
1326ba597c5SAnurag S. Maskey 
1336ba597c5SAnurag S. Maskey 	err = nwam_event_queue_init
1346ba597c5SAnurag S. Maskey 	    (req->nwda_data.nwdad_register_info.nwdad_name);
1356ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
1366ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_req_event_register: "
1376ba597c5SAnurag S. Maskey 		    "could not register events for %s",
1386ba597c5SAnurag S. Maskey 		    req->nwda_data.nwdad_register_info.nwdad_name);
1396ba597c5SAnurag S. Maskey 	}
1406ba597c5SAnurag S. Maskey 
1416ba597c5SAnurag S. Maskey 	return (err);
1426ba597c5SAnurag S. Maskey }
1436ba597c5SAnurag S. Maskey 
1446ba597c5SAnurag S. Maskey /* ARGSUSED */
1456ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_event_unregister(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)1466ba597c5SAnurag S. Maskey nwamd_door_req_event_unregister(nwamd_door_arg_t *req, ucred_t *ucr,
1476ba597c5SAnurag S. Maskey     struct passwd *pwd)
1486ba597c5SAnurag S. Maskey {
1496ba597c5SAnurag S. Maskey 	nwam_event_queue_fini(req->nwda_data.nwdad_register_info.nwdad_name);
1506ba597c5SAnurag S. Maskey 
1516ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1526ba597c5SAnurag S. Maskey }
1536ba597c5SAnurag S. Maskey 
1546ba597c5SAnurag S. Maskey /* ARGSUSED1 */
1556ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_wlan_scan(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)1566ba597c5SAnurag S. Maskey nwamd_door_req_wlan_scan(nwamd_door_arg_t *req, ucred_t *ucr,
1576ba597c5SAnurag S. Maskey     struct passwd *pwd)
1586ba597c5SAnurag S. Maskey {
1596ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG,
1606ba597c5SAnurag S. Maskey 	    "nwamd_door_req_wlan_scan: processing WLAN scan request: "
1616ba597c5SAnurag S. Maskey 	    "link %s", req->nwda_data.nwdad_wlan_info.nwdad_name);
1626ba597c5SAnurag S. Maskey 
1636ba597c5SAnurag S. Maskey 	return (nwamd_wlan_scan(req->nwda_data.nwdad_wlan_info.nwdad_name));
1646ba597c5SAnurag S. Maskey }
1656ba597c5SAnurag S. Maskey 
1666ba597c5SAnurag S. Maskey /* ARGSUSED */
1676ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_wlan_scan_results(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)1686ba597c5SAnurag S. Maskey nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *req, ucred_t *ucr,
1696ba597c5SAnurag S. Maskey     struct passwd *pwd)
1706ba597c5SAnurag S. Maskey {
1716ba597c5SAnurag S. Maskey 	nwamd_object_t obj;
1726ba597c5SAnurag S. Maskey 	nwamd_ncu_t *ncu;
1736ba597c5SAnurag S. Maskey 	nwamd_link_t *link;
1746ba597c5SAnurag S. Maskey 	uint_t num_wlans;
1756ba597c5SAnurag S. Maskey 
1766ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "nwamd_door_req_wlan_scan_results: processing WLAN "
1776ba597c5SAnurag S. Maskey 	    "scan results request: link %s",
1786ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_name);
1796ba597c5SAnurag S. Maskey 
1806ba597c5SAnurag S. Maskey 	obj = nwamd_ncu_object_find(NWAM_NCU_TYPE_LINK,
1816ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_name);
1826ba597c5SAnurag S. Maskey 	if (obj == NULL) {
1836ba597c5SAnurag S. Maskey 		nlog(LOG_ERR,
1846ba597c5SAnurag S. Maskey 		    "nwamd_door_req_wlan_scan_results: link %s not found",
1856ba597c5SAnurag S. Maskey 		    req->nwda_data.nwdad_wlan_info.nwdad_name);
1866ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_NOT_FOUND);
1876ba597c5SAnurag S. Maskey 	}
1886ba597c5SAnurag S. Maskey 
1896ba597c5SAnurag S. Maskey 	ncu = obj->nwamd_object_data;
190f6da83d4SAnurag S. Maskey 	link = &ncu->ncu_link;
1916ba597c5SAnurag S. Maskey 	num_wlans = link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr_num;
1926ba597c5SAnurag S. Maskey 
1936ba597c5SAnurag S. Maskey 	if (num_wlans > 0) {
1946ba597c5SAnurag S. Maskey 		(void) memcpy
1956ba597c5SAnurag S. Maskey 		    (req->nwda_data.nwdad_wlan_info.nwdad_wlans,
1966ba597c5SAnurag S. Maskey 		    link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr,
1976ba597c5SAnurag S. Maskey 		    num_wlans * sizeof (nwam_wlan_t));
1986ba597c5SAnurag S. Maskey 	}
1996ba597c5SAnurag S. Maskey 	req->nwda_data.nwdad_wlan_info.nwdad_num_wlans = num_wlans;
2006ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG,
2016ba597c5SAnurag S. Maskey 	    "nwamd_door_req_wlan_scan_results: returning %d scan results",
2026ba597c5SAnurag S. Maskey 	    num_wlans);
2036ba597c5SAnurag S. Maskey 	nwamd_object_release(obj);
2046ba597c5SAnurag S. Maskey 
2056ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
2066ba597c5SAnurag S. Maskey }
2076ba597c5SAnurag S. Maskey 
2086ba597c5SAnurag S. Maskey /* ARGSUSED */
2096ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_wlan_select(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)2106ba597c5SAnurag S. Maskey nwamd_door_req_wlan_select(nwamd_door_arg_t *req, ucred_t *ucr,
2116ba597c5SAnurag S. Maskey     struct passwd *pwd)
2126ba597c5SAnurag S. Maskey {
2136ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG,
2146ba597c5SAnurag S. Maskey 	    "nwamd_door_req_wlan_select: processing WLAN selection : "
2156ba597c5SAnurag S. Maskey 	    "link %s ESSID %s , BSSID %s",
2166ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_name,
2176ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
2186ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid);
2196ba597c5SAnurag S. Maskey 	return (nwamd_wlan_select
2206ba597c5SAnurag S. Maskey 	    (req->nwda_data.nwdad_wlan_info.nwdad_name,
2216ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
2226ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid,
2236ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
2246ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_add_to_known_wlans));
2256ba597c5SAnurag S. Maskey }
2266ba597c5SAnurag S. Maskey 
2276ba597c5SAnurag S. Maskey /* ARGSUSED */
2286ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_wlan_set_key(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)2296ba597c5SAnurag S. Maskey nwamd_door_req_wlan_set_key(nwamd_door_arg_t *req, ucred_t *ucr,
2306ba597c5SAnurag S. Maskey     struct passwd *pwd)
2316ba597c5SAnurag S. Maskey {
2326ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG,
2336ba597c5SAnurag S. Maskey 	    "nwamd_door_req_wlan_set_key: processing WLAN key input : "
2346ba597c5SAnurag S. Maskey 	    "link %s ESSID %s BSSID %s",
2356ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_name,
2366ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
2376ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid);
2386ba597c5SAnurag S. Maskey 	return (nwamd_wlan_set_key
2396ba597c5SAnurag S. Maskey 	    (req->nwda_data.nwdad_wlan_info.nwdad_name,
240*c1976b83Senricop 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
241*c1976b83Senricop 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid,
2426ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
2436ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_keyslot,
2446ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_wlan_info.nwdad_key));
2456ba597c5SAnurag S. Maskey }
2466ba597c5SAnurag S. Maskey 
2476ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_action(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)2486ba597c5SAnurag S. Maskey nwamd_door_req_action(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
2496ba597c5SAnurag S. Maskey {
2506ba597c5SAnurag S. Maskey 	char name[NWAM_MAX_NAME_LEN];
2516ba597c5SAnurag S. Maskey 	char parent[NWAM_MAX_NAME_LEN];
2526ba597c5SAnurag S. Maskey 	nwam_action_t action = req->nwda_data.nwdad_object_action.nwdad_action;
2536ba597c5SAnurag S. Maskey 	nwam_object_type_t object_type =
2546ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_object_action.nwdad_object_type;
2556ba597c5SAnurag S. Maskey 	char *obj_type_str  = (char *)nwam_object_type_to_string(object_type);
2566ba597c5SAnurag S. Maskey 	nwam_error_t err;
2576ba597c5SAnurag S. Maskey 
2586ba597c5SAnurag S. Maskey 	/* Check for name, parent overrun */
2596ba597c5SAnurag S. Maskey 	if (strlcpy(name, req->nwda_data.nwdad_object_action.nwdad_name,
2606ba597c5SAnurag S. Maskey 	    sizeof (name)) == NWAM_MAX_NAME_LEN ||
2616ba597c5SAnurag S. Maskey 	    strlcpy(parent, req->nwda_data.nwdad_object_action.nwdad_parent,
2626ba597c5SAnurag S. Maskey 	    sizeof (parent)) == NWAM_MAX_NAME_LEN)
2636ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
2646ba597c5SAnurag S. Maskey 
2656ba597c5SAnurag S. Maskey 	/*
2666ba597c5SAnurag S. Maskey 	 * Check authorizations against actions.
2676ba597c5SAnurag S. Maskey 	 * - ENABLE/DISABLE requires SELECT auth
2686ba597c5SAnurag S. Maskey 	 * - ADD/DESTROY/REFRESH on Known WLANs requires WLAN auth
2696ba597c5SAnurag S. Maskey 	 * - ADD/DESTROY on other objects requires WRITE auth
2706ba597c5SAnurag S. Maskey 	 * - REFRESH on other objects requires either WRITE or SELECT auth
2716ba597c5SAnurag S. Maskey 	 */
2726ba597c5SAnurag S. Maskey 	if (action == NWAM_ACTION_ENABLE || action == NWAM_ACTION_DISABLE) {
2736ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
2746ba597c5SAnurag S. Maskey 			nwam_record_audit_event(ucr,
2756ba597c5SAnurag S. Maskey 			    action == NWAM_ACTION_ENABLE ?
2766ba597c5SAnurag S. Maskey 			    ADT_nwam_enable : ADT_nwam_disable, name,
2776ba597c5SAnurag S. Maskey 			    obj_type_str, ADT_FAILURE, ADT_FAIL_VALUE_AUTH);
2786ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: "
2796ba597c5SAnurag S. Maskey 			    "need %s for %s action", AUTOCONF_SELECT_AUTH,
2806ba597c5SAnurag S. Maskey 			    nwam_action_to_string(action));
2816ba597c5SAnurag S. Maskey 			return (NWAM_PERMISSION_DENIED);
2826ba597c5SAnurag S. Maskey 		}
2836ba597c5SAnurag S. Maskey 	} else if (object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN) {
2846ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_WLAN_AUTH, pwd->pw_name) == 0) {
2856ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: "
2866ba597c5SAnurag S. Maskey 			    "need %s for %s action on Known WLAN",
2876ba597c5SAnurag S. Maskey 			    AUTOCONF_WLAN_AUTH, nwam_action_to_string(action));
2886ba597c5SAnurag S. Maskey 			return (NWAM_PERMISSION_DENIED);
2896ba597c5SAnurag S. Maskey 		}
2906ba597c5SAnurag S. Maskey 	} else if (action == NWAM_ACTION_ADD || action == NWAM_ACTION_DESTROY) {
2916ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0) {
2926ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: "
2936ba597c5SAnurag S. Maskey 			    "need %s for %s action", AUTOCONF_WRITE_AUTH,
2946ba597c5SAnurag S. Maskey 			    nwam_action_to_string(action));
2956ba597c5SAnurag S. Maskey 			return (NWAM_PERMISSION_DENIED);
2966ba597c5SAnurag S. Maskey 		}
2976ba597c5SAnurag S. Maskey 	} else if (action == NWAM_ACTION_REFRESH) {
2986ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0 &&
2996ba597c5SAnurag S. Maskey 		    chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
3006ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: "
3016ba597c5SAnurag S. Maskey 			    "need either %s or %s for %s action",
3026ba597c5SAnurag S. Maskey 			    AUTOCONF_WRITE_AUTH, AUTOCONF_SELECT_AUTH,
3036ba597c5SAnurag S. Maskey 			    nwam_action_to_string(action));
3046ba597c5SAnurag S. Maskey 			return (NWAM_PERMISSION_DENIED);
3056ba597c5SAnurag S. Maskey 		}
3066ba597c5SAnurag S. Maskey 	} else {
3076ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
3086ba597c5SAnurag S. Maskey 		    "action %d (%s)", action, nwam_action_to_string(action));
3096ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
3106ba597c5SAnurag S. Maskey 	}
3116ba597c5SAnurag S. Maskey 
3126ba597c5SAnurag S. Maskey 	switch (action) {
3136ba597c5SAnurag S. Maskey 	case NWAM_ACTION_ENABLE:
3146ba597c5SAnurag S. Maskey 	case NWAM_ACTION_DISABLE:
3156ba597c5SAnurag S. Maskey 		nwam_record_audit_event(ucr,
3166ba597c5SAnurag S. Maskey 		    action == NWAM_ACTION_ENABLE ?
3176ba597c5SAnurag S. Maskey 		    ADT_nwam_enable : ADT_nwam_disable, name,
3186ba597c5SAnurag S. Maskey 		    obj_type_str, ADT_SUCCESS, ADT_SUCCESS);
3196ba597c5SAnurag S. Maskey 
3206ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_door_req_action: %s %s",
3216ba597c5SAnurag S. Maskey 		    action == NWAM_ACTION_ENABLE ? "enabling" : "disabling",
3226ba597c5SAnurag S. Maskey 		    name);
3236ba597c5SAnurag S. Maskey 
3246ba597c5SAnurag S. Maskey 		switch (object_type) {
3256ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_ENM:
3266ba597c5SAnurag S. Maskey 			err = nwamd_enm_action(name, action);
3276ba597c5SAnurag S. Maskey 			break;
3286ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_LOC:
3296ba597c5SAnurag S. Maskey 			err = nwamd_loc_action(name, action);
3306ba597c5SAnurag S. Maskey 			break;
3316ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCU:
3326ba597c5SAnurag S. Maskey 			err = nwamd_ncu_action(name, parent, action);
3336ba597c5SAnurag S. Maskey 			break;
3346ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCP:
3356ba597c5SAnurag S. Maskey 			if (action == NWAM_ACTION_DISABLE) {
3366ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "nwamd_door_req_action: "
3376ba597c5SAnurag S. Maskey 				    "NCPs cannot be disabled");
3386ba597c5SAnurag S. Maskey 				err = NWAM_INVALID_ARG;
3396ba597c5SAnurag S. Maskey 			} else {
3406ba597c5SAnurag S. Maskey 				err = nwamd_ncp_action(name, action);
3416ba597c5SAnurag S. Maskey 			}
3426ba597c5SAnurag S. Maskey 			break;
3436ba597c5SAnurag S. Maskey 		default:
3446ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
3456ba597c5SAnurag S. Maskey 			    "object type %d (%s)", object_type,
3466ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(object_type));
3476ba597c5SAnurag S. Maskey 			return (NWAM_INVALID_ARG);
3486ba597c5SAnurag S. Maskey 		}
3496ba597c5SAnurag S. Maskey 		break;
3506ba597c5SAnurag S. Maskey 
3516ba597c5SAnurag S. Maskey 	case NWAM_ACTION_ADD:
3526ba597c5SAnurag S. Maskey 	case NWAM_ACTION_REFRESH:
3536ba597c5SAnurag S. Maskey 		/*
3546ba597c5SAnurag S. Maskey 		 * Called whenever an object is committed in the library.
3556ba597c5SAnurag S. Maskey 		 * Reread that committed object into nwamd.
3566ba597c5SAnurag S. Maskey 		 */
3576ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "door_switch: refreshing %s", name);
3586ba597c5SAnurag S. Maskey 
3596ba597c5SAnurag S. Maskey 		switch (object_type) {
3606ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_ENM:
3616ba597c5SAnurag S. Maskey 			err = nwamd_enm_action(name, action);
3626ba597c5SAnurag S. Maskey 			break;
3636ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_LOC:
3646ba597c5SAnurag S. Maskey 			err = nwamd_loc_action(name, action);
3656ba597c5SAnurag S. Maskey 			break;
3666ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
3676ba597c5SAnurag S. Maskey 			err = nwamd_known_wlan_action(name, action);
3686ba597c5SAnurag S. Maskey 			break;
3696ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCU:
3706ba597c5SAnurag S. Maskey 			err = nwamd_ncu_action(name, parent, action);
3716ba597c5SAnurag S. Maskey 			break;
3726ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCP:
3736ba597c5SAnurag S. Maskey 			err = nwamd_ncp_action(name, action);
3746ba597c5SAnurag S. Maskey 			break;
3756ba597c5SAnurag S. Maskey 		default:
3766ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
3776ba597c5SAnurag S. Maskey 			    "object type %d (%s)", object_type,
3786ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(object_type));
3796ba597c5SAnurag S. Maskey 			err = NWAM_INVALID_ARG;
3806ba597c5SAnurag S. Maskey 			break;
3816ba597c5SAnurag S. Maskey 		}
3826ba597c5SAnurag S. Maskey 		break;
3836ba597c5SAnurag S. Maskey 
3846ba597c5SAnurag S. Maskey 	case NWAM_ACTION_DESTROY:
3856ba597c5SAnurag S. Maskey 		/* Object was destroyed, remove from nwamd */
3866ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "door_switch: removing %s", name);
3876ba597c5SAnurag S. Maskey 
3886ba597c5SAnurag S. Maskey 		switch (object_type) {
3896ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_ENM:
3906ba597c5SAnurag S. Maskey 			err = nwamd_enm_action(name, NWAM_ACTION_DESTROY);
3916ba597c5SAnurag S. Maskey 			break;
3926ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_LOC:
3936ba597c5SAnurag S. Maskey 			err = nwamd_loc_action(name, NWAM_ACTION_DESTROY);
3946ba597c5SAnurag S. Maskey 			break;
3956ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
3966ba597c5SAnurag S. Maskey 			err = nwamd_known_wlan_action(name,
3976ba597c5SAnurag S. Maskey 			    NWAM_ACTION_DESTROY);
3986ba597c5SAnurag S. Maskey 			break;
3996ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCU:
4006ba597c5SAnurag S. Maskey 			err = nwamd_ncu_action(name, parent,
4016ba597c5SAnurag S. Maskey 			    NWAM_ACTION_DESTROY);
4026ba597c5SAnurag S. Maskey 			break;
4036ba597c5SAnurag S. Maskey 		case NWAM_OBJECT_TYPE_NCP:
4046ba597c5SAnurag S. Maskey 			(void) pthread_mutex_lock(&active_ncp_mutex);
4056ba597c5SAnurag S. Maskey 			if (strcmp(name, active_ncp) == 0) {
4066ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "nwamd_door_req_action: %s is "
4076ba597c5SAnurag S. Maskey 				    "active, cannot destroy", parent);
4086ba597c5SAnurag S. Maskey 				err = NWAM_ENTITY_IN_USE;
4096ba597c5SAnurag S. Maskey 			} else {
4106ba597c5SAnurag S. Maskey 				err = nwamd_ncp_action(name,
4116ba597c5SAnurag S. Maskey 				    NWAM_ACTION_DESTROY);
4126ba597c5SAnurag S. Maskey 			}
4136ba597c5SAnurag S. Maskey 			(void) pthread_mutex_unlock(&active_ncp_mutex);
4146ba597c5SAnurag S. Maskey 			break;
4156ba597c5SAnurag S. Maskey 		default:
4166ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
4176ba597c5SAnurag S. Maskey 			    "object type %d (%s)", object_type,
4186ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(object_type));
4196ba597c5SAnurag S. Maskey 			err = NWAM_INVALID_ARG;
4206ba597c5SAnurag S. Maskey 			break;
4216ba597c5SAnurag S. Maskey 		}
4226ba597c5SAnurag S. Maskey 		break;
4236ba597c5SAnurag S. Maskey 
4246ba597c5SAnurag S. Maskey 	default:
4256ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
4266ba597c5SAnurag S. Maskey 		    "action %d (%s)", action, nwam_action_to_string(action));
4276ba597c5SAnurag S. Maskey 		err = NWAM_INVALID_ARG;
4286ba597c5SAnurag S. Maskey 		break;
4296ba597c5SAnurag S. Maskey 	}
4306ba597c5SAnurag S. Maskey 
4316ba597c5SAnurag S. Maskey 	if (err == NWAM_SUCCESS) {
4326ba597c5SAnurag S. Maskey 		/*
4336ba597c5SAnurag S. Maskey 		 * At this point, we've successfully carried out an action.
4346ba597c5SAnurag S. Maskey 		 * Configuration may have changed, so we need to recheck
4356ba597c5SAnurag S. Maskey 		 * conditions, however we want to avoid a flurry of condition
4366ba597c5SAnurag S. Maskey 		 * check events, so we enqueue a triggered condition check
4376ba597c5SAnurag S. Maskey 		 * if none is due in the next few seconds.
4386ba597c5SAnurag S. Maskey 		 */
4396ba597c5SAnurag S. Maskey 		nwamd_create_triggered_condition_check_event(NEXT_FEW_SECONDS);
4406ba597c5SAnurag S. Maskey 	} else {
4416ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_req_action: could not carry out "
4426ba597c5SAnurag S. Maskey 		    "%s action on %s: %s", nwam_action_to_string(action),
4436ba597c5SAnurag S. Maskey 		    name, nwam_strerror(err));
4446ba597c5SAnurag S. Maskey 	}
4456ba597c5SAnurag S. Maskey 
4466ba597c5SAnurag S. Maskey 	return (err);
4476ba597c5SAnurag S. Maskey }
4486ba597c5SAnurag S. Maskey 
4496ba597c5SAnurag S. Maskey /* ARGSUSED */
4506ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_state(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)4516ba597c5SAnurag S. Maskey nwamd_door_req_state(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
4526ba597c5SAnurag S. Maskey {
4536ba597c5SAnurag S. Maskey 	char name[NWAM_MAX_NAME_LEN];
4546ba597c5SAnurag S. Maskey 	nwamd_object_t obj;
4556ba597c5SAnurag S. Maskey 	nwam_object_type_t object_type =
4566ba597c5SAnurag S. Maskey 	    req->nwda_data.nwdad_object_state.nwdad_object_type;
4576ba597c5SAnurag S. Maskey 	boolean_t is_active = B_FALSE;
4586ba597c5SAnurag S. Maskey 
4596ba597c5SAnurag S. Maskey 	/* Check for name, parent overrun */
4606ba597c5SAnurag S. Maskey 	if (strlcpy(name, req->nwda_data.nwdad_object_state.nwdad_name,
4616ba597c5SAnurag S. Maskey 	    sizeof (name)) == NWAM_MAX_NAME_LEN)
4626ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
4636ba597c5SAnurag S. Maskey 
4646ba597c5SAnurag S. Maskey 	switch (object_type) {
4656ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCP:
4666ba597c5SAnurag S. Maskey 		(void) pthread_mutex_lock(&active_ncp_mutex);
4676ba597c5SAnurag S. Maskey 		is_active = (strcmp(active_ncp, name) == 0);
4686ba597c5SAnurag S. Maskey 		(void) pthread_mutex_unlock(&active_ncp_mutex);
4696ba597c5SAnurag S. Maskey 		if (is_active) {
4706ba597c5SAnurag S. Maskey 			req->nwda_data.nwdad_object_state.nwdad_state =
4716ba597c5SAnurag S. Maskey 			    NWAM_STATE_ONLINE;
4726ba597c5SAnurag S. Maskey 			req->nwda_data.nwdad_object_state.
4736ba597c5SAnurag S. Maskey 			    nwdad_aux_state = NWAM_AUX_STATE_ACTIVE;
4746ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG,
4756ba597c5SAnurag S. Maskey 			    "nwamd_door_req_state: NCP %s is active", name);
4766ba597c5SAnurag S. Maskey 		} else {
4776ba597c5SAnurag S. Maskey 			req->nwda_data.nwdad_object_state.nwdad_state =
4786ba597c5SAnurag S. Maskey 			    NWAM_STATE_DISABLED;
4796ba597c5SAnurag S. Maskey 			req->nwda_data.nwdad_object_state.
4806ba597c5SAnurag S. Maskey 			    nwdad_aux_state =
4816ba597c5SAnurag S. Maskey 			    NWAM_AUX_STATE_MANUAL_DISABLE;
4826ba597c5SAnurag S. Maskey 			nlog(LOG_DEBUG, "nwamd_door_req_state: "
4836ba597c5SAnurag S. Maskey 			    "NCP %s is inactive", name);
4846ba597c5SAnurag S. Maskey 		}
4856ba597c5SAnurag S. Maskey 		break;
4866ba597c5SAnurag S. Maskey 
4876ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_LOC:
4886ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_NCU:
4896ba597c5SAnurag S. Maskey 	case NWAM_OBJECT_TYPE_ENM:
4906ba597c5SAnurag S. Maskey 		obj = nwamd_object_find(object_type, name);
4916ba597c5SAnurag S. Maskey 		if (obj == NULL) {
4926ba597c5SAnurag S. Maskey 			nlog(LOG_ERR, "nwamd_door_req_state: %s %s not found",
4936ba597c5SAnurag S. Maskey 			    nwam_object_type_to_string(object_type), name);
4946ba597c5SAnurag S. Maskey 			return (NWAM_ENTITY_NOT_FOUND);
4956ba597c5SAnurag S. Maskey 		}
4966ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_door_req_state: %s %s is %s",
4976ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(object_type), name,
4986ba597c5SAnurag S. Maskey 		    nwam_state_to_string(obj->nwamd_object_state));
4996ba597c5SAnurag S. Maskey 		req->nwda_data.nwdad_object_state.nwdad_state =
5006ba597c5SAnurag S. Maskey 		    obj->nwamd_object_state;
5016ba597c5SAnurag S. Maskey 		req->nwda_data.nwdad_object_state.nwdad_aux_state =
5026ba597c5SAnurag S. Maskey 		    obj->nwamd_object_aux_state;
5036ba597c5SAnurag S. Maskey 		nwamd_object_release(obj);
5046ba597c5SAnurag S. Maskey 		break;
5056ba597c5SAnurag S. Maskey 
5066ba597c5SAnurag S. Maskey 	default:
5076ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_req_state: received invalid "
5086ba597c5SAnurag S. Maskey 		    "object type %d (%s)", object_type,
5096ba597c5SAnurag S. Maskey 		    nwam_object_type_to_string(object_type));
5106ba597c5SAnurag S. Maskey 		req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
5116ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
5126ba597c5SAnurag S. Maskey 	}
5136ba597c5SAnurag S. Maskey 
5146ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5156ba597c5SAnurag S. Maskey }
5166ba597c5SAnurag S. Maskey 
5176ba597c5SAnurag S. Maskey /* ARGSUSED */
5186ba597c5SAnurag S. Maskey static nwam_error_t
nwamd_door_req_priority_group(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)5196ba597c5SAnurag S. Maskey nwamd_door_req_priority_group(nwamd_door_arg_t *req, ucred_t *ucr,
5206ba597c5SAnurag S. Maskey     struct passwd *pwd)
5216ba597c5SAnurag S. Maskey {
5226ba597c5SAnurag S. Maskey 	(void) pthread_mutex_lock(&active_ncp_mutex);
5236ba597c5SAnurag S. Maskey 	nlog(LOG_DEBUG, "nwamd_door_req_priority_group: "
5246ba597c5SAnurag S. Maskey 	    "retrieving active priority-group: %d",
5256ba597c5SAnurag S. Maskey 	    current_ncu_priority_group);
5266ba597c5SAnurag S. Maskey 	req->nwda_data.nwdad_priority_group_info.nwdad_priority =
5276ba597c5SAnurag S. Maskey 	    current_ncu_priority_group;
5286ba597c5SAnurag S. Maskey 	(void) pthread_mutex_unlock(&active_ncp_mutex);
5296ba597c5SAnurag S. Maskey 
5306ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
5316ba597c5SAnurag S. Maskey }
5326ba597c5SAnurag S. Maskey 
5336ba597c5SAnurag S. Maskey /* ARGSUSED */
5346ba597c5SAnurag S. Maskey static void
nwamd_door_switch(void * cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t n_desc)5356ba597c5SAnurag S. Maskey nwamd_door_switch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
5366ba597c5SAnurag S. Maskey     uint_t n_desc)
5376ba597c5SAnurag S. Maskey {
5386ba597c5SAnurag S. Maskey 	nwamd_door_arg_t *req;
5396ba597c5SAnurag S. Maskey 	ucred_t *ucr = NULL;
5406ba597c5SAnurag S. Maskey 	uid_t uid;
5416ba597c5SAnurag S. Maskey 	struct passwd *pwd = NULL;
5426ba597c5SAnurag S. Maskey 	boolean_t found = B_FALSE;
5436ba597c5SAnurag S. Maskey 	int i;
5446ba597c5SAnurag S. Maskey 
5456ba597c5SAnurag S. Maskey 	/* LINTED E_BAD_PTR_CAST_ALIGN */
5466ba597c5SAnurag S. Maskey 	req = (nwamd_door_arg_t *)argp;
5476ba597c5SAnurag S. Maskey 	req->nwda_error = NWAM_SUCCESS;
5486ba597c5SAnurag S. Maskey 
5496ba597c5SAnurag S. Maskey 	if (door_ucred(&ucr) != 0) {
5506ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_switch: door_ucred failed: %s",
5516ba597c5SAnurag S. Maskey 		    strerror(errno));
5526ba597c5SAnurag S. Maskey 		req->nwda_error = NWAM_ERROR_INTERNAL;
5536ba597c5SAnurag S. Maskey 		req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
5546ba597c5SAnurag S. Maskey 		goto done;
5556ba597c5SAnurag S. Maskey 	}
5566ba597c5SAnurag S. Maskey 	uid = ucred_getruid(ucr);
5576ba597c5SAnurag S. Maskey 
5586ba597c5SAnurag S. Maskey 	if ((pwd = getpwuid(uid)) == NULL) {
5596ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "nwamd_door_switch: getpwuid failed: %s",
5606ba597c5SAnurag S. Maskey 		    strerror(errno));
5616ba597c5SAnurag S. Maskey 		endpwent();
5626ba597c5SAnurag S. Maskey 		req->nwda_error = NWAM_ERROR_INTERNAL;
5636ba597c5SAnurag S. Maskey 		req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
5646ba597c5SAnurag S. Maskey 		goto done;
5656ba597c5SAnurag S. Maskey 	}
5666ba597c5SAnurag S. Maskey 
5676ba597c5SAnurag S. Maskey 	/*
5686ba597c5SAnurag S. Maskey 	 * Find door request entry in table, check auths and call the function
5696ba597c5SAnurag S. Maskey 	 * handling the request.
5706ba597c5SAnurag S. Maskey 	 */
5716ba597c5SAnurag S. Maskey 	for (i = 0;
5726ba597c5SAnurag S. Maskey 	    i < sizeof (door_req_table) / sizeof (struct nwamd_door_req_entry);
5736ba597c5SAnurag S. Maskey 	    i++) {
5746ba597c5SAnurag S. Maskey 		if (req->nwda_type != door_req_table[i].ndre_type)
5756ba597c5SAnurag S. Maskey 			continue;
5766ba597c5SAnurag S. Maskey 
5776ba597c5SAnurag S. Maskey 		found = B_TRUE;
5786ba597c5SAnurag S. Maskey 
5796ba597c5SAnurag S. Maskey 		if (door_req_table[i].ndre_auth != NULL &&
5806ba597c5SAnurag S. Maskey 		    chkauthattr(door_req_table[i].ndre_auth,
5816ba597c5SAnurag S. Maskey 		    pwd->pw_name) == 0) {
5826ba597c5SAnurag S. Maskey 			nlog(LOG_ERR,
5836ba597c5SAnurag S. Maskey 			    "nwamd_door_switch: need %s for request type %d",
5846ba597c5SAnurag S. Maskey 			    door_req_table[i].ndre_auth, req->nwda_type);
5856ba597c5SAnurag S. Maskey 			req->nwda_error = NWAM_PERMISSION_DENIED;
5866ba597c5SAnurag S. Maskey 			break;
5876ba597c5SAnurag S. Maskey 		}
5886ba597c5SAnurag S. Maskey 		req->nwda_error = door_req_table[i].ndre_fn(req, ucr, pwd);
5896ba597c5SAnurag S. Maskey 		break;
5906ba597c5SAnurag S. Maskey 	}
5916ba597c5SAnurag S. Maskey 	if (!found) {
5926ba597c5SAnurag S. Maskey 		nlog(LOG_ERR,
5936ba597c5SAnurag S. Maskey 		    "nwamd_door_switch: received unknown request type %d",
5946ba597c5SAnurag S. Maskey 		    req->nwda_type);
5956ba597c5SAnurag S. Maskey 		req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
5966ba597c5SAnurag S. Maskey 	} else {
5976ba597c5SAnurag S. Maskey 		if (req->nwda_error == NWAM_SUCCESS)
5986ba597c5SAnurag S. Maskey 			req->nwda_status = NWAM_REQUEST_STATUS_OK;
5996ba597c5SAnurag S. Maskey 		else
6006ba597c5SAnurag S. Maskey 			req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
6016ba597c5SAnurag S. Maskey 	}
6026ba597c5SAnurag S. Maskey 
6036ba597c5SAnurag S. Maskey done:
6046ba597c5SAnurag S. Maskey 	ucred_free(ucr);
6056ba597c5SAnurag S. Maskey 	endpwent();
6066ba597c5SAnurag S. Maskey 
6076ba597c5SAnurag S. Maskey 	if (door_return((char *)req, sizeof (nwamd_door_arg_t), NULL, 0)
6086ba597c5SAnurag S. Maskey 	    == -1) {
6096ba597c5SAnurag S. Maskey 		nlog(LOG_ERR, "door_switch: type %d door_return failed: %s",
6106ba597c5SAnurag S. Maskey 		    req->nwda_type, strerror(errno));
6116ba597c5SAnurag S. Maskey 	}
6126ba597c5SAnurag S. Maskey }
6136ba597c5SAnurag S. Maskey 
6146ba597c5SAnurag S. Maskey /*
6156ba597c5SAnurag S. Maskey  * We initialize the nwamd door here.  Failure to have this happen is critical
6166ba597c5SAnurag S. Maskey  * to the daemon so we log a message and pass up notice to the caller who
6176ba597c5SAnurag S. Maskey  * will most likely abort trying to start.  This routine is meant to only
6186ba597c5SAnurag S. Maskey  * be called once.
6196ba597c5SAnurag S. Maskey  */
6206ba597c5SAnurag S. Maskey void
nwamd_door_init(void)6216ba597c5SAnurag S. Maskey nwamd_door_init(void)
6226ba597c5SAnurag S. Maskey {
6236ba597c5SAnurag S. Maskey 	const int door_mode = 0644;
6246ba597c5SAnurag S. Maskey 	struct stat buf;
6256ba597c5SAnurag S. Maskey 
6266ba597c5SAnurag S. Maskey 	if ((doorfd = door_create(nwamd_door_switch, NULL,
6276ba597c5SAnurag S. Maskey 	    DOOR_NO_CANCEL | DOOR_REFUSE_DESC)) == -1)
6286ba597c5SAnurag S. Maskey 		pfail("Unable to create door: %s", strerror(errno));
6296ba597c5SAnurag S. Maskey 
6306ba597c5SAnurag S. Maskey 	if (stat(NWAM_DOOR, &buf) < 0) {
6316ba597c5SAnurag S. Maskey 		int nwam_door_fd;
6326ba597c5SAnurag S. Maskey 
6336ba597c5SAnurag S. Maskey 		if ((nwam_door_fd = creat(NWAM_DOOR, door_mode)) < 0) {
6346ba597c5SAnurag S. Maskey 			int err = errno;
6356ba597c5SAnurag S. Maskey 			(void) door_revoke(doorfd);
6366ba597c5SAnurag S. Maskey 			doorfd = -1;
6376ba597c5SAnurag S. Maskey 			pfail("Couldn't create door: %s", strerror(err));
6386ba597c5SAnurag S. Maskey 		}
6396ba597c5SAnurag S. Maskey 		(void) close(nwam_door_fd);
6406ba597c5SAnurag S. Maskey 	} else {
6416ba597c5SAnurag S. Maskey 		if (buf.st_mode != door_mode) {
6426ba597c5SAnurag S. Maskey 			if (chmod(NWAM_DOOR, door_mode) == -1) {
6436ba597c5SAnurag S. Maskey 				nlog(LOG_ERR, "couldn't change mode of %s: %s",
6446ba597c5SAnurag S. Maskey 				    NWAM_DOOR, strerror(errno));
6456ba597c5SAnurag S. Maskey 			}
6466ba597c5SAnurag S. Maskey 		}
6476ba597c5SAnurag S. Maskey 	}
6486ba597c5SAnurag S. Maskey 	/* cleanup anything hanging around from a previous invocation */
6496ba597c5SAnurag S. Maskey 	(void) fdetach(NWAM_DOOR);
6506ba597c5SAnurag S. Maskey 
6516ba597c5SAnurag S. Maskey 	/* Place our door in the file system so that others can find us. */
6526ba597c5SAnurag S. Maskey 	if (fattach(doorfd, NWAM_DOOR) < 0) {
6536ba597c5SAnurag S. Maskey 		int err = errno;
6546ba597c5SAnurag S. Maskey 		(void) door_revoke(doorfd);
6556ba597c5SAnurag S. Maskey 		doorfd = -1;
6566ba597c5SAnurag S. Maskey 		pfail("Couldn't attach door: %s", strerror(err));
6576ba597c5SAnurag S. Maskey 	}
6586ba597c5SAnurag S. Maskey }
6596ba597c5SAnurag S. Maskey 
6606ba597c5SAnurag S. Maskey void
nwamd_door_fini(void)6616ba597c5SAnurag S. Maskey nwamd_door_fini(void)
6626ba597c5SAnurag S. Maskey {
6636ba597c5SAnurag S. Maskey 	if (doorfd != -1) {
6646ba597c5SAnurag S. Maskey 		nlog(LOG_DEBUG, "nwamd_door_fini: closing door");
6656ba597c5SAnurag S. Maskey 		(void) door_revoke(doorfd);
6666ba597c5SAnurag S. Maskey 		doorfd = -1;
6676ba597c5SAnurag S. Maskey 	}
6686ba597c5SAnurag S. Maskey 	(void) unlink(NWAM_DOOR);
6696ba597c5SAnurag S. Maskey }
670