/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <auth_attr.h>
#include <auth_list.h>
#include <bsm/adt_event.h>
#include <door.h>
#include <errno.h>
#include <fcntl.h>
#include <libnwam_priv.h>
#include <libuutil.h>
#include <pthread.h>
#include <pwd.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include "conditions.h"
#include "events.h"
#include "ncp.h"
#include "ncu.h"
#include "objects.h"
#include "util.h"
/*
* This file contains functions which implement the command interface to
* nwam via the door NWAM_DOOR. Doors provide a LPC mechanism that allows
* for threads in one process to cause code to execute in another process.
* Doors also provide the ability to pass data and file descriptors. See
* libdoor(3LIB) for more information.
*
* This file exports two functions, nwamd_door_initialize() (which sets up
* the door) and nwamd_door_fini(), which removes it.
*
* It sets up the static routine nwamd_door_switch() to be called when a client
* calls the door (via door_call(3C)). The structure nwam_request_t is
* passed as data and contains data to specify the type of action requested
* and any data need to meet that request. A table consisting of entries
* for each door request, the associated authorization and the function to
* process that request is used to handle the various requests.
*/
struct nwamd_door_req_entry
{
int ndre_type;
char *ndre_auth;
};
/*
* This table defines the set of door commands available, the required
* authorizations for each command, and the function that carries out
* each command.
*/
{
/* Requires WRITE, SELECT or WLAN auth depending on action */
};
/* ARGSUSED */
static nwam_error_t
{
if (err != NWAM_SUCCESS) {
"could not register events for %s",
}
return (err);
}
/* ARGSUSED */
static nwam_error_t
{
return (NWAM_SUCCESS);
}
/* ARGSUSED1 */
static nwam_error_t
{
"nwamd_door_req_wlan_scan: processing WLAN scan request: "
}
/* ARGSUSED */
static nwam_error_t
{
"scan results request: link %s",
"nwamd_door_req_wlan_scan_results: link %s not found",
return (NWAM_ENTITY_NOT_FOUND);
}
if (num_wlans > 0) {
(void) memcpy
num_wlans * sizeof (nwam_wlan_t));
}
"nwamd_door_req_wlan_scan_results: returning %d scan results",
return (NWAM_SUCCESS);
}
/* ARGSUSED */
static nwam_error_t
{
"nwamd_door_req_wlan_select: processing WLAN selection : "
"link %s ESSID %s , BSSID %s",
return (nwamd_wlan_select
}
/* ARGSUSED */
static nwam_error_t
{
"nwamd_door_req_wlan_set_key: processing WLAN key input : "
"link %s ESSID %s BSSID %s",
return (nwamd_wlan_set_key
}
static nwam_error_t
{
/* Check for name, parent overrun */
sizeof (name)) == NWAM_MAX_NAME_LEN ||
sizeof (parent)) == NWAM_MAX_NAME_LEN)
return (NWAM_INVALID_ARG);
/*
* Check authorizations against actions.
* - REFRESH on other objects requires either WRITE or SELECT auth
*/
action == NWAM_ACTION_ENABLE ?
"need %s for %s action", AUTOCONF_SELECT_AUTH,
return (NWAM_PERMISSION_DENIED);
}
} else if (object_type == NWAM_OBJECT_TYPE_KNOWN_WLAN) {
"need %s for %s action on Known WLAN",
return (NWAM_PERMISSION_DENIED);
}
"need %s for %s action", AUTOCONF_WRITE_AUTH,
return (NWAM_PERMISSION_DENIED);
}
} else if (action == NWAM_ACTION_REFRESH) {
"need either %s or %s for %s action",
return (NWAM_PERMISSION_DENIED);
}
} else {
return (NWAM_INVALID_ARG);
}
switch (action) {
case NWAM_ACTION_ENABLE:
case NWAM_ACTION_DISABLE:
action == NWAM_ACTION_ENABLE ?
name);
switch (object_type) {
case NWAM_OBJECT_TYPE_ENM:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_NCP:
if (action == NWAM_ACTION_DISABLE) {
"NCPs cannot be disabled");
} else {
}
break;
default:
"object type %d (%s)", object_type,
return (NWAM_INVALID_ARG);
}
break;
case NWAM_ACTION_ADD:
case NWAM_ACTION_REFRESH:
/*
* Called whenever an object is committed in the library.
* Reread that committed object into nwamd.
*/
switch (object_type) {
case NWAM_OBJECT_TYPE_ENM:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
break;
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_NCP:
break;
default:
"object type %d (%s)", object_type,
break;
}
break;
case NWAM_ACTION_DESTROY:
/* Object was destroyed, remove from nwamd */
switch (object_type) {
case NWAM_OBJECT_TYPE_ENM:
break;
case NWAM_OBJECT_TYPE_LOC:
break;
break;
case NWAM_OBJECT_TYPE_NCU:
break;
case NWAM_OBJECT_TYPE_NCP:
(void) pthread_mutex_lock(&active_ncp_mutex);
"active, cannot destroy", parent);
} else {
}
(void) pthread_mutex_unlock(&active_ncp_mutex);
break;
default:
"object type %d (%s)", object_type,
break;
}
break;
default:
break;
}
if (err == NWAM_SUCCESS) {
/*
* At this point, we've successfully carried out an action.
* Configuration may have changed, so we need to recheck
* conditions, however we want to avoid a flurry of condition
* check events, so we enqueue a triggered condition check
* if none is due in the next few seconds.
*/
} else {
}
return (err);
}
/* ARGSUSED */
static nwam_error_t
{
/* Check for name, parent overrun */
sizeof (name)) == NWAM_MAX_NAME_LEN)
return (NWAM_INVALID_ARG);
switch (object_type) {
case NWAM_OBJECT_TYPE_NCP:
(void) pthread_mutex_lock(&active_ncp_mutex);
(void) pthread_mutex_unlock(&active_ncp_mutex);
if (is_active) {
"nwamd_door_req_state: NCP %s is active", name);
} else {
"NCP %s is inactive", name);
}
break;
case NWAM_OBJECT_TYPE_LOC:
case NWAM_OBJECT_TYPE_NCU:
case NWAM_OBJECT_TYPE_ENM:
return (NWAM_ENTITY_NOT_FOUND);
}
break;
default:
"object type %d (%s)", object_type,
return (NWAM_INVALID_ARG);
}
return (NWAM_SUCCESS);
}
/* ARGSUSED */
static nwam_error_t
{
(void) pthread_mutex_lock(&active_ncp_mutex);
"retrieving active priority-group: %d",
(void) pthread_mutex_unlock(&active_ncp_mutex);
return (NWAM_SUCCESS);
}
/* ARGSUSED */
static void
{
int i;
/* LINTED E_BAD_PTR_CAST_ALIGN */
if (door_ucred(&ucr) != 0) {
goto done;
}
endpwent();
goto done;
}
/*
* Find door request entry in table, check auths and call the function
* handling the request.
*/
for (i = 0;
i < sizeof (door_req_table) / sizeof (struct nwamd_door_req_entry);
i++) {
continue;
"nwamd_door_switch: need %s for request type %d",
break;
}
break;
}
if (!found) {
"nwamd_door_switch: received unknown request type %d",
} else {
else
}
done:
endpwent();
== -1) {
}
}
/*
* We initialize the nwamd door here. Failure to have this happen is critical
* to the daemon so we log a message and pass up notice to the caller who
* will most likely abort trying to start. This routine is meant to only
* be called once.
*/
void
nwamd_door_init(void)
{
int nwam_door_fd;
(void) door_revoke(doorfd);
doorfd = -1;
}
(void) close(nwam_door_fd);
} else {
}
}
}
/* cleanup anything hanging around from a previous invocation */
/* Place our door in the file system so that others can find us. */
(void) door_revoke(doorfd);
doorfd = -1;
}
}
void
nwamd_door_fini(void)
{
if (doorfd != -1) {
(void) door_revoke(doorfd);
doorfd = -1;
}
}