4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011 Gunnar Beutner
25 * Copyright (c) 2018, 2020 by Delphix. All rights reserved.
34 #include <sys/types.h>
39 #include "libzfs_impl.h"
40 #include "libshare_impl.h"
44 static sa_share_impl_t alloc_share(const char *zfsname, const char *path);
45 static void free_share(sa_share_impl_t share);
47 static int fstypes_count;
48 static sa_fstype_t *fstypes;
51 register_fstype(const char *name, const sa_share_ops_t *ops)
55 fstype = calloc(1, sizeof (sa_fstype_t));
62 fstype->fsinfo_index = fstypes_count;
66 fstype->next = fstypes;
72 __attribute__((constructor)) static void
80 sa_enable_share(const char *zfsname, const char *mountpoint,
81 const char *shareopts, char *protocol)
84 boolean_t found_protocol = B_FALSE;
87 sa_share_impl_t impl_share = alloc_share(zfsname, mountpoint);
88 if (impl_share == NULL)
89 return (SA_NO_MEMORY);
92 while (fstype != NULL) {
93 if (strcmp(fstype->name, protocol) == 0) {
95 rc = fstype->ops->update_shareopts(impl_share,
100 rc = fstype->ops->enable_share(impl_share);
104 found_protocol = B_TRUE;
107 fstype = fstype->next;
109 free_share(impl_share);
111 return (found_protocol ? ret : SA_INVALID_PROTOCOL);
115 sa_disable_share(const char *mountpoint, char *protocol)
118 boolean_t found_protocol = B_FALSE;
121 sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
122 if (impl_share == NULL)
123 return (SA_NO_MEMORY);
126 while (fstype != NULL) {
127 if (strcmp(fstype->name, protocol) == 0) {
129 rc = fstype->ops->disable_share(impl_share);
133 found_protocol = B_TRUE;
136 fstype = fstype->next;
138 free_share(impl_share);
140 return (found_protocol ? ret : SA_INVALID_PROTOCOL);
144 sa_is_shared(const char *mountpoint, char *protocol)
147 boolean_t ret = B_FALSE;
149 /* guid value is not used */
150 sa_share_impl_t impl_share = alloc_share(NULL, mountpoint);
151 if (impl_share == NULL)
155 while (fstype != NULL) {
156 if (strcmp(fstype->name, protocol) == 0) {
157 ret = fstype->ops->is_shared(impl_share);
159 fstype = fstype->next;
161 free_share(impl_share);
166 sa_commit_shares(const char *protocol)
168 sa_fstype_t *fstype = fstypes;
169 while (fstype != NULL) {
170 if (strcmp(fstype->name, protocol) == 0)
171 fstype->ops->commit_shares();
172 fstype = fstype->next;
179 * convert an error value to an error string
184 static char errstr[32];
189 ret = dgettext(TEXT_DOMAIN, "ok");
191 case SA_NO_SUCH_PATH:
192 ret = dgettext(TEXT_DOMAIN, "path doesn't exist");
195 ret = dgettext(TEXT_DOMAIN, "no memory");
197 case SA_DUPLICATE_NAME:
198 ret = dgettext(TEXT_DOMAIN, "name in use");
201 ret = dgettext(TEXT_DOMAIN, "bad path");
203 case SA_NO_SUCH_GROUP:
204 ret = dgettext(TEXT_DOMAIN, "no such group");
207 ret = dgettext(TEXT_DOMAIN, "configuration error");
210 ret = dgettext(TEXT_DOMAIN, "system error");
213 ret = dgettext(TEXT_DOMAIN, "syntax error");
215 case SA_NO_PERMISSION:
216 ret = dgettext(TEXT_DOMAIN, "no permission");
219 ret = dgettext(TEXT_DOMAIN, "busy");
221 case SA_NO_SUCH_PROP:
222 ret = dgettext(TEXT_DOMAIN, "no such property");
224 case SA_INVALID_NAME:
225 ret = dgettext(TEXT_DOMAIN, "invalid name");
227 case SA_INVALID_PROTOCOL:
228 ret = dgettext(TEXT_DOMAIN, "invalid protocol");
231 ret = dgettext(TEXT_DOMAIN, "operation not allowed");
234 ret = dgettext(TEXT_DOMAIN, "bad property value");
236 case SA_INVALID_SECURITY:
237 ret = dgettext(TEXT_DOMAIN, "invalid security type");
239 case SA_NO_SUCH_SECURITY:
240 ret = dgettext(TEXT_DOMAIN, "security type not found");
242 case SA_VALUE_CONFLICT:
243 ret = dgettext(TEXT_DOMAIN, "property value conflict");
245 case SA_NOT_IMPLEMENTED:
246 ret = dgettext(TEXT_DOMAIN, "not implemented");
248 case SA_INVALID_PATH:
249 ret = dgettext(TEXT_DOMAIN, "invalid path");
251 case SA_NOT_SUPPORTED:
252 ret = dgettext(TEXT_DOMAIN, "operation not supported");
254 case SA_PROP_SHARE_ONLY:
255 ret = dgettext(TEXT_DOMAIN, "property not valid for group");
258 ret = dgettext(TEXT_DOMAIN, "not shared");
260 case SA_NO_SUCH_RESOURCE:
261 ret = dgettext(TEXT_DOMAIN, "no such resource");
263 case SA_RESOURCE_REQUIRED:
264 ret = dgettext(TEXT_DOMAIN, "resource name required");
266 case SA_MULTIPLE_ERROR:
267 ret = dgettext(TEXT_DOMAIN, "errors from multiple protocols");
269 case SA_PATH_IS_SUBDIR:
270 ret = dgettext(TEXT_DOMAIN, "path is a subpath of share");
272 case SA_PATH_IS_PARENTDIR:
273 ret = dgettext(TEXT_DOMAIN, "path is parent of a share");
276 ret = dgettext(TEXT_DOMAIN, "protocol requires a section");
278 case SA_NO_PROPERTIES:
279 ret = dgettext(TEXT_DOMAIN, "properties not found");
281 case SA_NO_SUCH_SECTION:
282 ret = dgettext(TEXT_DOMAIN, "section not found");
284 case SA_PASSWORD_ENC:
285 ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted");
287 case SA_SHARE_EXISTS:
288 ret = dgettext(TEXT_DOMAIN, "path or file is already shared");
291 (void) snprintf(errstr, sizeof (errstr),
292 dgettext(TEXT_DOMAIN, "unknown %d"), err);
299 sa_validate_shareopts(char *options, char *proto)
304 while (fstype != NULL) {
305 if (strcmp(fstype->name, proto) != 0) {
306 fstype = fstype->next;
310 return (fstype->ops->validate_shareopts(options));
313 return (SA_INVALID_PROTOCOL);
316 static sa_share_impl_t
317 alloc_share(const char *zfsname, const char *mountpoint)
319 sa_share_impl_t impl_share;
321 impl_share = calloc(1, sizeof (struct sa_share_impl));
323 if (impl_share == NULL)
326 if (mountpoint != NULL &&
327 ((impl_share->sa_mountpoint = strdup(mountpoint)) == NULL)) {
332 if (zfsname != NULL &&
333 ((impl_share->sa_zfsname = strdup(zfsname)) == NULL)) {
334 free(impl_share->sa_mountpoint);
339 impl_share->sa_fsinfo = calloc(fstypes_count,
340 sizeof (sa_share_fsinfo_t));
341 if (impl_share->sa_fsinfo == NULL) {
342 free(impl_share->sa_mountpoint);
343 free(impl_share->sa_zfsname);
352 free_share(sa_share_impl_t impl_share)
357 while (fstype != NULL) {
358 fstype->ops->clear_shareopts(impl_share);
359 fstype = fstype->next;
362 free(impl_share->sa_mountpoint);
363 free(impl_share->sa_zfsname);
364 free(impl_share->sa_fsinfo);