1*36589d6bSRobert Mustacchi /*
2*36589d6bSRobert Mustacchi * This file and its contents are supplied under the terms of the
3*36589d6bSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*36589d6bSRobert Mustacchi * You may only use this file in accordance with the terms of version
5*36589d6bSRobert Mustacchi * 1.0 of the CDDL.
6*36589d6bSRobert Mustacchi *
7*36589d6bSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*36589d6bSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*36589d6bSRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*36589d6bSRobert Mustacchi */
11*36589d6bSRobert Mustacchi
12*36589d6bSRobert Mustacchi /*
13*36589d6bSRobert Mustacchi * Copyright 2015 Joyent, Inc.
14*36589d6bSRobert Mustacchi */
15*36589d6bSRobert Mustacchi
16*36589d6bSRobert Mustacchi /*
17*36589d6bSRobert Mustacchi * varpd door server logic
18*36589d6bSRobert Mustacchi */
19*36589d6bSRobert Mustacchi
20*36589d6bSRobert Mustacchi #include <door.h>
21*36589d6bSRobert Mustacchi #include <errno.h>
22*36589d6bSRobert Mustacchi #include <sys/types.h>
23*36589d6bSRobert Mustacchi #include <sys/stat.h>
24*36589d6bSRobert Mustacchi #include <fcntl.h>
25*36589d6bSRobert Mustacchi #include <unistd.h>
26*36589d6bSRobert Mustacchi #include <stropts.h>
27*36589d6bSRobert Mustacchi #include <stdlib.h>
28*36589d6bSRobert Mustacchi #include <strings.h>
29*36589d6bSRobert Mustacchi #include <priv.h>
30*36589d6bSRobert Mustacchi #include <libvarpd_impl.h>
31*36589d6bSRobert Mustacchi
32*36589d6bSRobert Mustacchi typedef int (libvarpd_door_f)(varpd_impl_t *, varpd_client_arg_t *, ucred_t *);
33*36589d6bSRobert Mustacchi
34*36589d6bSRobert Mustacchi static boolean_t
libvarpd_door_privileged(ucred_t * credp)35*36589d6bSRobert Mustacchi libvarpd_door_privileged(ucred_t *credp)
36*36589d6bSRobert Mustacchi {
37*36589d6bSRobert Mustacchi const priv_set_t *ps;
38*36589d6bSRobert Mustacchi
39*36589d6bSRobert Mustacchi ps = ucred_getprivset(credp, PRIV_EFFECTIVE);
40*36589d6bSRobert Mustacchi if (ps == NULL)
41*36589d6bSRobert Mustacchi return (B_FALSE);
42*36589d6bSRobert Mustacchi
43*36589d6bSRobert Mustacchi return (priv_ismember(ps, PRIV_SYS_NET_CONFIG));
44*36589d6bSRobert Mustacchi }
45*36589d6bSRobert Mustacchi
46*36589d6bSRobert Mustacchi /* ARGSUSED */
47*36589d6bSRobert Mustacchi static int
libvarpd_door_f_create(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)48*36589d6bSRobert Mustacchi libvarpd_door_f_create(varpd_impl_t *vip, varpd_client_arg_t *vcap,
49*36589d6bSRobert Mustacchi ucred_t *credp)
50*36589d6bSRobert Mustacchi {
51*36589d6bSRobert Mustacchi int ret;
52*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihdl;
53*36589d6bSRobert Mustacchi varpd_client_create_arg_t *vccap = &vcap->vca_un.vca_create;
54*36589d6bSRobert Mustacchi
55*36589d6bSRobert Mustacchi vccap->vcca_plugin[LIBVARPD_PROP_NAMELEN-1] = '\0';
56*36589d6bSRobert Mustacchi ret = libvarpd_instance_create((varpd_handle_t *)vip,
57*36589d6bSRobert Mustacchi vccap->vcca_linkid, vccap->vcca_plugin, &ihdl);
58*36589d6bSRobert Mustacchi if (ret == 0)
59*36589d6bSRobert Mustacchi vccap->vcca_id = libvarpd_instance_id(ihdl);
60*36589d6bSRobert Mustacchi
61*36589d6bSRobert Mustacchi return (ret);
62*36589d6bSRobert Mustacchi }
63*36589d6bSRobert Mustacchi
64*36589d6bSRobert Mustacchi /* ARGSUSED */
65*36589d6bSRobert Mustacchi static int
libvarpd_door_f_activate(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)66*36589d6bSRobert Mustacchi libvarpd_door_f_activate(varpd_impl_t *vip, varpd_client_arg_t *vcap,
67*36589d6bSRobert Mustacchi ucred_t *credp)
68*36589d6bSRobert Mustacchi {
69*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
70*36589d6bSRobert Mustacchi varpd_client_instance_arg_t *vciap = &vcap->vca_un.vca_instance;
71*36589d6bSRobert Mustacchi
72*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vciap->vcia_id);
73*36589d6bSRobert Mustacchi if (ihp == NULL)
74*36589d6bSRobert Mustacchi return (ENOENT);
75*36589d6bSRobert Mustacchi return (libvarpd_instance_activate(ihp));
76*36589d6bSRobert Mustacchi }
77*36589d6bSRobert Mustacchi
78*36589d6bSRobert Mustacchi /* ARGSUSED */
79*36589d6bSRobert Mustacchi static int
libvarpd_door_f_destroy(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)80*36589d6bSRobert Mustacchi libvarpd_door_f_destroy(varpd_impl_t *vip, varpd_client_arg_t *vcap,
81*36589d6bSRobert Mustacchi ucred_t *credp)
82*36589d6bSRobert Mustacchi {
83*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
84*36589d6bSRobert Mustacchi varpd_client_instance_arg_t *vciap = &vcap->vca_un.vca_instance;
85*36589d6bSRobert Mustacchi
86*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vciap->vcia_id);
87*36589d6bSRobert Mustacchi if (ihp == NULL)
88*36589d6bSRobert Mustacchi return (ENOENT);
89*36589d6bSRobert Mustacchi libvarpd_instance_destroy(ihp);
90*36589d6bSRobert Mustacchi return (0);
91*36589d6bSRobert Mustacchi }
92*36589d6bSRobert Mustacchi
93*36589d6bSRobert Mustacchi /* ARGSUSED */
94*36589d6bSRobert Mustacchi static int
libvarpd_door_f_nprops(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)95*36589d6bSRobert Mustacchi libvarpd_door_f_nprops(varpd_impl_t *vip, varpd_client_arg_t *vcap,
96*36589d6bSRobert Mustacchi ucred_t *credp)
97*36589d6bSRobert Mustacchi {
98*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
99*36589d6bSRobert Mustacchi varpd_client_nprops_arg_t *vcnap = &vcap->vca_un.vca_nprops;
100*36589d6bSRobert Mustacchi
101*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vcnap->vcna_id);
102*36589d6bSRobert Mustacchi if (ihp == NULL)
103*36589d6bSRobert Mustacchi return (ENOENT);
104*36589d6bSRobert Mustacchi
105*36589d6bSRobert Mustacchi return (libvarpd_prop_nprops(ihp, &vcnap->vcna_nprops));
106*36589d6bSRobert Mustacchi }
107*36589d6bSRobert Mustacchi
108*36589d6bSRobert Mustacchi /* ARGSUSED */
109*36589d6bSRobert Mustacchi static int
libvarpd_door_f_propinfo(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)110*36589d6bSRobert Mustacchi libvarpd_door_f_propinfo(varpd_impl_t *vip, varpd_client_arg_t *vcap,
111*36589d6bSRobert Mustacchi ucred_t *credp)
112*36589d6bSRobert Mustacchi {
113*36589d6bSRobert Mustacchi int ret;
114*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
115*36589d6bSRobert Mustacchi varpd_prop_handle_t *phdl;
116*36589d6bSRobert Mustacchi varpd_client_propinfo_arg_t *vcfap = &vcap->vca_un.vca_info;
117*36589d6bSRobert Mustacchi
118*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vcfap->vcfa_id);
119*36589d6bSRobert Mustacchi if (ihp == NULL)
120*36589d6bSRobert Mustacchi return (ENOENT);
121*36589d6bSRobert Mustacchi ret = libvarpd_prop_handle_alloc((varpd_handle_t *)vip, ihp, &phdl);
122*36589d6bSRobert Mustacchi if (ret != 0)
123*36589d6bSRobert Mustacchi return (ret);
124*36589d6bSRobert Mustacchi
125*36589d6bSRobert Mustacchi if (vcfap->vcfa_propid != UINT_MAX) {
126*36589d6bSRobert Mustacchi ret = libvarpd_prop_info_fill(phdl, vcfap->vcfa_propid);
127*36589d6bSRobert Mustacchi if (ret != 0) {
128*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
129*36589d6bSRobert Mustacchi return (ret);
130*36589d6bSRobert Mustacchi }
131*36589d6bSRobert Mustacchi } else {
132*36589d6bSRobert Mustacchi uint_t i, nprop;
133*36589d6bSRobert Mustacchi const char *name;
134*36589d6bSRobert Mustacchi
135*36589d6bSRobert Mustacchi vcfap->vcfa_name[LIBVARPD_PROP_NAMELEN-1] = '\0';
136*36589d6bSRobert Mustacchi ret = libvarpd_prop_nprops(ihp, &nprop);
137*36589d6bSRobert Mustacchi if (ret != 0) {
138*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
139*36589d6bSRobert Mustacchi return (ret);
140*36589d6bSRobert Mustacchi }
141*36589d6bSRobert Mustacchi for (i = 0; i < nprop; i++) {
142*36589d6bSRobert Mustacchi ret = libvarpd_prop_info_fill(phdl, i);
143*36589d6bSRobert Mustacchi if (ret != 0) {
144*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
145*36589d6bSRobert Mustacchi return (ret);
146*36589d6bSRobert Mustacchi }
147*36589d6bSRobert Mustacchi ret = libvarpd_prop_info(phdl, &name, NULL, NULL, NULL,
148*36589d6bSRobert Mustacchi NULL, NULL);
149*36589d6bSRobert Mustacchi if (ret != 0) {
150*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
151*36589d6bSRobert Mustacchi return (ret);
152*36589d6bSRobert Mustacchi }
153*36589d6bSRobert Mustacchi if (strcmp(vcfap->vcfa_name, name) == 0)
154*36589d6bSRobert Mustacchi break;
155*36589d6bSRobert Mustacchi }
156*36589d6bSRobert Mustacchi
157*36589d6bSRobert Mustacchi if (i == nprop) {
158*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
159*36589d6bSRobert Mustacchi return (ENOENT);
160*36589d6bSRobert Mustacchi }
161*36589d6bSRobert Mustacchi vcfap->vcfa_propid = i;
162*36589d6bSRobert Mustacchi }
163*36589d6bSRobert Mustacchi libvarpd_prop_door_convert(phdl, vcfap);
164*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
165*36589d6bSRobert Mustacchi return (0);
166*36589d6bSRobert Mustacchi }
167*36589d6bSRobert Mustacchi
168*36589d6bSRobert Mustacchi /* ARGSUSED */
169*36589d6bSRobert Mustacchi static int
libvarpd_door_f_getprop(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)170*36589d6bSRobert Mustacchi libvarpd_door_f_getprop(varpd_impl_t *vip, varpd_client_arg_t *vcap,
171*36589d6bSRobert Mustacchi ucred_t *credp)
172*36589d6bSRobert Mustacchi {
173*36589d6bSRobert Mustacchi int ret;
174*36589d6bSRobert Mustacchi uint32_t size;
175*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
176*36589d6bSRobert Mustacchi varpd_prop_handle_t *phdl;
177*36589d6bSRobert Mustacchi varpd_client_prop_arg_t *vcpap = &vcap->vca_un.vca_prop;
178*36589d6bSRobert Mustacchi
179*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vcpap->vcpa_id);
180*36589d6bSRobert Mustacchi if (ihp == NULL)
181*36589d6bSRobert Mustacchi return (ENOENT);
182*36589d6bSRobert Mustacchi ret = libvarpd_prop_handle_alloc((varpd_handle_t *)vip, ihp, &phdl);
183*36589d6bSRobert Mustacchi if (ret != 0)
184*36589d6bSRobert Mustacchi return (ret);
185*36589d6bSRobert Mustacchi
186*36589d6bSRobert Mustacchi ret = libvarpd_prop_info_fill(phdl, vcpap->vcpa_propid);
187*36589d6bSRobert Mustacchi if (ret != 0) {
188*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
189*36589d6bSRobert Mustacchi return (ret);
190*36589d6bSRobert Mustacchi }
191*36589d6bSRobert Mustacchi
192*36589d6bSRobert Mustacchi ret = libvarpd_prop_get(phdl, vcpap->vcpa_buf, &size);
193*36589d6bSRobert Mustacchi if (ret == 0)
194*36589d6bSRobert Mustacchi vcpap->vcpa_bufsize = size;
195*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
196*36589d6bSRobert Mustacchi return (0);
197*36589d6bSRobert Mustacchi }
198*36589d6bSRobert Mustacchi
199*36589d6bSRobert Mustacchi /* ARGSUSED */
200*36589d6bSRobert Mustacchi static int
libvarpd_door_f_setprop(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)201*36589d6bSRobert Mustacchi libvarpd_door_f_setprop(varpd_impl_t *vip, varpd_client_arg_t *vcap,
202*36589d6bSRobert Mustacchi ucred_t *credp)
203*36589d6bSRobert Mustacchi {
204*36589d6bSRobert Mustacchi int ret;
205*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
206*36589d6bSRobert Mustacchi varpd_prop_handle_t *phdl;
207*36589d6bSRobert Mustacchi varpd_client_prop_arg_t *vcpap = &vcap->vca_un.vca_prop;
208*36589d6bSRobert Mustacchi
209*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vcpap->vcpa_id);
210*36589d6bSRobert Mustacchi if (ihp == NULL)
211*36589d6bSRobert Mustacchi return (ENOENT);
212*36589d6bSRobert Mustacchi ret = libvarpd_prop_handle_alloc((varpd_handle_t *)vip, ihp, &phdl);
213*36589d6bSRobert Mustacchi if (ret != 0)
214*36589d6bSRobert Mustacchi return (ret);
215*36589d6bSRobert Mustacchi
216*36589d6bSRobert Mustacchi ret = libvarpd_prop_info_fill(phdl, vcpap->vcpa_propid);
217*36589d6bSRobert Mustacchi if (ret != 0) {
218*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
219*36589d6bSRobert Mustacchi return (ret);
220*36589d6bSRobert Mustacchi }
221*36589d6bSRobert Mustacchi
222*36589d6bSRobert Mustacchi ret = libvarpd_prop_set(phdl, vcpap->vcpa_buf, vcpap->vcpa_bufsize);
223*36589d6bSRobert Mustacchi libvarpd_prop_handle_free(phdl);
224*36589d6bSRobert Mustacchi return (ret);
225*36589d6bSRobert Mustacchi }
226*36589d6bSRobert Mustacchi
227*36589d6bSRobert Mustacchi /* ARGSUSED */
228*36589d6bSRobert Mustacchi static int
libvarpd_door_f_lookup(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)229*36589d6bSRobert Mustacchi libvarpd_door_f_lookup(varpd_impl_t *vip, varpd_client_arg_t *vcap,
230*36589d6bSRobert Mustacchi ucred_t *credp)
231*36589d6bSRobert Mustacchi {
232*36589d6bSRobert Mustacchi varpd_instance_t *inst;
233*36589d6bSRobert Mustacchi varpd_client_lookup_arg_t *vclap = &vcap->vca_un.vca_lookup;
234*36589d6bSRobert Mustacchi
235*36589d6bSRobert Mustacchi inst = libvarpd_instance_lookup_by_dlid(vip, vclap->vcla_linkid);
236*36589d6bSRobert Mustacchi if (inst == NULL)
237*36589d6bSRobert Mustacchi return (ENOENT);
238*36589d6bSRobert Mustacchi
239*36589d6bSRobert Mustacchi vclap->vcla_id = inst->vri_id;
240*36589d6bSRobert Mustacchi return (0);
241*36589d6bSRobert Mustacchi }
242*36589d6bSRobert Mustacchi
243*36589d6bSRobert Mustacchi /* ARGSUSED */
244*36589d6bSRobert Mustacchi static int
libvarpd_door_f_target(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)245*36589d6bSRobert Mustacchi libvarpd_door_f_target(varpd_impl_t *vip, varpd_client_arg_t *vcap,
246*36589d6bSRobert Mustacchi ucred_t *credp)
247*36589d6bSRobert Mustacchi {
248*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
249*36589d6bSRobert Mustacchi varpd_instance_t *inst;
250*36589d6bSRobert Mustacchi varpd_client_target_mode_arg_t *vtmap = &vcap->vca_un.vca_mode;
251*36589d6bSRobert Mustacchi
252*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vtmap->vtma_id);
253*36589d6bSRobert Mustacchi if (ihp == NULL)
254*36589d6bSRobert Mustacchi return (ENOENT);
255*36589d6bSRobert Mustacchi inst = (varpd_instance_t *)ihp;
256*36589d6bSRobert Mustacchi vtmap->vtma_dest = inst->vri_dest;
257*36589d6bSRobert Mustacchi vtmap->vtma_mode = inst->vri_mode;
258*36589d6bSRobert Mustacchi return (0);
259*36589d6bSRobert Mustacchi }
260*36589d6bSRobert Mustacchi
261*36589d6bSRobert Mustacchi static int
libvarpd_door_f_flush(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)262*36589d6bSRobert Mustacchi libvarpd_door_f_flush(varpd_impl_t *vip, varpd_client_arg_t *vcap,
263*36589d6bSRobert Mustacchi ucred_t *credp)
264*36589d6bSRobert Mustacchi {
265*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
266*36589d6bSRobert Mustacchi varpd_client_target_cache_arg_t *vtcap = &vcap->vca_un.vca_cache;
267*36589d6bSRobert Mustacchi
268*36589d6bSRobert Mustacchi if (libvarpd_door_privileged(credp) == B_FALSE)
269*36589d6bSRobert Mustacchi return (EPERM);
270*36589d6bSRobert Mustacchi
271*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vtcap->vtca_id);
272*36589d6bSRobert Mustacchi if (ihp == NULL)
273*36589d6bSRobert Mustacchi return (ENOENT);
274*36589d6bSRobert Mustacchi return (libvarpd_overlay_cache_flush((varpd_instance_t *)ihp));
275*36589d6bSRobert Mustacchi }
276*36589d6bSRobert Mustacchi
277*36589d6bSRobert Mustacchi static int
libvarpd_door_f_delete(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)278*36589d6bSRobert Mustacchi libvarpd_door_f_delete(varpd_impl_t *vip, varpd_client_arg_t *vcap,
279*36589d6bSRobert Mustacchi ucred_t *credp)
280*36589d6bSRobert Mustacchi {
281*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
282*36589d6bSRobert Mustacchi varpd_client_target_cache_arg_t *vtcap = &vcap->vca_un.vca_cache;
283*36589d6bSRobert Mustacchi
284*36589d6bSRobert Mustacchi if (libvarpd_door_privileged(credp) == B_FALSE)
285*36589d6bSRobert Mustacchi return (EPERM);
286*36589d6bSRobert Mustacchi
287*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vtcap->vtca_id);
288*36589d6bSRobert Mustacchi if (ihp == NULL)
289*36589d6bSRobert Mustacchi return (ENOENT);
290*36589d6bSRobert Mustacchi return (libvarpd_overlay_cache_delete((varpd_instance_t *)ihp,
291*36589d6bSRobert Mustacchi vtcap->vtca_key));
292*36589d6bSRobert Mustacchi }
293*36589d6bSRobert Mustacchi
294*36589d6bSRobert Mustacchi /* ARGSUSED */
295*36589d6bSRobert Mustacchi static int
libvarpd_door_f_get(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)296*36589d6bSRobert Mustacchi libvarpd_door_f_get(varpd_impl_t *vip, varpd_client_arg_t *vcap,
297*36589d6bSRobert Mustacchi ucred_t *credp)
298*36589d6bSRobert Mustacchi {
299*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
300*36589d6bSRobert Mustacchi varpd_client_target_cache_arg_t *vtcap = &vcap->vca_un.vca_cache;
301*36589d6bSRobert Mustacchi
302*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vtcap->vtca_id);
303*36589d6bSRobert Mustacchi if (ihp == NULL)
304*36589d6bSRobert Mustacchi return (ENOENT);
305*36589d6bSRobert Mustacchi return (libvarpd_overlay_cache_get((varpd_instance_t *)ihp,
306*36589d6bSRobert Mustacchi vtcap->vtca_key, &vtcap->vtca_entry));
307*36589d6bSRobert Mustacchi }
308*36589d6bSRobert Mustacchi
309*36589d6bSRobert Mustacchi static int
libvarpd_door_f_set(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)310*36589d6bSRobert Mustacchi libvarpd_door_f_set(varpd_impl_t *vip, varpd_client_arg_t *vcap,
311*36589d6bSRobert Mustacchi ucred_t *credp)
312*36589d6bSRobert Mustacchi {
313*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
314*36589d6bSRobert Mustacchi varpd_client_target_cache_arg_t *vtcap = &vcap->vca_un.vca_cache;
315*36589d6bSRobert Mustacchi
316*36589d6bSRobert Mustacchi if (libvarpd_door_privileged(credp) == B_FALSE)
317*36589d6bSRobert Mustacchi return (EPERM);
318*36589d6bSRobert Mustacchi
319*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vtcap->vtca_id);
320*36589d6bSRobert Mustacchi if (ihp == NULL)
321*36589d6bSRobert Mustacchi return (ENOENT);
322*36589d6bSRobert Mustacchi
323*36589d6bSRobert Mustacchi return (libvarpd_overlay_cache_set((varpd_instance_t *)ihp,
324*36589d6bSRobert Mustacchi vtcap->vtca_key, &vtcap->vtca_entry));
325*36589d6bSRobert Mustacchi }
326*36589d6bSRobert Mustacchi
327*36589d6bSRobert Mustacchi /* ARGSUSED */
328*36589d6bSRobert Mustacchi static int
libvarpd_door_f_walk(varpd_impl_t * vip,varpd_client_arg_t * vcap,ucred_t * credp)329*36589d6bSRobert Mustacchi libvarpd_door_f_walk(varpd_impl_t *vip, varpd_client_arg_t *vcap,
330*36589d6bSRobert Mustacchi ucred_t *credp)
331*36589d6bSRobert Mustacchi {
332*36589d6bSRobert Mustacchi varpd_instance_handle_t *ihp;
333*36589d6bSRobert Mustacchi varpd_client_target_walk_arg_t *vctwp = &vcap->vca_un.vca_walk;
334*36589d6bSRobert Mustacchi
335*36589d6bSRobert Mustacchi ihp = libvarpd_instance_lookup((varpd_handle_t *)vip, vctwp->vtcw_id);
336*36589d6bSRobert Mustacchi if (ihp == NULL)
337*36589d6bSRobert Mustacchi return (ENOENT);
338*36589d6bSRobert Mustacchi
339*36589d6bSRobert Mustacchi return (libvarpd_overlay_cache_walk_fill((varpd_instance_t *)ihp,
340*36589d6bSRobert Mustacchi &vctwp->vtcw_marker, &vctwp->vtcw_count, vctwp->vtcw_ents));
341*36589d6bSRobert Mustacchi }
342*36589d6bSRobert Mustacchi
343*36589d6bSRobert Mustacchi static libvarpd_door_f *libvarpd_door_table[] = {
344*36589d6bSRobert Mustacchi libvarpd_door_f_create,
345*36589d6bSRobert Mustacchi libvarpd_door_f_activate,
346*36589d6bSRobert Mustacchi libvarpd_door_f_destroy,
347*36589d6bSRobert Mustacchi libvarpd_door_f_nprops,
348*36589d6bSRobert Mustacchi libvarpd_door_f_propinfo,
349*36589d6bSRobert Mustacchi libvarpd_door_f_getprop,
350*36589d6bSRobert Mustacchi libvarpd_door_f_setprop,
351*36589d6bSRobert Mustacchi libvarpd_door_f_lookup,
352*36589d6bSRobert Mustacchi libvarpd_door_f_target,
353*36589d6bSRobert Mustacchi libvarpd_door_f_flush,
354*36589d6bSRobert Mustacchi libvarpd_door_f_delete,
355*36589d6bSRobert Mustacchi libvarpd_door_f_get,
356*36589d6bSRobert Mustacchi libvarpd_door_f_set,
357*36589d6bSRobert Mustacchi libvarpd_door_f_walk
358*36589d6bSRobert Mustacchi };
359*36589d6bSRobert Mustacchi
360*36589d6bSRobert Mustacchi /* ARGSUSED */
361*36589d6bSRobert Mustacchi static void
libvarpd_door_server(void * cookie,char * argp,size_t argsz,door_desc_t * dp,uint_t ndesc)362*36589d6bSRobert Mustacchi libvarpd_door_server(void *cookie, char *argp, size_t argsz, door_desc_t *dp,
363*36589d6bSRobert Mustacchi uint_t ndesc)
364*36589d6bSRobert Mustacchi {
365*36589d6bSRobert Mustacchi int ret;
366*36589d6bSRobert Mustacchi varpd_client_eresp_t err;
367*36589d6bSRobert Mustacchi ucred_t *credp = NULL;
368*36589d6bSRobert Mustacchi varpd_impl_t *vip = cookie;
369*36589d6bSRobert Mustacchi varpd_client_arg_t *vcap = (varpd_client_arg_t *)argp;
370*36589d6bSRobert Mustacchi
371*36589d6bSRobert Mustacchi err.vce_command = VARPD_CLIENT_INVALID;
372*36589d6bSRobert Mustacchi if (argsz < sizeof (varpd_client_arg_t)) {
373*36589d6bSRobert Mustacchi err.vce_errno = EINVAL;
374*36589d6bSRobert Mustacchi goto errout;
375*36589d6bSRobert Mustacchi }
376*36589d6bSRobert Mustacchi
377*36589d6bSRobert Mustacchi if ((ret = door_ucred(&credp)) != 0) {
378*36589d6bSRobert Mustacchi err.vce_errno = ret;
379*36589d6bSRobert Mustacchi goto errout;
380*36589d6bSRobert Mustacchi }
381*36589d6bSRobert Mustacchi
382*36589d6bSRobert Mustacchi if (vcap->vca_command == VARPD_CLIENT_INVALID ||
383*36589d6bSRobert Mustacchi vcap->vca_command >= VARPD_CLIENT_MAX) {
384*36589d6bSRobert Mustacchi err.vce_errno = EINVAL;
385*36589d6bSRobert Mustacchi goto errout;
386*36589d6bSRobert Mustacchi }
387*36589d6bSRobert Mustacchi
388*36589d6bSRobert Mustacchi vcap->vca_errno = 0;
389*36589d6bSRobert Mustacchi ret = libvarpd_door_table[vcap->vca_command - 1](vip, vcap, credp);
390*36589d6bSRobert Mustacchi if (ret != 0)
391*36589d6bSRobert Mustacchi vcap->vca_errno = ret;
392*36589d6bSRobert Mustacchi
393*36589d6bSRobert Mustacchi ucred_free(credp);
394*36589d6bSRobert Mustacchi (void) door_return(argp, argsz, NULL, 0);
395*36589d6bSRobert Mustacchi return;
396*36589d6bSRobert Mustacchi
397*36589d6bSRobert Mustacchi errout:
398*36589d6bSRobert Mustacchi ucred_free(credp);
399*36589d6bSRobert Mustacchi (void) door_return((char *)&err, sizeof (err), NULL, 0);
400*36589d6bSRobert Mustacchi }
401*36589d6bSRobert Mustacchi
402*36589d6bSRobert Mustacchi int
libvarpd_door_server_create(varpd_handle_t * vhp,const char * path)403*36589d6bSRobert Mustacchi libvarpd_door_server_create(varpd_handle_t *vhp, const char *path)
404*36589d6bSRobert Mustacchi {
405*36589d6bSRobert Mustacchi int fd, ret;
406*36589d6bSRobert Mustacchi varpd_impl_t *vip = (varpd_impl_t *)vhp;
407*36589d6bSRobert Mustacchi
408*36589d6bSRobert Mustacchi mutex_enter(&vip->vdi_lock);
409*36589d6bSRobert Mustacchi if (vip->vdi_doorfd >= 0) {
410*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
411*36589d6bSRobert Mustacchi return (EEXIST);
412*36589d6bSRobert Mustacchi }
413*36589d6bSRobert Mustacchi
414*36589d6bSRobert Mustacchi vip->vdi_doorfd = door_create(libvarpd_door_server, vip,
415*36589d6bSRobert Mustacchi DOOR_REFUSE_DESC | DOOR_NO_CANCEL);
416*36589d6bSRobert Mustacchi if (vip->vdi_doorfd == -1) {
417*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
418*36589d6bSRobert Mustacchi return (errno);
419*36589d6bSRobert Mustacchi }
420*36589d6bSRobert Mustacchi
421*36589d6bSRobert Mustacchi if ((fd = open(path, O_CREAT | O_RDWR, 0666)) == -1) {
422*36589d6bSRobert Mustacchi ret = errno;
423*36589d6bSRobert Mustacchi if (door_revoke(vip->vdi_doorfd) != 0)
424*36589d6bSRobert Mustacchi libvarpd_panic("failed to revoke door: %d",
425*36589d6bSRobert Mustacchi errno);
426*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
427*36589d6bSRobert Mustacchi return (errno);
428*36589d6bSRobert Mustacchi }
429*36589d6bSRobert Mustacchi
430*36589d6bSRobert Mustacchi if (fchown(fd, UID_NETADM, GID_NETADM) != 0) {
431*36589d6bSRobert Mustacchi ret = errno;
432*36589d6bSRobert Mustacchi if (door_revoke(vip->vdi_doorfd) != 0)
433*36589d6bSRobert Mustacchi libvarpd_panic("failed to revoke door: %d",
434*36589d6bSRobert Mustacchi errno);
435*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
436*36589d6bSRobert Mustacchi return (ret);
437*36589d6bSRobert Mustacchi }
438*36589d6bSRobert Mustacchi
439*36589d6bSRobert Mustacchi if (close(fd) != 0)
440*36589d6bSRobert Mustacchi libvarpd_panic("failed to close door fd %d: %d",
441*36589d6bSRobert Mustacchi fd, errno);
442*36589d6bSRobert Mustacchi (void) fdetach(path);
443*36589d6bSRobert Mustacchi if (fattach(vip->vdi_doorfd, path) != 0) {
444*36589d6bSRobert Mustacchi ret = errno;
445*36589d6bSRobert Mustacchi if (door_revoke(vip->vdi_doorfd) != 0)
446*36589d6bSRobert Mustacchi libvarpd_panic("failed to revoke door: %d",
447*36589d6bSRobert Mustacchi errno);
448*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
449*36589d6bSRobert Mustacchi return (ret);
450*36589d6bSRobert Mustacchi }
451*36589d6bSRobert Mustacchi
452*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
453*36589d6bSRobert Mustacchi return (0);
454*36589d6bSRobert Mustacchi }
455*36589d6bSRobert Mustacchi
456*36589d6bSRobert Mustacchi void
libvarpd_door_server_destroy(varpd_handle_t * vhp)457*36589d6bSRobert Mustacchi libvarpd_door_server_destroy(varpd_handle_t *vhp)
458*36589d6bSRobert Mustacchi {
459*36589d6bSRobert Mustacchi varpd_impl_t *vip = (varpd_impl_t *)vhp;
460*36589d6bSRobert Mustacchi
461*36589d6bSRobert Mustacchi mutex_enter(&vip->vdi_lock);
462*36589d6bSRobert Mustacchi if (vip->vdi_doorfd != 0) {
463*36589d6bSRobert Mustacchi if (door_revoke(vip->vdi_doorfd) != 0)
464*36589d6bSRobert Mustacchi libvarpd_panic("failed to revoke door: %d",
465*36589d6bSRobert Mustacchi errno);
466*36589d6bSRobert Mustacchi vip->vdi_doorfd = -1;
467*36589d6bSRobert Mustacchi }
468*36589d6bSRobert Mustacchi mutex_exit(&vip->vdi_lock);
469*36589d6bSRobert Mustacchi }
470