xref: /onnv-gate/usr/src/cmd/cmd-inet/lib/nwamd/door_if.c (revision 12576:ab8aacaead3f)
111767SAnurag.Maskey@Sun.COM /*
211767SAnurag.Maskey@Sun.COM  * CDDL HEADER START
311767SAnurag.Maskey@Sun.COM  *
411767SAnurag.Maskey@Sun.COM  * The contents of this file are subject to the terms of the
511767SAnurag.Maskey@Sun.COM  * Common Development and Distribution License (the "License").
611767SAnurag.Maskey@Sun.COM  * You may not use this file except in compliance with the License.
711767SAnurag.Maskey@Sun.COM  *
811767SAnurag.Maskey@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911767SAnurag.Maskey@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1011767SAnurag.Maskey@Sun.COM  * See the License for the specific language governing permissions
1111767SAnurag.Maskey@Sun.COM  * and limitations under the License.
1211767SAnurag.Maskey@Sun.COM  *
1311767SAnurag.Maskey@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1411767SAnurag.Maskey@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511767SAnurag.Maskey@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1611767SAnurag.Maskey@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1711767SAnurag.Maskey@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1811767SAnurag.Maskey@Sun.COM  *
1911767SAnurag.Maskey@Sun.COM  * CDDL HEADER END
2011767SAnurag.Maskey@Sun.COM  */
2111767SAnurag.Maskey@Sun.COM 
2211767SAnurag.Maskey@Sun.COM /*
23*12576SAnurag.Maskey@Oracle.COM  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411767SAnurag.Maskey@Sun.COM  */
2511767SAnurag.Maskey@Sun.COM 
2611767SAnurag.Maskey@Sun.COM #include <auth_attr.h>
2711767SAnurag.Maskey@Sun.COM #include <auth_list.h>
2811767SAnurag.Maskey@Sun.COM #include <bsm/adt.h>
2911767SAnurag.Maskey@Sun.COM #include <bsm/adt_event.h>
3011767SAnurag.Maskey@Sun.COM #include <door.h>
3111767SAnurag.Maskey@Sun.COM #include <errno.h>
3211767SAnurag.Maskey@Sun.COM #include <fcntl.h>
3311767SAnurag.Maskey@Sun.COM #include <libnwam_priv.h>
3411767SAnurag.Maskey@Sun.COM #include <libuutil.h>
3511767SAnurag.Maskey@Sun.COM #include <pthread.h>
3611767SAnurag.Maskey@Sun.COM #include <pwd.h>
3711767SAnurag.Maskey@Sun.COM #include <stdlib.h>
3811767SAnurag.Maskey@Sun.COM #include <sys/stat.h>
3911767SAnurag.Maskey@Sun.COM 
4011767SAnurag.Maskey@Sun.COM #include <sys/mman.h>
4111767SAnurag.Maskey@Sun.COM #include <syslog.h>
4211767SAnurag.Maskey@Sun.COM #include <unistd.h>
4311767SAnurag.Maskey@Sun.COM 
4411767SAnurag.Maskey@Sun.COM #include "conditions.h"
4511767SAnurag.Maskey@Sun.COM #include "events.h"
4611767SAnurag.Maskey@Sun.COM #include "ncp.h"
4711767SAnurag.Maskey@Sun.COM #include "ncu.h"
4811767SAnurag.Maskey@Sun.COM #include "objects.h"
4911767SAnurag.Maskey@Sun.COM #include "util.h"
5011767SAnurag.Maskey@Sun.COM 
5111767SAnurag.Maskey@Sun.COM /*
5211767SAnurag.Maskey@Sun.COM  * door_if.c
5311767SAnurag.Maskey@Sun.COM  * This file contains functions which implement the command interface to
5411767SAnurag.Maskey@Sun.COM  * nwam via the door NWAM_DOOR.  Doors provide a LPC mechanism that allows
5511767SAnurag.Maskey@Sun.COM  * for threads in one process to cause code to execute in another process.
5611767SAnurag.Maskey@Sun.COM  * Doors also provide the ability to pass data and file descriptors.  See
5711767SAnurag.Maskey@Sun.COM  * libdoor(3LIB) for more information.
5811767SAnurag.Maskey@Sun.COM  *
5911767SAnurag.Maskey@Sun.COM  * This file exports two functions, nwamd_door_initialize() (which sets up
6011767SAnurag.Maskey@Sun.COM  * the door) and nwamd_door_fini(), which removes it.
6111767SAnurag.Maskey@Sun.COM  *
6211767SAnurag.Maskey@Sun.COM  * It sets up the static routine nwamd_door_switch() to be called when a client
6311767SAnurag.Maskey@Sun.COM  * calls the door (via door_call(3C)).  The structure nwam_request_t is
6411767SAnurag.Maskey@Sun.COM  * passed as data and contains data to specify the type of action requested
6511767SAnurag.Maskey@Sun.COM  * and any data need to meet that request.  A table consisting of entries
6611767SAnurag.Maskey@Sun.COM  * for each door request, the associated authorization and the function to
6711767SAnurag.Maskey@Sun.COM  * process that request is used to handle the various requests.
6811767SAnurag.Maskey@Sun.COM  */
6911767SAnurag.Maskey@Sun.COM 
7011767SAnurag.Maskey@Sun.COM struct nwamd_door_req_entry
7111767SAnurag.Maskey@Sun.COM {
7211767SAnurag.Maskey@Sun.COM 	int ndre_type;
7311767SAnurag.Maskey@Sun.COM 	char *ndre_auth;
7411767SAnurag.Maskey@Sun.COM 	nwam_error_t (*ndre_fn)(nwamd_door_arg_t *, ucred_t *, struct passwd *);
7511767SAnurag.Maskey@Sun.COM };
7611767SAnurag.Maskey@Sun.COM 
7711767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_event_register(nwamd_door_arg_t *,
7811767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
7911767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_event_unregister(nwamd_door_arg_t *,
8011767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
8111767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_wlan_scan(nwamd_door_arg_t *,
8211767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
8311767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *,
8411767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
8511767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_wlan_select(nwamd_door_arg_t *,
8611767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
8711767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_wlan_set_key(nwamd_door_arg_t *,
8811767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
8911767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_action(nwamd_door_arg_t *,
9011767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
9111767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_state(nwamd_door_arg_t *,
9211767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
9311767SAnurag.Maskey@Sun.COM static nwam_error_t nwamd_door_req_priority_group(nwamd_door_arg_t *,
9411767SAnurag.Maskey@Sun.COM 	ucred_t *, struct passwd *);
9511767SAnurag.Maskey@Sun.COM 
9611767SAnurag.Maskey@Sun.COM /*
9711767SAnurag.Maskey@Sun.COM  * This table defines the set of door commands available, the required
9811767SAnurag.Maskey@Sun.COM  * authorizations for each command, and the function that carries out
9911767SAnurag.Maskey@Sun.COM  * each command.
10011767SAnurag.Maskey@Sun.COM  */
10111767SAnurag.Maskey@Sun.COM struct nwamd_door_req_entry door_req_table[] =
10211767SAnurag.Maskey@Sun.COM {
10311767SAnurag.Maskey@Sun.COM 
10411767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_EVENT_REGISTER, AUTOCONF_READ_AUTH,
10511767SAnurag.Maskey@Sun.COM 	nwamd_door_req_event_register },
10611767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_EVENT_UNREGISTER, AUTOCONF_READ_AUTH,
10711767SAnurag.Maskey@Sun.COM 	nwamd_door_req_event_unregister },
10811767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_WLAN_SCAN, AUTOCONF_WLAN_AUTH,
10911767SAnurag.Maskey@Sun.COM 	nwamd_door_req_wlan_scan },
11011767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS, AUTOCONF_READ_AUTH,
11111767SAnurag.Maskey@Sun.COM 	nwamd_door_req_wlan_scan_results },
11211767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_WLAN_SELECT, AUTOCONF_WLAN_AUTH,
11311767SAnurag.Maskey@Sun.COM 	nwamd_door_req_wlan_select },
11411767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_WLAN_SET_KEY, AUTOCONF_WLAN_AUTH,
11511767SAnurag.Maskey@Sun.COM 	nwamd_door_req_wlan_set_key },
11611767SAnurag.Maskey@Sun.COM 	/* Requires WRITE, SELECT or WLAN auth depending on action */
11711767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_ACTION, NULL, nwamd_door_req_action },
11811767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_STATE, AUTOCONF_READ_AUTH,
11911767SAnurag.Maskey@Sun.COM 	nwamd_door_req_state },
12011767SAnurag.Maskey@Sun.COM 	{ NWAM_REQUEST_TYPE_PRIORITY_GROUP, AUTOCONF_READ_AUTH,
12111767SAnurag.Maskey@Sun.COM 	nwamd_door_req_priority_group },
12211767SAnurag.Maskey@Sun.COM };
12311767SAnurag.Maskey@Sun.COM 
12411767SAnurag.Maskey@Sun.COM int doorfd = -1;
12511767SAnurag.Maskey@Sun.COM 
12611767SAnurag.Maskey@Sun.COM /* ARGSUSED */
12711767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_event_register(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)12811767SAnurag.Maskey@Sun.COM nwamd_door_req_event_register(nwamd_door_arg_t *req, ucred_t *ucr,
12911767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
13011767SAnurag.Maskey@Sun.COM {
13111767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
13211767SAnurag.Maskey@Sun.COM 
13311767SAnurag.Maskey@Sun.COM 	err = nwam_event_queue_init
13411767SAnurag.Maskey@Sun.COM 	    (req->nwda_data.nwdad_register_info.nwdad_name);
13511767SAnurag.Maskey@Sun.COM 	if (err != NWAM_SUCCESS) {
13611767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_req_event_register: "
13711767SAnurag.Maskey@Sun.COM 		    "could not register events for %s",
13811767SAnurag.Maskey@Sun.COM 		    req->nwda_data.nwdad_register_info.nwdad_name);
13911767SAnurag.Maskey@Sun.COM 	}
14011767SAnurag.Maskey@Sun.COM 
14111767SAnurag.Maskey@Sun.COM 	return (err);
14211767SAnurag.Maskey@Sun.COM }
14311767SAnurag.Maskey@Sun.COM 
14411767SAnurag.Maskey@Sun.COM /* ARGSUSED */
14511767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_event_unregister(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)14611767SAnurag.Maskey@Sun.COM nwamd_door_req_event_unregister(nwamd_door_arg_t *req, ucred_t *ucr,
14711767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
14811767SAnurag.Maskey@Sun.COM {
14911767SAnurag.Maskey@Sun.COM 	nwam_event_queue_fini(req->nwda_data.nwdad_register_info.nwdad_name);
15011767SAnurag.Maskey@Sun.COM 
15111767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
15211767SAnurag.Maskey@Sun.COM }
15311767SAnurag.Maskey@Sun.COM 
15411767SAnurag.Maskey@Sun.COM /* ARGSUSED1 */
15511767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_wlan_scan(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)15611767SAnurag.Maskey@Sun.COM nwamd_door_req_wlan_scan(nwamd_door_arg_t *req, ucred_t *ucr,
15711767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
15811767SAnurag.Maskey@Sun.COM {
15911767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG,
16011767SAnurag.Maskey@Sun.COM 	    "nwamd_door_req_wlan_scan: processing WLAN scan request: "
16111767SAnurag.Maskey@Sun.COM 	    "link %s", req->nwda_data.nwdad_wlan_info.nwdad_name);
16211767SAnurag.Maskey@Sun.COM 
16311767SAnurag.Maskey@Sun.COM 	return (nwamd_wlan_scan(req->nwda_data.nwdad_wlan_info.nwdad_name));
16411767SAnurag.Maskey@Sun.COM }
16511767SAnurag.Maskey@Sun.COM 
16611767SAnurag.Maskey@Sun.COM /* ARGSUSED */
16711767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_wlan_scan_results(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)16811767SAnurag.Maskey@Sun.COM nwamd_door_req_wlan_scan_results(nwamd_door_arg_t *req, ucred_t *ucr,
16911767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
17011767SAnurag.Maskey@Sun.COM {
17111767SAnurag.Maskey@Sun.COM 	nwamd_object_t obj;
17211767SAnurag.Maskey@Sun.COM 	nwamd_ncu_t *ncu;
17311767SAnurag.Maskey@Sun.COM 	nwamd_link_t *link;
17411767SAnurag.Maskey@Sun.COM 	uint_t num_wlans;
17511767SAnurag.Maskey@Sun.COM 
17611767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG, "nwamd_door_req_wlan_scan_results: processing WLAN "
17711767SAnurag.Maskey@Sun.COM 	    "scan results request: link %s",
17811767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_name);
17911767SAnurag.Maskey@Sun.COM 
18011767SAnurag.Maskey@Sun.COM 	obj = nwamd_ncu_object_find(NWAM_NCU_TYPE_LINK,
18111767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_name);
18211767SAnurag.Maskey@Sun.COM 	if (obj == NULL) {
18311767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR,
18411767SAnurag.Maskey@Sun.COM 		    "nwamd_door_req_wlan_scan_results: link %s not found",
18511767SAnurag.Maskey@Sun.COM 		    req->nwda_data.nwdad_wlan_info.nwdad_name);
18611767SAnurag.Maskey@Sun.COM 		return (NWAM_ENTITY_NOT_FOUND);
18711767SAnurag.Maskey@Sun.COM 	}
18811767SAnurag.Maskey@Sun.COM 
18911767SAnurag.Maskey@Sun.COM 	ncu = obj->nwamd_object_data;
190*12576SAnurag.Maskey@Oracle.COM 	link = &ncu->ncu_link;
19111767SAnurag.Maskey@Sun.COM 	num_wlans = link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr_num;
19211767SAnurag.Maskey@Sun.COM 
19311767SAnurag.Maskey@Sun.COM 	if (num_wlans > 0) {
19411767SAnurag.Maskey@Sun.COM 		(void) memcpy
19511767SAnurag.Maskey@Sun.COM 		    (req->nwda_data.nwdad_wlan_info.nwdad_wlans,
19611767SAnurag.Maskey@Sun.COM 		    link->nwamd_link_wifi_scan.nwamd_wifi_scan_curr,
19711767SAnurag.Maskey@Sun.COM 		    num_wlans * sizeof (nwam_wlan_t));
19811767SAnurag.Maskey@Sun.COM 	}
19911767SAnurag.Maskey@Sun.COM 	req->nwda_data.nwdad_wlan_info.nwdad_num_wlans = num_wlans;
20011767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG,
20111767SAnurag.Maskey@Sun.COM 	    "nwamd_door_req_wlan_scan_results: returning %d scan results",
20211767SAnurag.Maskey@Sun.COM 	    num_wlans);
20311767SAnurag.Maskey@Sun.COM 	nwamd_object_release(obj);
20411767SAnurag.Maskey@Sun.COM 
20511767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
20611767SAnurag.Maskey@Sun.COM }
20711767SAnurag.Maskey@Sun.COM 
20811767SAnurag.Maskey@Sun.COM /* ARGSUSED */
20911767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_wlan_select(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)21011767SAnurag.Maskey@Sun.COM nwamd_door_req_wlan_select(nwamd_door_arg_t *req, ucred_t *ucr,
21111767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
21211767SAnurag.Maskey@Sun.COM {
21311767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG,
21411767SAnurag.Maskey@Sun.COM 	    "nwamd_door_req_wlan_select: processing WLAN selection : "
21511767SAnurag.Maskey@Sun.COM 	    "link %s ESSID %s , BSSID %s",
21611767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_name,
21711767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
21811767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid);
21911767SAnurag.Maskey@Sun.COM 	return (nwamd_wlan_select
22011767SAnurag.Maskey@Sun.COM 	    (req->nwda_data.nwdad_wlan_info.nwdad_name,
22111767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
22211767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid,
22311767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
22411767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_add_to_known_wlans));
22511767SAnurag.Maskey@Sun.COM }
22611767SAnurag.Maskey@Sun.COM 
22711767SAnurag.Maskey@Sun.COM /* ARGSUSED */
22811767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_wlan_set_key(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)22911767SAnurag.Maskey@Sun.COM nwamd_door_req_wlan_set_key(nwamd_door_arg_t *req, ucred_t *ucr,
23011767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
23111767SAnurag.Maskey@Sun.COM {
23211767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG,
23311767SAnurag.Maskey@Sun.COM 	    "nwamd_door_req_wlan_set_key: processing WLAN key input : "
23411767SAnurag.Maskey@Sun.COM 	    "link %s ESSID %s BSSID %s",
23511767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_name,
23611767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_essid,
23711767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_bssid);
23811767SAnurag.Maskey@Sun.COM 	return (nwamd_wlan_set_key
23911767SAnurag.Maskey@Sun.COM 	    (req->nwda_data.nwdad_wlan_info.nwdad_name,
24011767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_essid, NULL,
24111767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_security_mode,
24211767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_keyslot,
24311767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_wlan_info.nwdad_key));
24411767SAnurag.Maskey@Sun.COM }
24511767SAnurag.Maskey@Sun.COM 
24611767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_action(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)24711767SAnurag.Maskey@Sun.COM nwamd_door_req_action(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
24811767SAnurag.Maskey@Sun.COM {
24911767SAnurag.Maskey@Sun.COM 	char name[NWAM_MAX_NAME_LEN];
25011767SAnurag.Maskey@Sun.COM 	char parent[NWAM_MAX_NAME_LEN];
25111767SAnurag.Maskey@Sun.COM 	nwam_action_t action = req->nwda_data.nwdad_object_action.nwdad_action;
25211767SAnurag.Maskey@Sun.COM 	nwam_object_type_t object_type =
25311767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_object_action.nwdad_object_type;
25411767SAnurag.Maskey@Sun.COM 	char *obj_type_str  = (char *)nwam_object_type_to_string(object_type);
25511767SAnurag.Maskey@Sun.COM 	nwam_error_t err;
25611767SAnurag.Maskey@Sun.COM 
25711767SAnurag.Maskey@Sun.COM 	/* Check for name, parent overrun */
25811767SAnurag.Maskey@Sun.COM 	if (strlcpy(name, req->nwda_data.nwdad_object_action.nwdad_name,
25911767SAnurag.Maskey@Sun.COM 	    sizeof (name)) == NWAM_MAX_NAME_LEN ||
26011767SAnurag.Maskey@Sun.COM 	    strlcpy(parent, req->nwda_data.nwdad_object_action.nwdad_parent,
26111767SAnurag.Maskey@Sun.COM 	    sizeof (parent)) == NWAM_MAX_NAME_LEN)
26211767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
26311767SAnurag.Maskey@Sun.COM 
26411767SAnurag.Maskey@Sun.COM 	/*
26511767SAnurag.Maskey@Sun.COM 	 * Check authorizations against actions.
26611767SAnurag.Maskey@Sun.COM 	 * - ENABLE/DISABLE requires SELECT auth
26711767SAnurag.Maskey@Sun.COM 	 * - ADD/DESTROY/REFRESH on Known WLANs requires WLAN auth
26811767SAnurag.Maskey@Sun.COM 	 * - ADD/DESTROY on other objects requires WRITE auth
26911767SAnurag.Maskey@Sun.COM 	 * - REFRESH on other objects requires either WRITE or SELECT auth
27011767SAnurag.Maskey@Sun.COM 	 */
27111767SAnurag.Maskey@Sun.COM 	if (action == NWAM_ACTION_ENABLE || action == NWAM_ACTION_DISABLE) {
27211767SAnurag.Maskey@Sun.COM 		if (chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
27311767SAnurag.Maskey@Sun.COM 			nwam_record_audit_event(ucr,
27411767SAnurag.Maskey@Sun.COM 			    action == NWAM_ACTION_ENABLE ?
27511767SAnurag.Maskey@Sun.COM 			    ADT_nwam_enable : ADT_nwam_disable, name,
27611767SAnurag.Maskey@Sun.COM 			    obj_type_str, ADT_FAILURE, ADT_FAIL_VALUE_AUTH);
27711767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: "
27811767SAnurag.Maskey@Sun.COM 			    "need %s for %s action", AUTOCONF_SELECT_AUTH,
27911767SAnurag.Maskey@Sun.COM 			    nwam_action_to_string(action));
28011767SAnurag.Maskey@Sun.COM 			return (NWAM_PERMISSION_DENIED);
28111767SAnurag.Maskey@Sun.COM 		}
28211767SAnurag.Maskey@Sun.COM 	} else if (object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN) {
28311767SAnurag.Maskey@Sun.COM 		if (chkauthattr(AUTOCONF_WLAN_AUTH, pwd->pw_name) == 0) {
28411767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: "
28511767SAnurag.Maskey@Sun.COM 			    "need %s for %s action on Known WLAN",
28611767SAnurag.Maskey@Sun.COM 			    AUTOCONF_WLAN_AUTH, nwam_action_to_string(action));
28711767SAnurag.Maskey@Sun.COM 			return (NWAM_PERMISSION_DENIED);
28811767SAnurag.Maskey@Sun.COM 		}
28911767SAnurag.Maskey@Sun.COM 	} else if (action == NWAM_ACTION_ADD || action == NWAM_ACTION_DESTROY) {
29011767SAnurag.Maskey@Sun.COM 		if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0) {
29111767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: "
29211767SAnurag.Maskey@Sun.COM 			    "need %s for %s action", AUTOCONF_WRITE_AUTH,
29311767SAnurag.Maskey@Sun.COM 			    nwam_action_to_string(action));
29411767SAnurag.Maskey@Sun.COM 			return (NWAM_PERMISSION_DENIED);
29511767SAnurag.Maskey@Sun.COM 		}
29611767SAnurag.Maskey@Sun.COM 	} else if (action == NWAM_ACTION_REFRESH) {
29711767SAnurag.Maskey@Sun.COM 		if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0 &&
29811767SAnurag.Maskey@Sun.COM 		    chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0) {
29911767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: "
30011767SAnurag.Maskey@Sun.COM 			    "need either %s or %s for %s action",
30111767SAnurag.Maskey@Sun.COM 			    AUTOCONF_WRITE_AUTH, AUTOCONF_SELECT_AUTH,
30211767SAnurag.Maskey@Sun.COM 			    nwam_action_to_string(action));
30311767SAnurag.Maskey@Sun.COM 			return (NWAM_PERMISSION_DENIED);
30411767SAnurag.Maskey@Sun.COM 		}
30511767SAnurag.Maskey@Sun.COM 	} else {
30611767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
30711767SAnurag.Maskey@Sun.COM 		    "action %d (%s)", action, nwam_action_to_string(action));
30811767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
30911767SAnurag.Maskey@Sun.COM 	}
31011767SAnurag.Maskey@Sun.COM 
31111767SAnurag.Maskey@Sun.COM 	switch (action) {
31211767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ENABLE:
31311767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DISABLE:
31411767SAnurag.Maskey@Sun.COM 		nwam_record_audit_event(ucr,
31511767SAnurag.Maskey@Sun.COM 		    action == NWAM_ACTION_ENABLE ?
31611767SAnurag.Maskey@Sun.COM 		    ADT_nwam_enable : ADT_nwam_disable, name,
31711767SAnurag.Maskey@Sun.COM 		    obj_type_str, ADT_SUCCESS, ADT_SUCCESS);
31811767SAnurag.Maskey@Sun.COM 
31911767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "nwamd_door_req_action: %s %s",
32011767SAnurag.Maskey@Sun.COM 		    action == NWAM_ACTION_ENABLE ? "enabling" : "disabling",
32111767SAnurag.Maskey@Sun.COM 		    name);
32211767SAnurag.Maskey@Sun.COM 
32311767SAnurag.Maskey@Sun.COM 		switch (object_type) {
32411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
32511767SAnurag.Maskey@Sun.COM 			err = nwamd_enm_action(name, action);
32611767SAnurag.Maskey@Sun.COM 			break;
32711767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
32811767SAnurag.Maskey@Sun.COM 			err = nwamd_loc_action(name, action);
32911767SAnurag.Maskey@Sun.COM 			break;
33011767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
33111767SAnurag.Maskey@Sun.COM 			err = nwamd_ncu_action(name, parent, action);
33211767SAnurag.Maskey@Sun.COM 			break;
33311767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCP:
33411767SAnurag.Maskey@Sun.COM 			if (action == NWAM_ACTION_DISABLE) {
33511767SAnurag.Maskey@Sun.COM 				nlog(LOG_ERR, "nwamd_door_req_action: "
33611767SAnurag.Maskey@Sun.COM 				    "NCPs cannot be disabled");
33711767SAnurag.Maskey@Sun.COM 				err = NWAM_INVALID_ARG;
33811767SAnurag.Maskey@Sun.COM 			} else {
33911767SAnurag.Maskey@Sun.COM 				err = nwamd_ncp_action(name, action);
34011767SAnurag.Maskey@Sun.COM 			}
34111767SAnurag.Maskey@Sun.COM 			break;
34211767SAnurag.Maskey@Sun.COM 		default:
34311767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
34411767SAnurag.Maskey@Sun.COM 			    "object type %d (%s)", object_type,
34511767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(object_type));
34611767SAnurag.Maskey@Sun.COM 			return (NWAM_INVALID_ARG);
34711767SAnurag.Maskey@Sun.COM 		}
34811767SAnurag.Maskey@Sun.COM 		break;
34911767SAnurag.Maskey@Sun.COM 
35011767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_ADD:
35111767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_REFRESH:
35211767SAnurag.Maskey@Sun.COM 		/*
35311767SAnurag.Maskey@Sun.COM 		 * Called whenever an object is committed in the library.
35411767SAnurag.Maskey@Sun.COM 		 * Reread that committed object into nwamd.
35511767SAnurag.Maskey@Sun.COM 		 */
35611767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "door_switch: refreshing %s", name);
35711767SAnurag.Maskey@Sun.COM 
35811767SAnurag.Maskey@Sun.COM 		switch (object_type) {
35911767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
36011767SAnurag.Maskey@Sun.COM 			err = nwamd_enm_action(name, action);
36111767SAnurag.Maskey@Sun.COM 			break;
36211767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
36311767SAnurag.Maskey@Sun.COM 			err = nwamd_loc_action(name, action);
36411767SAnurag.Maskey@Sun.COM 			break;
36511767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
36611767SAnurag.Maskey@Sun.COM 			err = nwamd_known_wlan_action(name, action);
36711767SAnurag.Maskey@Sun.COM 			break;
36811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
36911767SAnurag.Maskey@Sun.COM 			err = nwamd_ncu_action(name, parent, action);
37011767SAnurag.Maskey@Sun.COM 			break;
37111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCP:
37211767SAnurag.Maskey@Sun.COM 			err = nwamd_ncp_action(name, action);
37311767SAnurag.Maskey@Sun.COM 			break;
37411767SAnurag.Maskey@Sun.COM 		default:
37511767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
37611767SAnurag.Maskey@Sun.COM 			    "object type %d (%s)", object_type,
37711767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(object_type));
37811767SAnurag.Maskey@Sun.COM 			err = NWAM_INVALID_ARG;
37911767SAnurag.Maskey@Sun.COM 			break;
38011767SAnurag.Maskey@Sun.COM 		}
38111767SAnurag.Maskey@Sun.COM 		break;
38211767SAnurag.Maskey@Sun.COM 
38311767SAnurag.Maskey@Sun.COM 	case NWAM_ACTION_DESTROY:
38411767SAnurag.Maskey@Sun.COM 		/* Object was destroyed, remove from nwamd */
38511767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "door_switch: removing %s", name);
38611767SAnurag.Maskey@Sun.COM 
38711767SAnurag.Maskey@Sun.COM 		switch (object_type) {
38811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_ENM:
38911767SAnurag.Maskey@Sun.COM 			err = nwamd_enm_action(name, NWAM_ACTION_DESTROY);
39011767SAnurag.Maskey@Sun.COM 			break;
39111767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_LOC:
39211767SAnurag.Maskey@Sun.COM 			err = nwamd_loc_action(name, NWAM_ACTION_DESTROY);
39311767SAnurag.Maskey@Sun.COM 			break;
39411767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_KNOWN_WLAN:
39511767SAnurag.Maskey@Sun.COM 			err = nwamd_known_wlan_action(name,
39611767SAnurag.Maskey@Sun.COM 			    NWAM_ACTION_DESTROY);
39711767SAnurag.Maskey@Sun.COM 			break;
39811767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCU:
39911767SAnurag.Maskey@Sun.COM 			err = nwamd_ncu_action(name, parent,
40011767SAnurag.Maskey@Sun.COM 			    NWAM_ACTION_DESTROY);
40111767SAnurag.Maskey@Sun.COM 			break;
40211767SAnurag.Maskey@Sun.COM 		case NWAM_OBJECT_TYPE_NCP:
40311767SAnurag.Maskey@Sun.COM 			(void) pthread_mutex_lock(&active_ncp_mutex);
40411767SAnurag.Maskey@Sun.COM 			if (strcmp(name, active_ncp) == 0) {
40511767SAnurag.Maskey@Sun.COM 				nlog(LOG_ERR, "nwamd_door_req_action: %s is "
40611767SAnurag.Maskey@Sun.COM 				    "active, cannot destroy", parent);
40711767SAnurag.Maskey@Sun.COM 				err = NWAM_ENTITY_IN_USE;
40811767SAnurag.Maskey@Sun.COM 			} else {
40911767SAnurag.Maskey@Sun.COM 				err = nwamd_ncp_action(name,
41011767SAnurag.Maskey@Sun.COM 				    NWAM_ACTION_DESTROY);
41111767SAnurag.Maskey@Sun.COM 			}
41211767SAnurag.Maskey@Sun.COM 			(void) pthread_mutex_unlock(&active_ncp_mutex);
41311767SAnurag.Maskey@Sun.COM 			break;
41411767SAnurag.Maskey@Sun.COM 		default:
41511767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_action: received invalid "
41611767SAnurag.Maskey@Sun.COM 			    "object type %d (%s)", object_type,
41711767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(object_type));
41811767SAnurag.Maskey@Sun.COM 			err = NWAM_INVALID_ARG;
41911767SAnurag.Maskey@Sun.COM 			break;
42011767SAnurag.Maskey@Sun.COM 		}
42111767SAnurag.Maskey@Sun.COM 		break;
42211767SAnurag.Maskey@Sun.COM 
42311767SAnurag.Maskey@Sun.COM 	default:
42411767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_req_action: received unknown "
42511767SAnurag.Maskey@Sun.COM 		    "action %d (%s)", action, nwam_action_to_string(action));
42611767SAnurag.Maskey@Sun.COM 		err = NWAM_INVALID_ARG;
42711767SAnurag.Maskey@Sun.COM 		break;
42811767SAnurag.Maskey@Sun.COM 	}
42911767SAnurag.Maskey@Sun.COM 
43011767SAnurag.Maskey@Sun.COM 	if (err == NWAM_SUCCESS) {
43111767SAnurag.Maskey@Sun.COM 		/*
43211767SAnurag.Maskey@Sun.COM 		 * At this point, we've successfully carried out an action.
43311767SAnurag.Maskey@Sun.COM 		 * Configuration may have changed, so we need to recheck
43411767SAnurag.Maskey@Sun.COM 		 * conditions, however we want to avoid a flurry of condition
43511767SAnurag.Maskey@Sun.COM 		 * check events, so we enqueue a triggered condition check
43611767SAnurag.Maskey@Sun.COM 		 * if none is due in the next few seconds.
43711767SAnurag.Maskey@Sun.COM 		 */
43811767SAnurag.Maskey@Sun.COM 		nwamd_create_triggered_condition_check_event(NEXT_FEW_SECONDS);
43911767SAnurag.Maskey@Sun.COM 	} else {
44011767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_req_action: could not carry out "
44111767SAnurag.Maskey@Sun.COM 		    "%s action on %s: %s", nwam_action_to_string(action),
44211767SAnurag.Maskey@Sun.COM 		    name, nwam_strerror(err));
44311767SAnurag.Maskey@Sun.COM 	}
44411767SAnurag.Maskey@Sun.COM 
44511767SAnurag.Maskey@Sun.COM 	return (err);
44611767SAnurag.Maskey@Sun.COM }
44711767SAnurag.Maskey@Sun.COM 
44811767SAnurag.Maskey@Sun.COM /* ARGSUSED */
44911767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_state(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)45011767SAnurag.Maskey@Sun.COM nwamd_door_req_state(nwamd_door_arg_t *req, ucred_t *ucr, struct passwd *pwd)
45111767SAnurag.Maskey@Sun.COM {
45211767SAnurag.Maskey@Sun.COM 	char name[NWAM_MAX_NAME_LEN];
45311767SAnurag.Maskey@Sun.COM 	nwamd_object_t obj;
45411767SAnurag.Maskey@Sun.COM 	nwam_object_type_t object_type =
45511767SAnurag.Maskey@Sun.COM 	    req->nwda_data.nwdad_object_state.nwdad_object_type;
45611767SAnurag.Maskey@Sun.COM 	boolean_t is_active = B_FALSE;
45711767SAnurag.Maskey@Sun.COM 
45811767SAnurag.Maskey@Sun.COM 	/* Check for name, parent overrun */
45911767SAnurag.Maskey@Sun.COM 	if (strlcpy(name, req->nwda_data.nwdad_object_state.nwdad_name,
46011767SAnurag.Maskey@Sun.COM 	    sizeof (name)) == NWAM_MAX_NAME_LEN)
46111767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
46211767SAnurag.Maskey@Sun.COM 
46311767SAnurag.Maskey@Sun.COM 	switch (object_type) {
46411767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCP:
46511767SAnurag.Maskey@Sun.COM 		(void) pthread_mutex_lock(&active_ncp_mutex);
46611767SAnurag.Maskey@Sun.COM 		is_active = (strcmp(active_ncp, name) == 0);
46711767SAnurag.Maskey@Sun.COM 		(void) pthread_mutex_unlock(&active_ncp_mutex);
46811767SAnurag.Maskey@Sun.COM 		if (is_active) {
46911767SAnurag.Maskey@Sun.COM 			req->nwda_data.nwdad_object_state.nwdad_state =
47011767SAnurag.Maskey@Sun.COM 			    NWAM_STATE_ONLINE;
47111767SAnurag.Maskey@Sun.COM 			req->nwda_data.nwdad_object_state.
47211767SAnurag.Maskey@Sun.COM 			    nwdad_aux_state = NWAM_AUX_STATE_ACTIVE;
47311767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG,
47411767SAnurag.Maskey@Sun.COM 			    "nwamd_door_req_state: NCP %s is active", name);
47511767SAnurag.Maskey@Sun.COM 		} else {
47611767SAnurag.Maskey@Sun.COM 			req->nwda_data.nwdad_object_state.nwdad_state =
47711767SAnurag.Maskey@Sun.COM 			    NWAM_STATE_DISABLED;
47811767SAnurag.Maskey@Sun.COM 			req->nwda_data.nwdad_object_state.
47911767SAnurag.Maskey@Sun.COM 			    nwdad_aux_state =
48011767SAnurag.Maskey@Sun.COM 			    NWAM_AUX_STATE_MANUAL_DISABLE;
48111767SAnurag.Maskey@Sun.COM 			nlog(LOG_DEBUG, "nwamd_door_req_state: "
48211767SAnurag.Maskey@Sun.COM 			    "NCP %s is inactive", name);
48311767SAnurag.Maskey@Sun.COM 		}
48411767SAnurag.Maskey@Sun.COM 		break;
48511767SAnurag.Maskey@Sun.COM 
48611767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_LOC:
48711767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_NCU:
48811767SAnurag.Maskey@Sun.COM 	case NWAM_OBJECT_TYPE_ENM:
48911767SAnurag.Maskey@Sun.COM 		obj = nwamd_object_find(object_type, name);
49011767SAnurag.Maskey@Sun.COM 		if (obj == NULL) {
49111767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR, "nwamd_door_req_state: %s %s not found",
49211767SAnurag.Maskey@Sun.COM 			    nwam_object_type_to_string(object_type), name);
49311767SAnurag.Maskey@Sun.COM 			return (NWAM_ENTITY_NOT_FOUND);
49411767SAnurag.Maskey@Sun.COM 		}
49511767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "nwamd_door_req_state: %s %s is %s",
49611767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(object_type), name,
49711767SAnurag.Maskey@Sun.COM 		    nwam_state_to_string(obj->nwamd_object_state));
49811767SAnurag.Maskey@Sun.COM 		req->nwda_data.nwdad_object_state.nwdad_state =
49911767SAnurag.Maskey@Sun.COM 		    obj->nwamd_object_state;
50011767SAnurag.Maskey@Sun.COM 		req->nwda_data.nwdad_object_state.nwdad_aux_state =
50111767SAnurag.Maskey@Sun.COM 		    obj->nwamd_object_aux_state;
50211767SAnurag.Maskey@Sun.COM 		nwamd_object_release(obj);
50311767SAnurag.Maskey@Sun.COM 		break;
50411767SAnurag.Maskey@Sun.COM 
50511767SAnurag.Maskey@Sun.COM 	default:
50611767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_req_state: received invalid "
50711767SAnurag.Maskey@Sun.COM 		    "object type %d (%s)", object_type,
50811767SAnurag.Maskey@Sun.COM 		    nwam_object_type_to_string(object_type));
50911767SAnurag.Maskey@Sun.COM 		req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
51011767SAnurag.Maskey@Sun.COM 		return (NWAM_INVALID_ARG);
51111767SAnurag.Maskey@Sun.COM 	}
51211767SAnurag.Maskey@Sun.COM 
51311767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
51411767SAnurag.Maskey@Sun.COM }
51511767SAnurag.Maskey@Sun.COM 
51611767SAnurag.Maskey@Sun.COM /* ARGSUSED */
51711767SAnurag.Maskey@Sun.COM static nwam_error_t
nwamd_door_req_priority_group(nwamd_door_arg_t * req,ucred_t * ucr,struct passwd * pwd)51811767SAnurag.Maskey@Sun.COM nwamd_door_req_priority_group(nwamd_door_arg_t *req, ucred_t *ucr,
51911767SAnurag.Maskey@Sun.COM     struct passwd *pwd)
52011767SAnurag.Maskey@Sun.COM {
52111767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_lock(&active_ncp_mutex);
52211767SAnurag.Maskey@Sun.COM 	nlog(LOG_DEBUG, "nwamd_door_req_priority_group: "
52311767SAnurag.Maskey@Sun.COM 	    "retrieving active priority-group: %d",
52411767SAnurag.Maskey@Sun.COM 	    current_ncu_priority_group);
52511767SAnurag.Maskey@Sun.COM 	req->nwda_data.nwdad_priority_group_info.nwdad_priority =
52611767SAnurag.Maskey@Sun.COM 	    current_ncu_priority_group;
52711767SAnurag.Maskey@Sun.COM 	(void) pthread_mutex_unlock(&active_ncp_mutex);
52811767SAnurag.Maskey@Sun.COM 
52911767SAnurag.Maskey@Sun.COM 	return (NWAM_SUCCESS);
53011767SAnurag.Maskey@Sun.COM }
53111767SAnurag.Maskey@Sun.COM 
53211767SAnurag.Maskey@Sun.COM /* ARGSUSED */
53311767SAnurag.Maskey@Sun.COM static void
nwamd_door_switch(void * cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t n_desc)53411767SAnurag.Maskey@Sun.COM nwamd_door_switch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
53511767SAnurag.Maskey@Sun.COM     uint_t n_desc)
53611767SAnurag.Maskey@Sun.COM {
53711767SAnurag.Maskey@Sun.COM 	nwamd_door_arg_t *req;
53811767SAnurag.Maskey@Sun.COM 	ucred_t *ucr = NULL;
53911767SAnurag.Maskey@Sun.COM 	uid_t uid;
54011767SAnurag.Maskey@Sun.COM 	struct passwd *pwd = NULL;
54111767SAnurag.Maskey@Sun.COM 	boolean_t found = B_FALSE;
54211767SAnurag.Maskey@Sun.COM 	int i;
54311767SAnurag.Maskey@Sun.COM 
54411767SAnurag.Maskey@Sun.COM 	/* LINTED E_BAD_PTR_CAST_ALIGN */
54511767SAnurag.Maskey@Sun.COM 	req = (nwamd_door_arg_t *)argp;
54611767SAnurag.Maskey@Sun.COM 	req->nwda_error = NWAM_SUCCESS;
54711767SAnurag.Maskey@Sun.COM 
54811767SAnurag.Maskey@Sun.COM 	if (door_ucred(&ucr) != 0) {
54911767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_switch: door_ucred failed: %s",
55011767SAnurag.Maskey@Sun.COM 		    strerror(errno));
55111767SAnurag.Maskey@Sun.COM 		req->nwda_error = NWAM_ERROR_INTERNAL;
55211767SAnurag.Maskey@Sun.COM 		req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
55311767SAnurag.Maskey@Sun.COM 		goto done;
55411767SAnurag.Maskey@Sun.COM 	}
55511767SAnurag.Maskey@Sun.COM 	uid = ucred_getruid(ucr);
55611767SAnurag.Maskey@Sun.COM 
55711767SAnurag.Maskey@Sun.COM 	if ((pwd = getpwuid(uid)) == NULL) {
55811767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "nwamd_door_switch: getpwuid failed: %s",
55911767SAnurag.Maskey@Sun.COM 		    strerror(errno));
56011767SAnurag.Maskey@Sun.COM 		endpwent();
56111767SAnurag.Maskey@Sun.COM 		req->nwda_error = NWAM_ERROR_INTERNAL;
56211767SAnurag.Maskey@Sun.COM 		req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
56311767SAnurag.Maskey@Sun.COM 		goto done;
56411767SAnurag.Maskey@Sun.COM 	}
56511767SAnurag.Maskey@Sun.COM 
56611767SAnurag.Maskey@Sun.COM 	/*
56711767SAnurag.Maskey@Sun.COM 	 * Find door request entry in table, check auths and call the function
56811767SAnurag.Maskey@Sun.COM 	 * handling the request.
56911767SAnurag.Maskey@Sun.COM 	 */
57011767SAnurag.Maskey@Sun.COM 	for (i = 0;
57111767SAnurag.Maskey@Sun.COM 	    i < sizeof (door_req_table) / sizeof (struct nwamd_door_req_entry);
57211767SAnurag.Maskey@Sun.COM 	    i++) {
57311767SAnurag.Maskey@Sun.COM 		if (req->nwda_type != door_req_table[i].ndre_type)
57411767SAnurag.Maskey@Sun.COM 			continue;
57511767SAnurag.Maskey@Sun.COM 
57611767SAnurag.Maskey@Sun.COM 		found = B_TRUE;
57711767SAnurag.Maskey@Sun.COM 
57811767SAnurag.Maskey@Sun.COM 		if (door_req_table[i].ndre_auth != NULL &&
57911767SAnurag.Maskey@Sun.COM 		    chkauthattr(door_req_table[i].ndre_auth,
58011767SAnurag.Maskey@Sun.COM 		    pwd->pw_name) == 0) {
58111767SAnurag.Maskey@Sun.COM 			nlog(LOG_ERR,
58211767SAnurag.Maskey@Sun.COM 			    "nwamd_door_switch: need %s for request type %d",
58311767SAnurag.Maskey@Sun.COM 			    door_req_table[i].ndre_auth, req->nwda_type);
58411767SAnurag.Maskey@Sun.COM 			req->nwda_error = NWAM_PERMISSION_DENIED;
58511767SAnurag.Maskey@Sun.COM 			break;
58611767SAnurag.Maskey@Sun.COM 		}
58711767SAnurag.Maskey@Sun.COM 		req->nwda_error = door_req_table[i].ndre_fn(req, ucr, pwd);
58811767SAnurag.Maskey@Sun.COM 		break;
58911767SAnurag.Maskey@Sun.COM 	}
59011767SAnurag.Maskey@Sun.COM 	if (!found) {
59111767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR,
59211767SAnurag.Maskey@Sun.COM 		    "nwamd_door_switch: received unknown request type %d",
59311767SAnurag.Maskey@Sun.COM 		    req->nwda_type);
59411767SAnurag.Maskey@Sun.COM 		req->nwda_status = NWAM_REQUEST_STATUS_UNKNOWN;
59511767SAnurag.Maskey@Sun.COM 	} else {
59611767SAnurag.Maskey@Sun.COM 		if (req->nwda_error == NWAM_SUCCESS)
59711767SAnurag.Maskey@Sun.COM 			req->nwda_status = NWAM_REQUEST_STATUS_OK;
59811767SAnurag.Maskey@Sun.COM 		else
59911767SAnurag.Maskey@Sun.COM 			req->nwda_status = NWAM_REQUEST_STATUS_FAILED;
60011767SAnurag.Maskey@Sun.COM 	}
60111767SAnurag.Maskey@Sun.COM 
60211767SAnurag.Maskey@Sun.COM done:
60311767SAnurag.Maskey@Sun.COM 	ucred_free(ucr);
60411767SAnurag.Maskey@Sun.COM 	endpwent();
60511767SAnurag.Maskey@Sun.COM 
60611767SAnurag.Maskey@Sun.COM 	if (door_return((char *)req, sizeof (nwamd_door_arg_t), NULL, 0)
60711767SAnurag.Maskey@Sun.COM 	    == -1) {
60811767SAnurag.Maskey@Sun.COM 		nlog(LOG_ERR, "door_switch: type %d door_return failed: %s",
60911767SAnurag.Maskey@Sun.COM 		    req->nwda_type, strerror(errno));
61011767SAnurag.Maskey@Sun.COM 	}
61111767SAnurag.Maskey@Sun.COM }
61211767SAnurag.Maskey@Sun.COM 
61311767SAnurag.Maskey@Sun.COM /*
61411767SAnurag.Maskey@Sun.COM  * We initialize the nwamd door here.  Failure to have this happen is critical
61511767SAnurag.Maskey@Sun.COM  * to the daemon so we log a message and pass up notice to the caller who
61611767SAnurag.Maskey@Sun.COM  * will most likely abort trying to start.  This routine is meant to only
61711767SAnurag.Maskey@Sun.COM  * be called once.
61811767SAnurag.Maskey@Sun.COM  */
61911767SAnurag.Maskey@Sun.COM void
nwamd_door_init(void)62011767SAnurag.Maskey@Sun.COM nwamd_door_init(void)
62111767SAnurag.Maskey@Sun.COM {
62211767SAnurag.Maskey@Sun.COM 	const int door_mode = 0644;
62311767SAnurag.Maskey@Sun.COM 	struct stat buf;
62411767SAnurag.Maskey@Sun.COM 
62511767SAnurag.Maskey@Sun.COM 	if ((doorfd = door_create(nwamd_door_switch, NULL,
62611767SAnurag.Maskey@Sun.COM 	    DOOR_NO_CANCEL | DOOR_REFUSE_DESC)) == -1)
62711767SAnurag.Maskey@Sun.COM 		pfail("Unable to create door: %s", strerror(errno));
62811767SAnurag.Maskey@Sun.COM 
62911767SAnurag.Maskey@Sun.COM 	if (stat(NWAM_DOOR, &buf) < 0) {
63011767SAnurag.Maskey@Sun.COM 		int nwam_door_fd;
63111767SAnurag.Maskey@Sun.COM 
63211767SAnurag.Maskey@Sun.COM 		if ((nwam_door_fd = creat(NWAM_DOOR, door_mode)) < 0) {
63311767SAnurag.Maskey@Sun.COM 			int err = errno;
63411767SAnurag.Maskey@Sun.COM 			(void) door_revoke(doorfd);
63511767SAnurag.Maskey@Sun.COM 			doorfd = -1;
63611767SAnurag.Maskey@Sun.COM 			pfail("Couldn't create door: %s", strerror(err));
63711767SAnurag.Maskey@Sun.COM 		}
63811767SAnurag.Maskey@Sun.COM 		(void) close(nwam_door_fd);
63911767SAnurag.Maskey@Sun.COM 	} else {
64011767SAnurag.Maskey@Sun.COM 		if (buf.st_mode != door_mode) {
64111767SAnurag.Maskey@Sun.COM 			if (chmod(NWAM_DOOR, door_mode) == -1) {
64211767SAnurag.Maskey@Sun.COM 				nlog(LOG_ERR, "couldn't change mode of %s: %s",
64311767SAnurag.Maskey@Sun.COM 				    NWAM_DOOR, strerror(errno));
64411767SAnurag.Maskey@Sun.COM 			}
64511767SAnurag.Maskey@Sun.COM 		}
64611767SAnurag.Maskey@Sun.COM 	}
64711767SAnurag.Maskey@Sun.COM 	/* cleanup anything hanging around from a previous invocation */
64811767SAnurag.Maskey@Sun.COM 	(void) fdetach(NWAM_DOOR);
64911767SAnurag.Maskey@Sun.COM 
65011767SAnurag.Maskey@Sun.COM 	/* Place our door in the file system so that others can find us. */
65111767SAnurag.Maskey@Sun.COM 	if (fattach(doorfd, NWAM_DOOR) < 0) {
65211767SAnurag.Maskey@Sun.COM 		int err = errno;
65311767SAnurag.Maskey@Sun.COM 		(void) door_revoke(doorfd);
65411767SAnurag.Maskey@Sun.COM 		doorfd = -1;
65511767SAnurag.Maskey@Sun.COM 		pfail("Couldn't attach door: %s", strerror(err));
65611767SAnurag.Maskey@Sun.COM 	}
65711767SAnurag.Maskey@Sun.COM }
65811767SAnurag.Maskey@Sun.COM 
65911767SAnurag.Maskey@Sun.COM void
nwamd_door_fini(void)66011767SAnurag.Maskey@Sun.COM nwamd_door_fini(void)
66111767SAnurag.Maskey@Sun.COM {
66211767SAnurag.Maskey@Sun.COM 	if (doorfd != -1) {
66311767SAnurag.Maskey@Sun.COM 		nlog(LOG_DEBUG, "nwamd_door_fini: closing door");
66411767SAnurag.Maskey@Sun.COM 		(void) door_revoke(doorfd);
66511767SAnurag.Maskey@Sun.COM 		doorfd = -1;
66611767SAnurag.Maskey@Sun.COM 	}
66711767SAnurag.Maskey@Sun.COM 	(void) unlink(NWAM_DOOR);
66811767SAnurag.Maskey@Sun.COM }
669