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 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 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 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 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 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 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 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 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 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 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