xref: /freebsd/sys/contrib/openzfs/lib/libshare/libshare.c (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy /*
2*eda14cbcSMatt Macy  * CDDL HEADER START
3*eda14cbcSMatt Macy  *
4*eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5*eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6*eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7*eda14cbcSMatt Macy  *
8*eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*eda14cbcSMatt Macy  * or http://www.opensolaris.org/os/licensing.
10*eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11*eda14cbcSMatt Macy  * and limitations under the License.
12*eda14cbcSMatt Macy  *
13*eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14*eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16*eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17*eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18*eda14cbcSMatt Macy  *
19*eda14cbcSMatt Macy  * CDDL HEADER END
20*eda14cbcSMatt Macy  */
21*eda14cbcSMatt Macy 
22*eda14cbcSMatt Macy /*
23*eda14cbcSMatt Macy  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24*eda14cbcSMatt Macy  * Copyright (c) 2011 Gunnar Beutner
25*eda14cbcSMatt Macy  * Copyright (c) 2018, 2020 by Delphix. All rights reserved.
26*eda14cbcSMatt Macy  */
27*eda14cbcSMatt Macy 
28*eda14cbcSMatt Macy #include <stdio.h>
29*eda14cbcSMatt Macy #include <stdlib.h>
30*eda14cbcSMatt Macy #include <errno.h>
31*eda14cbcSMatt Macy #include <strings.h>
32*eda14cbcSMatt Macy #include <libintl.h>
33*eda14cbcSMatt Macy #include <sys/file.h>
34*eda14cbcSMatt Macy #include <sys/types.h>
35*eda14cbcSMatt Macy #include <sys/stat.h>
36*eda14cbcSMatt Macy #include <unistd.h>
37*eda14cbcSMatt Macy #include <libzfs.h>
38*eda14cbcSMatt Macy #include <libshare.h>
39*eda14cbcSMatt Macy #include "libzfs_impl.h"
40*eda14cbcSMatt Macy #include "libshare_impl.h"
41*eda14cbcSMatt Macy #include "nfs.h"
42*eda14cbcSMatt Macy #include "smb.h"
43*eda14cbcSMatt Macy 
44*eda14cbcSMatt Macy static sa_share_impl_t alloc_share(const char *zfsname, const char *path);
45*eda14cbcSMatt Macy static void free_share(sa_share_impl_t share);
46*eda14cbcSMatt Macy 
47*eda14cbcSMatt Macy static int fstypes_count;
48*eda14cbcSMatt Macy static sa_fstype_t *fstypes;
49*eda14cbcSMatt Macy 
50*eda14cbcSMatt Macy sa_fstype_t *
51*eda14cbcSMatt Macy register_fstype(const char *name, const sa_share_ops_t *ops)
52*eda14cbcSMatt Macy {
53*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
54*eda14cbcSMatt Macy 
55*eda14cbcSMatt Macy 	fstype = calloc(1, sizeof (sa_fstype_t));
56*eda14cbcSMatt Macy 
57*eda14cbcSMatt Macy 	if (fstype == NULL)
58*eda14cbcSMatt Macy 		return (NULL);
59*eda14cbcSMatt Macy 
60*eda14cbcSMatt Macy 	fstype->name = name;
61*eda14cbcSMatt Macy 	fstype->ops = ops;
62*eda14cbcSMatt Macy 	fstype->fsinfo_index = fstypes_count;
63*eda14cbcSMatt Macy 
64*eda14cbcSMatt Macy 	fstypes_count++;
65*eda14cbcSMatt Macy 
66*eda14cbcSMatt Macy 	fstype->next = fstypes;
67*eda14cbcSMatt Macy 	fstypes = fstype;
68*eda14cbcSMatt Macy 
69*eda14cbcSMatt Macy 	return (fstype);
70*eda14cbcSMatt Macy }
71*eda14cbcSMatt Macy 
72*eda14cbcSMatt Macy __attribute__((constructor)) static void
73*eda14cbcSMatt Macy libshare_init(void)
74*eda14cbcSMatt Macy {
75*eda14cbcSMatt Macy 	libshare_nfs_init();
76*eda14cbcSMatt Macy 	libshare_smb_init();
77*eda14cbcSMatt Macy }
78*eda14cbcSMatt Macy 
79*eda14cbcSMatt Macy int
80*eda14cbcSMatt Macy sa_enable_share(const char *zfsname, const char *mountpoint,
81*eda14cbcSMatt Macy     const char *shareopts, char *protocol)
82*eda14cbcSMatt Macy {
83*eda14cbcSMatt Macy 	int rc, ret = SA_OK;
84*eda14cbcSMatt Macy 	boolean_t found_protocol = B_FALSE;
85*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
86*eda14cbcSMatt Macy 
87*eda14cbcSMatt Macy 	sa_share_impl_t impl_share = alloc_share(zfsname, mountpoint);
88*eda14cbcSMatt Macy 	if (impl_share == NULL)
89*eda14cbcSMatt Macy 		return (SA_NO_MEMORY);
90*eda14cbcSMatt Macy 
91*eda14cbcSMatt Macy 	fstype = fstypes;
92*eda14cbcSMatt Macy 	while (fstype != NULL) {
93*eda14cbcSMatt Macy 		if (strcmp(fstype->name, protocol) == 0) {
94*eda14cbcSMatt Macy 
95*eda14cbcSMatt Macy 			rc = fstype->ops->update_shareopts(impl_share,
96*eda14cbcSMatt Macy 			    shareopts);
97*eda14cbcSMatt Macy 			if (rc != SA_OK)
98*eda14cbcSMatt Macy 				break;
99*eda14cbcSMatt Macy 
100*eda14cbcSMatt Macy 			rc = fstype->ops->enable_share(impl_share);
101*eda14cbcSMatt Macy 			if (rc != SA_OK)
102*eda14cbcSMatt Macy 				ret = rc;
103*eda14cbcSMatt Macy 
104*eda14cbcSMatt Macy 			found_protocol = B_TRUE;
105*eda14cbcSMatt Macy 		}
106*eda14cbcSMatt Macy 
107*eda14cbcSMatt Macy 		fstype = fstype->next;
108*eda14cbcSMatt Macy 	}
109*eda14cbcSMatt Macy 	free_share(impl_share);
110*eda14cbcSMatt Macy 
111*eda14cbcSMatt Macy 	return (found_protocol ? ret : SA_INVALID_PROTOCOL);
112*eda14cbcSMatt Macy }
113*eda14cbcSMatt Macy 
114*eda14cbcSMatt Macy int
115*eda14cbcSMatt Macy sa_disable_share(const char *mountpoint, char *protocol)
116*eda14cbcSMatt Macy {
117*eda14cbcSMatt Macy 	int rc, ret = SA_OK;
118*eda14cbcSMatt Macy 	boolean_t found_protocol = B_FALSE;
119*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
120*eda14cbcSMatt Macy 
121*eda14cbcSMatt Macy 	sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
122*eda14cbcSMatt Macy 	if (impl_share == NULL)
123*eda14cbcSMatt Macy 		return (SA_NO_MEMORY);
124*eda14cbcSMatt Macy 
125*eda14cbcSMatt Macy 	fstype = fstypes;
126*eda14cbcSMatt Macy 	while (fstype != NULL) {
127*eda14cbcSMatt Macy 		if (strcmp(fstype->name, protocol) == 0) {
128*eda14cbcSMatt Macy 
129*eda14cbcSMatt Macy 			rc = fstype->ops->disable_share(impl_share);
130*eda14cbcSMatt Macy 			if (rc != SA_OK)
131*eda14cbcSMatt Macy 				ret = rc;
132*eda14cbcSMatt Macy 
133*eda14cbcSMatt Macy 			found_protocol = B_TRUE;
134*eda14cbcSMatt Macy 		}
135*eda14cbcSMatt Macy 
136*eda14cbcSMatt Macy 		fstype = fstype->next;
137*eda14cbcSMatt Macy 	}
138*eda14cbcSMatt Macy 	free_share(impl_share);
139*eda14cbcSMatt Macy 
140*eda14cbcSMatt Macy 	return (found_protocol ? ret : SA_INVALID_PROTOCOL);
141*eda14cbcSMatt Macy }
142*eda14cbcSMatt Macy 
143*eda14cbcSMatt Macy boolean_t
144*eda14cbcSMatt Macy sa_is_shared(const char *mountpoint, char *protocol)
145*eda14cbcSMatt Macy {
146*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
147*eda14cbcSMatt Macy 	boolean_t ret = B_FALSE;
148*eda14cbcSMatt Macy 
149*eda14cbcSMatt Macy 	/* guid value is not used */
150*eda14cbcSMatt Macy 	sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
151*eda14cbcSMatt Macy 	if (impl_share == NULL)
152*eda14cbcSMatt Macy 		return (B_FALSE);
153*eda14cbcSMatt Macy 
154*eda14cbcSMatt Macy 	fstype = fstypes;
155*eda14cbcSMatt Macy 	while (fstype != NULL) {
156*eda14cbcSMatt Macy 		if (strcmp(fstype->name, protocol) == 0) {
157*eda14cbcSMatt Macy 			ret = fstype->ops->is_shared(impl_share);
158*eda14cbcSMatt Macy 		}
159*eda14cbcSMatt Macy 		fstype = fstype->next;
160*eda14cbcSMatt Macy 	}
161*eda14cbcSMatt Macy 	free_share(impl_share);
162*eda14cbcSMatt Macy 	return (ret);
163*eda14cbcSMatt Macy }
164*eda14cbcSMatt Macy 
165*eda14cbcSMatt Macy void
166*eda14cbcSMatt Macy sa_commit_shares(const char *protocol)
167*eda14cbcSMatt Macy {
168*eda14cbcSMatt Macy 	sa_fstype_t *fstype = fstypes;
169*eda14cbcSMatt Macy 	while (fstype != NULL) {
170*eda14cbcSMatt Macy 		if (strcmp(fstype->name, protocol) == 0)
171*eda14cbcSMatt Macy 			fstype->ops->commit_shares();
172*eda14cbcSMatt Macy 		fstype = fstype->next;
173*eda14cbcSMatt Macy 	}
174*eda14cbcSMatt Macy }
175*eda14cbcSMatt Macy 
176*eda14cbcSMatt Macy /*
177*eda14cbcSMatt Macy  * sa_errorstr(err)
178*eda14cbcSMatt Macy  *
179*eda14cbcSMatt Macy  * convert an error value to an error string
180*eda14cbcSMatt Macy  */
181*eda14cbcSMatt Macy char *
182*eda14cbcSMatt Macy sa_errorstr(int err)
183*eda14cbcSMatt Macy {
184*eda14cbcSMatt Macy 	static char errstr[32];
185*eda14cbcSMatt Macy 	char *ret = NULL;
186*eda14cbcSMatt Macy 
187*eda14cbcSMatt Macy 	switch (err) {
188*eda14cbcSMatt Macy 	case SA_OK:
189*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "ok");
190*eda14cbcSMatt Macy 		break;
191*eda14cbcSMatt Macy 	case SA_NO_SUCH_PATH:
192*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "path doesn't exist");
193*eda14cbcSMatt Macy 		break;
194*eda14cbcSMatt Macy 	case SA_NO_MEMORY:
195*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "no memory");
196*eda14cbcSMatt Macy 		break;
197*eda14cbcSMatt Macy 	case SA_DUPLICATE_NAME:
198*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "name in use");
199*eda14cbcSMatt Macy 		break;
200*eda14cbcSMatt Macy 	case SA_BAD_PATH:
201*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "bad path");
202*eda14cbcSMatt Macy 		break;
203*eda14cbcSMatt Macy 	case SA_NO_SUCH_GROUP:
204*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "no such group");
205*eda14cbcSMatt Macy 		break;
206*eda14cbcSMatt Macy 	case SA_CONFIG_ERR:
207*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "configuration error");
208*eda14cbcSMatt Macy 		break;
209*eda14cbcSMatt Macy 	case SA_SYSTEM_ERR:
210*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "system error");
211*eda14cbcSMatt Macy 		break;
212*eda14cbcSMatt Macy 	case SA_SYNTAX_ERR:
213*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "syntax error");
214*eda14cbcSMatt Macy 		break;
215*eda14cbcSMatt Macy 	case SA_NO_PERMISSION:
216*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "no permission");
217*eda14cbcSMatt Macy 		break;
218*eda14cbcSMatt Macy 	case SA_BUSY:
219*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "busy");
220*eda14cbcSMatt Macy 		break;
221*eda14cbcSMatt Macy 	case SA_NO_SUCH_PROP:
222*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "no such property");
223*eda14cbcSMatt Macy 		break;
224*eda14cbcSMatt Macy 	case SA_INVALID_NAME:
225*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "invalid name");
226*eda14cbcSMatt Macy 		break;
227*eda14cbcSMatt Macy 	case SA_INVALID_PROTOCOL:
228*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "invalid protocol");
229*eda14cbcSMatt Macy 		break;
230*eda14cbcSMatt Macy 	case SA_NOT_ALLOWED:
231*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "operation not allowed");
232*eda14cbcSMatt Macy 		break;
233*eda14cbcSMatt Macy 	case SA_BAD_VALUE:
234*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "bad property value");
235*eda14cbcSMatt Macy 		break;
236*eda14cbcSMatt Macy 	case SA_INVALID_SECURITY:
237*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "invalid security type");
238*eda14cbcSMatt Macy 		break;
239*eda14cbcSMatt Macy 	case SA_NO_SUCH_SECURITY:
240*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "security type not found");
241*eda14cbcSMatt Macy 		break;
242*eda14cbcSMatt Macy 	case SA_VALUE_CONFLICT:
243*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "property value conflict");
244*eda14cbcSMatt Macy 		break;
245*eda14cbcSMatt Macy 	case SA_NOT_IMPLEMENTED:
246*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "not implemented");
247*eda14cbcSMatt Macy 		break;
248*eda14cbcSMatt Macy 	case SA_INVALID_PATH:
249*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "invalid path");
250*eda14cbcSMatt Macy 		break;
251*eda14cbcSMatt Macy 	case SA_NOT_SUPPORTED:
252*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "operation not supported");
253*eda14cbcSMatt Macy 		break;
254*eda14cbcSMatt Macy 	case SA_PROP_SHARE_ONLY:
255*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "property not valid for group");
256*eda14cbcSMatt Macy 		break;
257*eda14cbcSMatt Macy 	case SA_NOT_SHARED:
258*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "not shared");
259*eda14cbcSMatt Macy 		break;
260*eda14cbcSMatt Macy 	case SA_NO_SUCH_RESOURCE:
261*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "no such resource");
262*eda14cbcSMatt Macy 		break;
263*eda14cbcSMatt Macy 	case SA_RESOURCE_REQUIRED:
264*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "resource name required");
265*eda14cbcSMatt Macy 		break;
266*eda14cbcSMatt Macy 	case SA_MULTIPLE_ERROR:
267*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "errors from multiple protocols");
268*eda14cbcSMatt Macy 		break;
269*eda14cbcSMatt Macy 	case SA_PATH_IS_SUBDIR:
270*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "path is a subpath of share");
271*eda14cbcSMatt Macy 		break;
272*eda14cbcSMatt Macy 	case SA_PATH_IS_PARENTDIR:
273*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "path is parent of a share");
274*eda14cbcSMatt Macy 		break;
275*eda14cbcSMatt Macy 	case SA_NO_SECTION:
276*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "protocol requires a section");
277*eda14cbcSMatt Macy 		break;
278*eda14cbcSMatt Macy 	case SA_NO_PROPERTIES:
279*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "properties not found");
280*eda14cbcSMatt Macy 		break;
281*eda14cbcSMatt Macy 	case SA_NO_SUCH_SECTION:
282*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "section not found");
283*eda14cbcSMatt Macy 		break;
284*eda14cbcSMatt Macy 	case SA_PASSWORD_ENC:
285*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted");
286*eda14cbcSMatt Macy 		break;
287*eda14cbcSMatt Macy 	case SA_SHARE_EXISTS:
288*eda14cbcSMatt Macy 		ret = dgettext(TEXT_DOMAIN, "path or file is already shared");
289*eda14cbcSMatt Macy 		break;
290*eda14cbcSMatt Macy 	default:
291*eda14cbcSMatt Macy 		(void) snprintf(errstr, sizeof (errstr),
292*eda14cbcSMatt Macy 		    dgettext(TEXT_DOMAIN, "unknown %d"), err);
293*eda14cbcSMatt Macy 		ret = errstr;
294*eda14cbcSMatt Macy 	}
295*eda14cbcSMatt Macy 	return (ret);
296*eda14cbcSMatt Macy }
297*eda14cbcSMatt Macy 
298*eda14cbcSMatt Macy int
299*eda14cbcSMatt Macy sa_validate_shareopts(char *options, char *proto)
300*eda14cbcSMatt Macy {
301*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
302*eda14cbcSMatt Macy 
303*eda14cbcSMatt Macy 	fstype = fstypes;
304*eda14cbcSMatt Macy 	while (fstype != NULL) {
305*eda14cbcSMatt Macy 		if (strcmp(fstype->name, proto) != 0) {
306*eda14cbcSMatt Macy 			fstype = fstype->next;
307*eda14cbcSMatt Macy 			continue;
308*eda14cbcSMatt Macy 		}
309*eda14cbcSMatt Macy 
310*eda14cbcSMatt Macy 		return (fstype->ops->validate_shareopts(options));
311*eda14cbcSMatt Macy 	}
312*eda14cbcSMatt Macy 
313*eda14cbcSMatt Macy 	return (SA_INVALID_PROTOCOL);
314*eda14cbcSMatt Macy }
315*eda14cbcSMatt Macy 
316*eda14cbcSMatt Macy static sa_share_impl_t
317*eda14cbcSMatt Macy alloc_share(const char *zfsname, const char *mountpoint)
318*eda14cbcSMatt Macy {
319*eda14cbcSMatt Macy 	sa_share_impl_t impl_share;
320*eda14cbcSMatt Macy 
321*eda14cbcSMatt Macy 	impl_share = calloc(1, sizeof (struct sa_share_impl));
322*eda14cbcSMatt Macy 
323*eda14cbcSMatt Macy 	if (impl_share == NULL)
324*eda14cbcSMatt Macy 		return (NULL);
325*eda14cbcSMatt Macy 
326*eda14cbcSMatt Macy 	if (mountpoint != NULL &&
327*eda14cbcSMatt Macy 	    ((impl_share->sa_mountpoint = strdup(mountpoint)) == NULL)) {
328*eda14cbcSMatt Macy 		free(impl_share);
329*eda14cbcSMatt Macy 		return (NULL);
330*eda14cbcSMatt Macy 	}
331*eda14cbcSMatt Macy 
332*eda14cbcSMatt Macy 	if (zfsname != NULL &&
333*eda14cbcSMatt Macy 	    ((impl_share->sa_zfsname = strdup(zfsname)) == NULL)) {
334*eda14cbcSMatt Macy 		free(impl_share->sa_mountpoint);
335*eda14cbcSMatt Macy 		free(impl_share);
336*eda14cbcSMatt Macy 		return (NULL);
337*eda14cbcSMatt Macy 	}
338*eda14cbcSMatt Macy 
339*eda14cbcSMatt Macy 	impl_share->sa_fsinfo = calloc(fstypes_count,
340*eda14cbcSMatt Macy 	    sizeof (sa_share_fsinfo_t));
341*eda14cbcSMatt Macy 	if (impl_share->sa_fsinfo == NULL) {
342*eda14cbcSMatt Macy 		free(impl_share->sa_mountpoint);
343*eda14cbcSMatt Macy 		free(impl_share->sa_zfsname);
344*eda14cbcSMatt Macy 		free(impl_share);
345*eda14cbcSMatt Macy 		return (NULL);
346*eda14cbcSMatt Macy 	}
347*eda14cbcSMatt Macy 
348*eda14cbcSMatt Macy 	return (impl_share);
349*eda14cbcSMatt Macy }
350*eda14cbcSMatt Macy 
351*eda14cbcSMatt Macy static void
352*eda14cbcSMatt Macy free_share(sa_share_impl_t impl_share)
353*eda14cbcSMatt Macy {
354*eda14cbcSMatt Macy 	sa_fstype_t *fstype;
355*eda14cbcSMatt Macy 
356*eda14cbcSMatt Macy 	fstype = fstypes;
357*eda14cbcSMatt Macy 	while (fstype != NULL) {
358*eda14cbcSMatt Macy 		fstype->ops->clear_shareopts(impl_share);
359*eda14cbcSMatt Macy 		fstype = fstype->next;
360*eda14cbcSMatt Macy 	}
361*eda14cbcSMatt Macy 
362*eda14cbcSMatt Macy 	free(impl_share->sa_mountpoint);
363*eda14cbcSMatt Macy 	free(impl_share->sa_zfsname);
364*eda14cbcSMatt Macy 	free(impl_share->sa_fsinfo);
365*eda14cbcSMatt Macy 	free(impl_share);
366*eda14cbcSMatt Macy }
367