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