1*6ba597c5SAnurag S. Maskey /*
2*6ba597c5SAnurag S. Maskey  * CDDL HEADER START
3*6ba597c5SAnurag S. Maskey  *
4*6ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
5*6ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
6*6ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
7*6ba597c5SAnurag S. Maskey  *
8*6ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
10*6ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
11*6ba597c5SAnurag S. Maskey  * and limitations under the License.
12*6ba597c5SAnurag S. Maskey  *
13*6ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
14*6ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
16*6ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
17*6ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6ba597c5SAnurag S. Maskey  *
19*6ba597c5SAnurag S. Maskey  * CDDL HEADER END
20*6ba597c5SAnurag S. Maskey  */
21*6ba597c5SAnurag S. Maskey 
22*6ba597c5SAnurag S. Maskey /*
23*6ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*6ba597c5SAnurag S. Maskey  * Use is subject to license terms.
25*6ba597c5SAnurag S. Maskey  */
26*6ba597c5SAnurag S. Maskey 
27*6ba597c5SAnurag S. Maskey #include <assert.h>
28*6ba597c5SAnurag S. Maskey #include <auth_attr.h>
29*6ba597c5SAnurag S. Maskey #include <auth_list.h>
30*6ba597c5SAnurag S. Maskey #include <bsm/adt.h>
31*6ba597c5SAnurag S. Maskey #include <bsm/adt_event.h>
32*6ba597c5SAnurag S. Maskey #include <ctype.h>
33*6ba597c5SAnurag S. Maskey #include <errno.h>
34*6ba597c5SAnurag S. Maskey #include <fcntl.h>
35*6ba597c5SAnurag S. Maskey #include <libgen.h>
36*6ba597c5SAnurag S. Maskey #include <pwd.h>
37*6ba597c5SAnurag S. Maskey #include <secdb.h>
38*6ba597c5SAnurag S. Maskey #include <stdlib.h>
39*6ba597c5SAnurag S. Maskey #include <sys/param.h>
40*6ba597c5SAnurag S. Maskey #include <sys/types.h>
41*6ba597c5SAnurag S. Maskey #include <sys/stat.h>
42*6ba597c5SAnurag S. Maskey #include <stdio.h>
43*6ba597c5SAnurag S. Maskey #include <strings.h>
44*6ba597c5SAnurag S. Maskey #include <unistd.h>
45*6ba597c5SAnurag S. Maskey 
46*6ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
47*6ba597c5SAnurag S. Maskey #include <libnwam_priv.h>
48*6ba597c5SAnurag S. Maskey #include <libnwam.h>
49*6ba597c5SAnurag S. Maskey 
50*6ba597c5SAnurag S. Maskey /*
51*6ba597c5SAnurag S. Maskey  * Communicate with and implement library backend (running in netcfgd) to
52*6ba597c5SAnurag S. Maskey  * retrieve or change NWAM configuration.
53*6ba597c5SAnurag S. Maskey  */
54*6ba597c5SAnurag S. Maskey 
55*6ba597c5SAnurag S. Maskey static int backend_door_client_fd = -1;
56*6ba597c5SAnurag S. Maskey 
57*6ba597c5SAnurag S. Maskey /*
58*6ba597c5SAnurag S. Maskey  * Check if uid has proper auths.  flags is used to check auths for
59*6ba597c5SAnurag S. Maskey  * enable/disable of profiles and manipulation of Known WLANs.
60*6ba597c5SAnurag S. Maskey  */
61*6ba597c5SAnurag S. Maskey static nwam_error_t
nwam_check_auths(uid_t uid,boolean_t write,uint64_t flags)62*6ba597c5SAnurag S. Maskey nwam_check_auths(uid_t uid, boolean_t write, uint64_t flags)
63*6ba597c5SAnurag S. Maskey {
64*6ba597c5SAnurag S. Maskey 	struct passwd *pwd;
65*6ba597c5SAnurag S. Maskey 	nwam_error_t err = NWAM_SUCCESS;
66*6ba597c5SAnurag S. Maskey 
67*6ba597c5SAnurag S. Maskey 	if ((pwd = getpwuid(uid)) == NULL) {
68*6ba597c5SAnurag S. Maskey 		endpwent();
69*6ba597c5SAnurag S. Maskey 		return (NWAM_PERMISSION_DENIED);
70*6ba597c5SAnurag S. Maskey 	}
71*6ba597c5SAnurag S. Maskey 
72*6ba597c5SAnurag S. Maskey 	if (flags & NWAM_FLAG_ENTITY_ENABLE) {
73*6ba597c5SAnurag S. Maskey 		/* Enabling/disabling profile - need SELECT auth */
74*6ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_SELECT_AUTH, pwd->pw_name) == 0)
75*6ba597c5SAnurag S. Maskey 			err = NWAM_PERMISSION_DENIED;
76*6ba597c5SAnurag S. Maskey 
77*6ba597c5SAnurag S. Maskey 	} else if (flags & NWAM_FLAG_ENTITY_KNOWN_WLAN) {
78*6ba597c5SAnurag S. Maskey 		/* Known WLAN activity - need WLAN auth */
79*6ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_WLAN_AUTH, pwd->pw_name) == 0)
80*6ba597c5SAnurag S. Maskey 			err = NWAM_PERMISSION_DENIED;
81*6ba597c5SAnurag S. Maskey 
82*6ba597c5SAnurag S. Maskey 	} else {
83*6ba597c5SAnurag S. Maskey 		/*
84*6ba597c5SAnurag S. Maskey 		 * First, check for WRITE, since it implies READ.  If this
85*6ba597c5SAnurag S. Maskey 		 * auth is not present, and write is true, fail, otherwise
86*6ba597c5SAnurag S. Maskey 		 * check for READ.
87*6ba597c5SAnurag S. Maskey 		 */
88*6ba597c5SAnurag S. Maskey 		if (chkauthattr(AUTOCONF_WRITE_AUTH, pwd->pw_name) == 0) {
89*6ba597c5SAnurag S. Maskey 			if (write) {
90*6ba597c5SAnurag S. Maskey 				err = NWAM_PERMISSION_DENIED;
91*6ba597c5SAnurag S. Maskey 			} else {
92*6ba597c5SAnurag S. Maskey 				if (chkauthattr(AUTOCONF_READ_AUTH,
93*6ba597c5SAnurag S. Maskey 				    pwd->pw_name) == 0)
94*6ba597c5SAnurag S. Maskey 					err = NWAM_PERMISSION_DENIED;
95*6ba597c5SAnurag S. Maskey 			}
96*6ba597c5SAnurag S. Maskey 		}
97*6ba597c5SAnurag S. Maskey 	}
98*6ba597c5SAnurag S. Maskey 
99*6ba597c5SAnurag S. Maskey 	endpwent();
100*6ba597c5SAnurag S. Maskey 	return (err);
101*6ba597c5SAnurag S. Maskey }
102*6ba597c5SAnurag S. Maskey 
103*6ba597c5SAnurag S. Maskey static nwam_error_t
nwam_create_backend_door_arg(nwam_backend_door_cmd_t cmd,const char * dbname,const char * objname,uint64_t flags,void * obj,nwam_backend_door_arg_t * arg)104*6ba597c5SAnurag S. Maskey nwam_create_backend_door_arg(nwam_backend_door_cmd_t cmd,
105*6ba597c5SAnurag S. Maskey     const char *dbname, const char *objname, uint64_t flags,
106*6ba597c5SAnurag S. Maskey     void *obj, nwam_backend_door_arg_t *arg)
107*6ba597c5SAnurag S. Maskey {
108*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
109*6ba597c5SAnurag S. Maskey 	size_t datalen = 0;
110*6ba597c5SAnurag S. Maskey 	caddr_t dataptr;
111*6ba597c5SAnurag S. Maskey 
112*6ba597c5SAnurag S. Maskey 	switch (cmd) {
113*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_READ_REQ:
114*6ba597c5SAnurag S. Maskey 		/*
115*6ba597c5SAnurag S. Maskey 		 * For a read request,  we want the full buffer to be
116*6ba597c5SAnurag S. Maskey 		 * available for the backend door to write to.
117*6ba597c5SAnurag S. Maskey 		 */
118*6ba597c5SAnurag S. Maskey 		datalen = NWAM_BACKEND_DOOR_ARG_SIZE;
119*6ba597c5SAnurag S. Maskey 		break;
120*6ba597c5SAnurag S. Maskey 
121*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_UPDATE_REQ:
122*6ba597c5SAnurag S. Maskey 		/*
123*6ba597c5SAnurag S. Maskey 		 * An update request may either specify an object list
124*6ba597c5SAnurag S. Maskey 		 * (which we pack into the buffer immediately after the
125*6ba597c5SAnurag S. Maskey 		 * backend door request) or may not specify an object
126*6ba597c5SAnurag S. Maskey 		 * (signifying a request to create the container of the
127*6ba597c5SAnurag S. Maskey 		 * object).
128*6ba597c5SAnurag S. Maskey 		 */
129*6ba597c5SAnurag S. Maskey 		if (obj == NULL) {
130*6ba597c5SAnurag S. Maskey 			datalen = 0;
131*6ba597c5SAnurag S. Maskey 			break;
132*6ba597c5SAnurag S. Maskey 		}
133*6ba597c5SAnurag S. Maskey 		/* Data immediately follows the descriptor */
134*6ba597c5SAnurag S. Maskey 		dataptr = (caddr_t)arg + sizeof (nwam_backend_door_arg_t);
135*6ba597c5SAnurag S. Maskey 		datalen = NWAM_BACKEND_DOOR_ARG_SIZE;
136*6ba597c5SAnurag S. Maskey 		/* pack object list for update request,  adjusting datalen */
137*6ba597c5SAnurag S. Maskey 		if ((err = nwam_pack_object_list(obj, (char **)&dataptr,
138*6ba597c5SAnurag S. Maskey 		    &datalen)) != NWAM_SUCCESS)
139*6ba597c5SAnurag S. Maskey 			return (err);
140*6ba597c5SAnurag S. Maskey 		break;
141*6ba597c5SAnurag S. Maskey 
142*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_REMOVE_REQ:
143*6ba597c5SAnurag S. Maskey 		/* A remove request has no associated object list. */
144*6ba597c5SAnurag S. Maskey 		datalen = 0;
145*6ba597c5SAnurag S. Maskey 		break;
146*6ba597c5SAnurag S. Maskey 
147*6ba597c5SAnurag S. Maskey 	default:
148*6ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
149*6ba597c5SAnurag S. Maskey 	}
150*6ba597c5SAnurag S. Maskey 
151*6ba597c5SAnurag S. Maskey 	arg->nwbda_cmd = cmd;
152*6ba597c5SAnurag S. Maskey 	arg->nwbda_flags = flags;
153*6ba597c5SAnurag S. Maskey 	arg->nwbda_datalen = datalen;
154*6ba597c5SAnurag S. Maskey 	arg->nwbda_result = NWAM_SUCCESS;
155*6ba597c5SAnurag S. Maskey 
156*6ba597c5SAnurag S. Maskey 	if (dbname != NULL)
157*6ba597c5SAnurag S. Maskey 		(void) strlcpy(arg->nwbda_dbname, dbname, MAXPATHLEN);
158*6ba597c5SAnurag S. Maskey 	else
159*6ba597c5SAnurag S. Maskey 		arg->nwbda_dbname[0] = '\0';
160*6ba597c5SAnurag S. Maskey 
161*6ba597c5SAnurag S. Maskey 	if (objname != NULL)
162*6ba597c5SAnurag S. Maskey 		(void) strlcpy(arg->nwbda_object, objname, NWAM_MAX_NAME_LEN);
163*6ba597c5SAnurag S. Maskey 	else
164*6ba597c5SAnurag S. Maskey 		arg->nwbda_object[0] = '\0';
165*6ba597c5SAnurag S. Maskey 
166*6ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
167*6ba597c5SAnurag S. Maskey }
168*6ba597c5SAnurag S. Maskey 
169*6ba597c5SAnurag S. Maskey /*
170*6ba597c5SAnurag S. Maskey  * If the arg datalen is non-zero,  unpack the object list associated with
171*6ba597c5SAnurag S. Maskey  * the backend door argument.
172*6ba597c5SAnurag S. Maskey  */
173*6ba597c5SAnurag S. Maskey static nwam_error_t
nwam_read_object_from_backend_door_arg(nwam_backend_door_arg_t * arg,char * dbname,char * name,void * objp)174*6ba597c5SAnurag S. Maskey nwam_read_object_from_backend_door_arg(nwam_backend_door_arg_t *arg,
175*6ba597c5SAnurag S. Maskey     char *dbname, char *name, void *objp)
176*6ba597c5SAnurag S. Maskey {
177*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
178*6ba597c5SAnurag S. Maskey 	caddr_t dataptr = (caddr_t)arg + sizeof (nwam_backend_door_arg_t);
179*6ba597c5SAnurag S. Maskey 
180*6ba597c5SAnurag S. Maskey 	if (arg->nwbda_result != NWAM_SUCCESS)
181*6ba597c5SAnurag S. Maskey 		return (arg->nwbda_result);
182*6ba597c5SAnurag S. Maskey 
183*6ba597c5SAnurag S. Maskey 	if (arg->nwbda_datalen > 0) {
184*6ba597c5SAnurag S. Maskey 		if ((err = nwam_unpack_object_list((char *)dataptr,
185*6ba597c5SAnurag S. Maskey 		    arg->nwbda_datalen, objp)) != NWAM_SUCCESS)
186*6ba597c5SAnurag S. Maskey 			return (err);
187*6ba597c5SAnurag S. Maskey 	} else {
188*6ba597c5SAnurag S. Maskey 		*((char **)objp) = NULL;
189*6ba597c5SAnurag S. Maskey 	}
190*6ba597c5SAnurag S. Maskey 
191*6ba597c5SAnurag S. Maskey 	/*
192*6ba597c5SAnurag S. Maskey 	 * If "dbname" and "name" are non-NULL, copy in the actual dbname
193*6ba597c5SAnurag S. Maskey 	 * and name values from the door arg since both may have been changed
194*6ba597c5SAnurag S. Maskey 	 * from case-insensitive to case-sensitive matches.  They will be the
195*6ba597c5SAnurag S. Maskey 	 * same length as they only differ in case.
196*6ba597c5SAnurag S. Maskey 	 */
197*6ba597c5SAnurag S. Maskey 	if (dbname != NULL && strcmp(dbname, arg->nwbda_dbname) != 0)
198*6ba597c5SAnurag S. Maskey 		(void) strlcpy(dbname, arg->nwbda_dbname, strlen(dbname) + 1);
199*6ba597c5SAnurag S. Maskey 	if (name != NULL && strcmp(name, arg->nwbda_object) != 0)
200*6ba597c5SAnurag S. Maskey 		(void) strlcpy(name, arg->nwbda_object, strlen(name) + 1);
201*6ba597c5SAnurag S. Maskey 
202*6ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
203*6ba597c5SAnurag S. Maskey }
204*6ba597c5SAnurag S. Maskey 
205*6ba597c5SAnurag S. Maskey /* ARGSUSED */
206*6ba597c5SAnurag S. Maskey void
nwam_backend_door_server(void * cookie,char * arg,size_t arg_size,door_desc_t * dp,uint_t ndesc)207*6ba597c5SAnurag S. Maskey nwam_backend_door_server(void *cookie, char *arg, size_t arg_size,
208*6ba597c5SAnurag S. Maskey     door_desc_t *dp, uint_t ndesc)
209*6ba597c5SAnurag S. Maskey {
210*6ba597c5SAnurag S. Maskey 	/* LINTED: alignment */
211*6ba597c5SAnurag S. Maskey 	nwam_backend_door_arg_t *req = (nwam_backend_door_arg_t *)arg;
212*6ba597c5SAnurag S. Maskey 	nwam_error_t err;
213*6ba597c5SAnurag S. Maskey 	void *obj, *newobj = NULL;
214*6ba597c5SAnurag S. Maskey 	ucred_t *ucr = NULL;
215*6ba597c5SAnurag S. Maskey 	uid_t uid;
216*6ba597c5SAnurag S. Maskey 	boolean_t write = B_TRUE;
217*6ba597c5SAnurag S. Maskey 
218*6ba597c5SAnurag S. Maskey 	/* Check arg size */
219*6ba597c5SAnurag S. Maskey 	if (arg_size < sizeof (nwam_backend_door_arg_t)) {
220*6ba597c5SAnurag S. Maskey 		req->nwbda_result = NWAM_INVALID_ARG;
221*6ba597c5SAnurag S. Maskey 		(void) door_return((char *)req,
222*6ba597c5SAnurag S. Maskey 		    sizeof (nwam_backend_door_arg_t), NULL, 0);
223*6ba597c5SAnurag S. Maskey 	}
224*6ba597c5SAnurag S. Maskey 
225*6ba597c5SAnurag S. Maskey 	if (door_ucred(&ucr) != 0) {
226*6ba597c5SAnurag S. Maskey 		req->nwbda_result = NWAM_ERROR_INTERNAL;
227*6ba597c5SAnurag S. Maskey 		(void) door_return((char *)req, arg_size, NULL, 0);
228*6ba597c5SAnurag S. Maskey 	}
229*6ba597c5SAnurag S. Maskey 
230*6ba597c5SAnurag S. Maskey 	/* Check auths */
231*6ba597c5SAnurag S. Maskey 	uid = ucred_getruid(ucr);
232*6ba597c5SAnurag S. Maskey 
233*6ba597c5SAnurag S. Maskey 	if (req->nwbda_cmd == NWAM_BACKEND_DOOR_CMD_READ_REQ)
234*6ba597c5SAnurag S. Maskey 		write = B_FALSE;
235*6ba597c5SAnurag S. Maskey 	if ((err = nwam_check_auths(uid, write, req->nwbda_flags))
236*6ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS) {
237*6ba597c5SAnurag S. Maskey 		if (write) {
238*6ba597c5SAnurag S. Maskey 			nwam_record_audit_event(ucr,
239*6ba597c5SAnurag S. Maskey 			    req->nwbda_cmd == NWAM_BACKEND_DOOR_CMD_UPDATE_REQ ?
240*6ba597c5SAnurag S. Maskey 			    ADT_netcfg_update : ADT_netcfg_remove,
241*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_object,
242*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_dbname, ADT_FAILURE,
243*6ba597c5SAnurag S. Maskey 			    ADT_FAIL_VALUE_AUTH);
244*6ba597c5SAnurag S. Maskey 		}
245*6ba597c5SAnurag S. Maskey 		req->nwbda_result = err;
246*6ba597c5SAnurag S. Maskey 		goto door_return;
247*6ba597c5SAnurag S. Maskey 	}
248*6ba597c5SAnurag S. Maskey 
249*6ba597c5SAnurag S. Maskey 	switch (req->nwbda_cmd) {
250*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_READ_REQ:
251*6ba597c5SAnurag S. Maskey 		if ((req->nwbda_result = nwam_read_object_from_files_backend
252*6ba597c5SAnurag S. Maskey 		    (strlen(req->nwbda_dbname) > 0 ? req->nwbda_dbname : NULL,
253*6ba597c5SAnurag S. Maskey 		    strlen(req->nwbda_object) > 0 ? req->nwbda_object : NULL,
254*6ba597c5SAnurag S. Maskey 		    req->nwbda_flags, &newobj)) != NWAM_SUCCESS) {
255*6ba597c5SAnurag S. Maskey 			break;
256*6ba597c5SAnurag S. Maskey 		}
257*6ba597c5SAnurag S. Maskey 		if (newobj != NULL) {
258*6ba597c5SAnurag S. Maskey 			size_t datalen = arg_size -
259*6ba597c5SAnurag S. Maskey 			    sizeof (nwam_backend_door_arg_t);
260*6ba597c5SAnurag S. Maskey 			caddr_t dataptr = (caddr_t)req +
261*6ba597c5SAnurag S. Maskey 			    sizeof (nwam_backend_door_arg_t);
262*6ba597c5SAnurag S. Maskey 
263*6ba597c5SAnurag S. Maskey 			if ((req->nwbda_result = nwam_pack_object_list(newobj,
264*6ba597c5SAnurag S. Maskey 			    (char **)&dataptr, &datalen)) != NWAM_SUCCESS)
265*6ba597c5SAnurag S. Maskey 				req->nwbda_datalen = 0;
266*6ba597c5SAnurag S. Maskey 			else
267*6ba597c5SAnurag S. Maskey 				req->nwbda_datalen = datalen;
268*6ba597c5SAnurag S. Maskey 			nwam_free_object_list(newobj);
269*6ba597c5SAnurag S. Maskey 		} else {
270*6ba597c5SAnurag S. Maskey 			req->nwbda_datalen = 0;
271*6ba597c5SAnurag S. Maskey 		}
272*6ba597c5SAnurag S. Maskey 		break;
273*6ba597c5SAnurag S. Maskey 
274*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_UPDATE_REQ:
275*6ba597c5SAnurag S. Maskey 		if (req->nwbda_datalen == 0) {
276*6ba597c5SAnurag S. Maskey 			obj = NULL;
277*6ba597c5SAnurag S. Maskey 		} else {
278*6ba597c5SAnurag S. Maskey 			if ((req->nwbda_result =
279*6ba597c5SAnurag S. Maskey 			    nwam_read_object_from_backend_door_arg
280*6ba597c5SAnurag S. Maskey 			    (req, NULL, NULL, &obj)) != NWAM_SUCCESS)
281*6ba597c5SAnurag S. Maskey 				break;
282*6ba597c5SAnurag S. Maskey 		}
283*6ba597c5SAnurag S. Maskey 		req->nwbda_result = nwam_update_object_in_files_backend(
284*6ba597c5SAnurag S. Maskey 		    req->nwbda_dbname[0] == 0 ? NULL : req->nwbda_dbname,
285*6ba597c5SAnurag S. Maskey 		    req->nwbda_object[0] == 0 ? NULL : req->nwbda_object,
286*6ba597c5SAnurag S. Maskey 		    req->nwbda_flags, obj);
287*6ba597c5SAnurag S. Maskey 		nwam_free_object_list(obj);
288*6ba597c5SAnurag S. Maskey 		if (req->nwbda_result == NWAM_SUCCESS) {
289*6ba597c5SAnurag S. Maskey 			req->nwbda_datalen = 0;
290*6ba597c5SAnurag S. Maskey 			nwam_record_audit_event(ucr, ADT_netcfg_update,
291*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_object,
292*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_dbname, ADT_SUCCESS,
293*6ba597c5SAnurag S. Maskey 			    ADT_SUCCESS);
294*6ba597c5SAnurag S. Maskey 		}
295*6ba597c5SAnurag S. Maskey 		break;
296*6ba597c5SAnurag S. Maskey 
297*6ba597c5SAnurag S. Maskey 	case NWAM_BACKEND_DOOR_CMD_REMOVE_REQ:
298*6ba597c5SAnurag S. Maskey 		req->nwbda_result = nwam_remove_object_from_files_backend
299*6ba597c5SAnurag S. Maskey 		    (strlen(req->nwbda_dbname) > 0 ? req->nwbda_dbname : NULL,
300*6ba597c5SAnurag S. Maskey 		    strlen(req->nwbda_object) > 0 ? req->nwbda_object : NULL,
301*6ba597c5SAnurag S. Maskey 		    req->nwbda_flags);
302*6ba597c5SAnurag S. Maskey 		if (req->nwbda_result == NWAM_SUCCESS) {
303*6ba597c5SAnurag S. Maskey 			nwam_record_audit_event(ucr, ADT_netcfg_update,
304*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_object,
305*6ba597c5SAnurag S. Maskey 			    (char *)req->nwbda_dbname, ADT_SUCCESS,
306*6ba597c5SAnurag S. Maskey 			    ADT_SUCCESS);
307*6ba597c5SAnurag S. Maskey 		}
308*6ba597c5SAnurag S. Maskey 		break;
309*6ba597c5SAnurag S. Maskey 
310*6ba597c5SAnurag S. Maskey 	default:
311*6ba597c5SAnurag S. Maskey 		req->nwbda_result = NWAM_INVALID_ARG;
312*6ba597c5SAnurag S. Maskey 		break;
313*6ba597c5SAnurag S. Maskey 	}
314*6ba597c5SAnurag S. Maskey 
315*6ba597c5SAnurag S. Maskey door_return:
316*6ba597c5SAnurag S. Maskey 	ucred_free(ucr);
317*6ba597c5SAnurag S. Maskey 
318*6ba597c5SAnurag S. Maskey 	(void) door_return((char *)req, arg_size, NULL, 0);
319*6ba597c5SAnurag S. Maskey }
320*6ba597c5SAnurag S. Maskey 
321*6ba597c5SAnurag S. Maskey static int backend_door_fd = -1;
322*6ba597c5SAnurag S. Maskey 
323*6ba597c5SAnurag S. Maskey void
nwam_backend_fini(void)324*6ba597c5SAnurag S. Maskey nwam_backend_fini(void)
325*6ba597c5SAnurag S. Maskey {
326*6ba597c5SAnurag S. Maskey 	if (backend_door_fd != -1) {
327*6ba597c5SAnurag S. Maskey 		(void) door_revoke(backend_door_fd);
328*6ba597c5SAnurag S. Maskey 		backend_door_fd = -1;
329*6ba597c5SAnurag S. Maskey 	}
330*6ba597c5SAnurag S. Maskey 	(void) unlink(NWAM_BACKEND_DOOR_FILE);
331*6ba597c5SAnurag S. Maskey }
332*6ba597c5SAnurag S. Maskey 
333*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_backend_init(void)334*6ba597c5SAnurag S. Maskey nwam_backend_init(void)
335*6ba597c5SAnurag S. Maskey {
336*6ba597c5SAnurag S. Maskey 	int did;
337*6ba597c5SAnurag S. Maskey 	struct stat statbuf;
338*6ba597c5SAnurag S. Maskey 
339*6ba597c5SAnurag S. Maskey 	/* Create the door directory if it doesn't already exist */
340*6ba597c5SAnurag S. Maskey 	if (stat(NWAM_DOOR_DIR, &statbuf) < 0) {
341*6ba597c5SAnurag S. Maskey 		if (mkdir(NWAM_DOOR_DIR, (mode_t)0755) < 0)
342*6ba597c5SAnurag S. Maskey 			return (NWAM_ERROR_BACKEND_INIT);
343*6ba597c5SAnurag S. Maskey 	} else {
344*6ba597c5SAnurag S. Maskey 		if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
345*6ba597c5SAnurag S. Maskey 			return (NWAM_ERROR_BACKEND_INIT);
346*6ba597c5SAnurag S. Maskey 	}
347*6ba597c5SAnurag S. Maskey 
348*6ba597c5SAnurag S. Maskey 	if (chmod(NWAM_DOOR_DIR, 0755) < 0 ||
349*6ba597c5SAnurag S. Maskey 	    chown(NWAM_DOOR_DIR, UID_NETADM, GID_NETADM) < 0)
350*6ba597c5SAnurag S. Maskey 		return (NWAM_ERROR_BACKEND_INIT);
351*6ba597c5SAnurag S. Maskey 
352*6ba597c5SAnurag S. Maskey 	/* Do a low-overhead "touch" on the file that will be the door node. */
353*6ba597c5SAnurag S. Maskey 	did = open(NWAM_BACKEND_DOOR_FILE,
354*6ba597c5SAnurag S. Maskey 	    O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_NONBLOCK,
355*6ba597c5SAnurag S. Maskey 	    S_IRUSR | S_IRGRP | S_IROTH);
356*6ba597c5SAnurag S. Maskey 
357*6ba597c5SAnurag S. Maskey 	if (did != -1)
358*6ba597c5SAnurag S. Maskey 		(void) close(did);
359*6ba597c5SAnurag S. Maskey 	else if (errno != EEXIST)
360*6ba597c5SAnurag S. Maskey 		return (NWAM_ERROR_BACKEND_INIT);
361*6ba597c5SAnurag S. Maskey 
362*6ba597c5SAnurag S. Maskey 	/* Create the door. */
363*6ba597c5SAnurag S. Maskey 	backend_door_fd = door_create(nwam_backend_door_server, NULL,
364*6ba597c5SAnurag S. Maskey 	    DOOR_REFUSE_DESC);
365*6ba597c5SAnurag S. Maskey 	if (backend_door_fd == -1)
366*6ba597c5SAnurag S. Maskey 		return (NWAM_ERROR_BACKEND_INIT);
367*6ba597c5SAnurag S. Maskey 
368*6ba597c5SAnurag S. Maskey 	/* Attach the door to the file. */
369*6ba597c5SAnurag S. Maskey 	(void) fdetach(NWAM_BACKEND_DOOR_FILE);
370*6ba597c5SAnurag S. Maskey 	if (fattach(backend_door_fd, NWAM_BACKEND_DOOR_FILE) == -1) {
371*6ba597c5SAnurag S. Maskey 		(void) door_revoke(backend_door_fd);
372*6ba597c5SAnurag S. Maskey 		return (NWAM_ERROR_BACKEND_INIT);
373*6ba597c5SAnurag S. Maskey 	}
374*6ba597c5SAnurag S. Maskey 
375*6ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
376*6ba597c5SAnurag S. Maskey }
377*6ba597c5SAnurag S. Maskey 
378*6ba597c5SAnurag S. Maskey static nwam_error_t
nwam_backend_door_call(nwam_backend_door_cmd_t cmd,char * dbname,char * objname,uint64_t flags,void * obj)379*6ba597c5SAnurag S. Maskey nwam_backend_door_call(nwam_backend_door_cmd_t cmd, char *dbname,
380*6ba597c5SAnurag S. Maskey     char *objname, uint64_t flags, void *obj)
381*6ba597c5SAnurag S. Maskey {
382*6ba597c5SAnurag S. Maskey 	uchar_t reqbuf[NWAM_BACKEND_DOOR_ARG_SIZE];
383*6ba597c5SAnurag S. Maskey 	/* LINTED: alignment */
384*6ba597c5SAnurag S. Maskey 	nwam_backend_door_arg_t *req = (nwam_backend_door_arg_t *)&reqbuf;
385*6ba597c5SAnurag S. Maskey 	nwam_error_t err, reserr;
386*6ba597c5SAnurag S. Maskey 
387*6ba597c5SAnurag S. Maskey 	if ((err = nwam_create_backend_door_arg(cmd, dbname, objname, flags,
388*6ba597c5SAnurag S. Maskey 	    obj, req)) != NWAM_SUCCESS)
389*6ba597c5SAnurag S. Maskey 		return (err);
390*6ba597c5SAnurag S. Maskey 
391*6ba597c5SAnurag S. Maskey 	if (nwam_make_door_call(NWAM_BACKEND_DOOR_FILE, &backend_door_client_fd,
392*6ba597c5SAnurag S. Maskey 	    req, sizeof (reqbuf)) != 0)
393*6ba597c5SAnurag S. Maskey 		return (NWAM_ERROR_BIND);
394*6ba597c5SAnurag S. Maskey 
395*6ba597c5SAnurag S. Maskey 	reserr = req->nwbda_result;
396*6ba597c5SAnurag S. Maskey 
397*6ba597c5SAnurag S. Maskey 	if (cmd == NWAM_BACKEND_DOOR_CMD_READ_REQ) {
398*6ba597c5SAnurag S. Maskey 		err = nwam_read_object_from_backend_door_arg(req, dbname,
399*6ba597c5SAnurag S. Maskey 		    objname, obj);
400*6ba597c5SAnurag S. Maskey 	}
401*6ba597c5SAnurag S. Maskey 
402*6ba597c5SAnurag S. Maskey 	return (err == NWAM_SUCCESS ? reserr : err);
403*6ba597c5SAnurag S. Maskey }
404*6ba597c5SAnurag S. Maskey 
405*6ba597c5SAnurag S. Maskey /*
406*6ba597c5SAnurag S. Maskey  * Read object specified by objname from backend dbname, retrieving an object
407*6ba597c5SAnurag S. Maskey  * list representation.
408*6ba597c5SAnurag S. Maskey  *
409*6ba597c5SAnurag S. Maskey  * If dbname is NULL, obj is a list of string arrays consisting of the list
410*6ba597c5SAnurag S. Maskey  * of backend dbnames.
411*6ba597c5SAnurag S. Maskey  *
412*6ba597c5SAnurag S. Maskey  * If objname is NULL, read all objects in the specified dbname and create
413*6ba597c5SAnurag S. Maskey  * an object list containing a string array which represents each object.
414*6ba597c5SAnurag S. Maskey  *
415*6ba597c5SAnurag S. Maskey  * Otherwise obj will point to a list of the properties for the object
416*6ba597c5SAnurag S. Maskey  * specified by objname in the backend dbname.
417*6ba597c5SAnurag S. Maskey  */
418*6ba597c5SAnurag S. Maskey /* ARGSUSED2 */
419*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_read_object_from_backend(char * dbname,char * objname,uint64_t flags,void * obj)420*6ba597c5SAnurag S. Maskey nwam_read_object_from_backend(char *dbname, char *objname,
421*6ba597c5SAnurag S. Maskey     uint64_t flags, void *obj)
422*6ba597c5SAnurag S. Maskey {
423*6ba597c5SAnurag S. Maskey 	nwam_error_t err = nwam_check_auths(getuid(), B_FALSE, flags);
424*6ba597c5SAnurag S. Maskey 
425*6ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
426*6ba597c5SAnurag S. Maskey 		return (err);
427*6ba597c5SAnurag S. Maskey 
428*6ba597c5SAnurag S. Maskey 	return (nwam_backend_door_call(NWAM_BACKEND_DOOR_CMD_READ_REQ,
429*6ba597c5SAnurag S. Maskey 	    dbname, objname, flags, obj));
430*6ba597c5SAnurag S. Maskey }
431*6ba597c5SAnurag S. Maskey 
432*6ba597c5SAnurag S. Maskey /*
433*6ba597c5SAnurag S. Maskey  * Read in all objects from backend dbname and update object corresponding
434*6ba597c5SAnurag S. Maskey  * to objname with properties recorded in proplist, writing the results to
435*6ba597c5SAnurag S. Maskey  * the backend dbname.
436*6ba597c5SAnurag S. Maskey  */
437*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_update_object_in_backend(char * dbname,char * objname,uint64_t flags,void * obj)438*6ba597c5SAnurag S. Maskey nwam_update_object_in_backend(char *dbname, char *objname,
439*6ba597c5SAnurag S. Maskey     uint64_t flags, void *obj)
440*6ba597c5SAnurag S. Maskey {
441*6ba597c5SAnurag S. Maskey 	nwam_error_t err = nwam_check_auths(getuid(), B_TRUE, flags);
442*6ba597c5SAnurag S. Maskey 
443*6ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
444*6ba597c5SAnurag S. Maskey 		return (err);
445*6ba597c5SAnurag S. Maskey 
446*6ba597c5SAnurag S. Maskey 	return (nwam_backend_door_call(NWAM_BACKEND_DOOR_CMD_UPDATE_REQ,
447*6ba597c5SAnurag S. Maskey 	    dbname, objname, flags, obj));
448*6ba597c5SAnurag S. Maskey }
449*6ba597c5SAnurag S. Maskey 
450*6ba597c5SAnurag S. Maskey /*
451*6ba597c5SAnurag S. Maskey  * Remove specified object from backend by reading in the list of objects,
452*6ba597c5SAnurag S. Maskey  * removing objname and writing the remainder.
453*6ba597c5SAnurag S. Maskey  *
454*6ba597c5SAnurag S. Maskey  * If objname is NULL, remove the backend dbname.
455*6ba597c5SAnurag S. Maskey  */
456*6ba597c5SAnurag S. Maskey nwam_error_t
nwam_remove_object_from_backend(char * dbname,char * objname,uint64_t flags)457*6ba597c5SAnurag S. Maskey nwam_remove_object_from_backend(char *dbname, char *objname, uint64_t flags)
458*6ba597c5SAnurag S. Maskey {
459*6ba597c5SAnurag S. Maskey 	nwam_error_t err = nwam_check_auths(getuid(), B_TRUE, flags);
460*6ba597c5SAnurag S. Maskey 
461*6ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS)
462*6ba597c5SAnurag S. Maskey 		return (err);
463*6ba597c5SAnurag S. Maskey 
464*6ba597c5SAnurag S. Maskey 	return (nwam_backend_door_call(NWAM_BACKEND_DOOR_CMD_REMOVE_REQ,
465*6ba597c5SAnurag S. Maskey 	    dbname, objname, flags, NULL));
466*6ba597c5SAnurag S. Maskey }
467