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