aboutsummaryrefslogtreecommitdiff
path: root/lib/libshare
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libshare')
-rw-r--r--lib/libshare/Makefile.am27
-rw-r--r--lib/libshare/libshare.c204
-rw-r--r--lib/libshare/libshare_impl.h48
-rw-r--r--lib/libshare/nfs.c318
-rw-r--r--lib/libshare/nfs.h38
-rw-r--r--lib/libshare/os/freebsd/nfs.c244
-rw-r--r--lib/libshare/os/freebsd/smb.c87
-rw-r--r--lib/libshare/os/linux/nfs.c587
-rw-r--r--lib/libshare/os/linux/smb.c407
-rw-r--r--lib/libshare/smb.h46
10 files changed, 0 insertions, 2006 deletions
diff --git a/lib/libshare/Makefile.am b/lib/libshare/Makefile.am
deleted file mode 100644
index 48d8cb832428..000000000000
--- a/lib/libshare/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-libshare_la_CFLAGS = $(AM_CFLAGS) $(LIBRARY_CFLAGS)
-libshare_la_CFLAGS += -fvisibility=hidden
-
-libshare_la_CPPFLAGS = $(AM_CPPFLAGS)
-libshare_la_CPPFLAGS += -I$(srcdir)/%D%
-
-noinst_LTLIBRARIES += libshare.la
-CPPCHECKTARGETS += libshare.la
-
-libshare_la_SOURCES = \
- %D%/libshare_impl.h \
- %D%/libshare.c \
- %D%/nfs.c \
- %D%/nfs.h \
- %D%/smb.h
-
-if BUILD_LINUX
-libshare_la_SOURCES += \
- %D%/os/linux/nfs.c \
- %D%/os/linux/smb.c
-endif
-
-if BUILD_FREEBSD
-libshare_la_SOURCES += \
- %D%/os/freebsd/nfs.c \
- %D%/os/freebsd/smb.c
-endif
diff --git a/lib/libshare/libshare.c b/lib/libshare/libshare.c
deleted file mode 100644
index 3695207e6fe7..000000000000
--- a/lib/libshare/libshare.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 Gunnar Beutner
- * Copyright (c) 2018, 2022 by Delphix. All rights reserved.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-#include <libintl.h>
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <libzfs.h>
-#include <libshare.h>
-#include "libshare_impl.h"
-
-#define init_share(zfsname, path, shareopts) \
- { \
- .sa_zfsname = zfsname, \
- .sa_mountpoint = path, \
- .sa_shareopts = shareopts, \
- }
-
-#define VALIDATE_PROTOCOL(proto, ...) \
- if ((proto) < 0 || (proto) >= SA_PROTOCOL_COUNT) \
- return __VA_ARGS__
-
-const char *const sa_protocol_names[SA_PROTOCOL_COUNT] = {
- [SA_PROTOCOL_NFS] = "nfs",
- [SA_PROTOCOL_SMB] = "smb",
-};
-
-static const sa_fstype_t *fstypes[SA_PROTOCOL_COUNT] =
- {&libshare_nfs_type, &libshare_smb_type};
-
-int
-sa_enable_share(const char *zfsname, const char *mountpoint,
- const char *shareopts, enum sa_protocol protocol)
-{
- VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL);
-
- const struct sa_share_impl args =
- init_share(zfsname, mountpoint, shareopts);
- return (fstypes[protocol]->enable_share(&args));
-}
-
-int
-sa_disable_share(const char *mountpoint, enum sa_protocol protocol)
-{
- VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL);
-
- const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
- return (fstypes[protocol]->disable_share(&args));
-}
-
-boolean_t
-sa_is_shared(const char *mountpoint, enum sa_protocol protocol)
-{
- VALIDATE_PROTOCOL(protocol, B_FALSE);
-
- const struct sa_share_impl args = init_share(NULL, mountpoint, NULL);
- return (fstypes[protocol]->is_shared(&args));
-}
-
-void
-sa_commit_shares(enum sa_protocol protocol)
-{
- /* CSTYLED */
- VALIDATE_PROTOCOL(protocol, );
-
- fstypes[protocol]->commit_shares();
-}
-
-void
-sa_truncate_shares(enum sa_protocol protocol)
-{
- /* CSTYLED */
- VALIDATE_PROTOCOL(protocol, );
-
- if (fstypes[protocol]->truncate_shares != NULL)
- fstypes[protocol]->truncate_shares();
-}
-
-int
-sa_validate_shareopts(const char *options, enum sa_protocol protocol)
-{
- VALIDATE_PROTOCOL(protocol, SA_INVALID_PROTOCOL);
-
- return (fstypes[protocol]->validate_shareopts(options));
-}
-
-/*
- * sa_errorstr(err)
- *
- * convert an error value to an error string
- */
-const char *
-sa_errorstr(int err)
-{
- static char errstr[32];
-
- switch (err) {
- case SA_OK:
- return (dgettext(TEXT_DOMAIN, "ok"));
- case SA_NO_SUCH_PATH:
- return (dgettext(TEXT_DOMAIN, "path doesn't exist"));
- case SA_NO_MEMORY:
- return (dgettext(TEXT_DOMAIN, "no memory"));
- case SA_DUPLICATE_NAME:
- return (dgettext(TEXT_DOMAIN, "name in use"));
- case SA_BAD_PATH:
- return (dgettext(TEXT_DOMAIN, "bad path"));
- case SA_NO_SUCH_GROUP:
- return (dgettext(TEXT_DOMAIN, "no such group"));
- case SA_CONFIG_ERR:
- return (dgettext(TEXT_DOMAIN, "configuration error"));
- case SA_SYSTEM_ERR:
- return (dgettext(TEXT_DOMAIN, "system error"));
- case SA_SYNTAX_ERR:
- return (dgettext(TEXT_DOMAIN, "syntax error"));
- case SA_NO_PERMISSION:
- return (dgettext(TEXT_DOMAIN, "no permission"));
- case SA_BUSY:
- return (dgettext(TEXT_DOMAIN, "busy"));
- case SA_NO_SUCH_PROP:
- return (dgettext(TEXT_DOMAIN, "no such property"));
- case SA_INVALID_NAME:
- return (dgettext(TEXT_DOMAIN, "invalid name"));
- case SA_INVALID_PROTOCOL:
- return (dgettext(TEXT_DOMAIN, "invalid protocol"));
- case SA_NOT_ALLOWED:
- return (dgettext(TEXT_DOMAIN, "operation not allowed"));
- case SA_BAD_VALUE:
- return (dgettext(TEXT_DOMAIN, "bad property value"));
- case SA_INVALID_SECURITY:
- return (dgettext(TEXT_DOMAIN, "invalid security type"));
- case SA_NO_SUCH_SECURITY:
- return (dgettext(TEXT_DOMAIN, "security type not found"));
- case SA_VALUE_CONFLICT:
- return (dgettext(TEXT_DOMAIN, "property value conflict"));
- case SA_NOT_IMPLEMENTED:
- return (dgettext(TEXT_DOMAIN, "not implemented"));
- case SA_INVALID_PATH:
- return (dgettext(TEXT_DOMAIN, "invalid path"));
- case SA_NOT_SUPPORTED:
- return (dgettext(TEXT_DOMAIN, "operation not supported"));
- case SA_PROP_SHARE_ONLY:
- return (dgettext(TEXT_DOMAIN, "property not valid for group"));
- case SA_NOT_SHARED:
- return (dgettext(TEXT_DOMAIN, "not shared"));
- case SA_NO_SUCH_RESOURCE:
- return (dgettext(TEXT_DOMAIN, "no such resource"));
- case SA_RESOURCE_REQUIRED:
- return (dgettext(TEXT_DOMAIN, "resource name required"));
- case SA_MULTIPLE_ERROR:
- return (dgettext(TEXT_DOMAIN,
- "errors from multiple protocols"));
- case SA_PATH_IS_SUBDIR:
- return (dgettext(TEXT_DOMAIN, "path is a subpath of share"));
- case SA_PATH_IS_PARENTDIR:
- return (dgettext(TEXT_DOMAIN, "path is parent of a share"));
- case SA_NO_SECTION:
- return (dgettext(TEXT_DOMAIN, "protocol requires a section"));
- case SA_NO_PROPERTIES:
- return (dgettext(TEXT_DOMAIN, "properties not found"));
- case SA_NO_SUCH_SECTION:
- return (dgettext(TEXT_DOMAIN, "section not found"));
- case SA_PASSWORD_ENC:
- return (dgettext(TEXT_DOMAIN, "passwords must be encrypted"));
- case SA_SHARE_EXISTS:
- return (dgettext(TEXT_DOMAIN,
- "path or file is already shared"));
- default:
- (void) snprintf(errstr, sizeof (errstr),
- dgettext(TEXT_DOMAIN, "unknown %d"), err);
- return (errstr);
- }
-}
diff --git a/lib/libshare/libshare_impl.h b/lib/libshare/libshare_impl.h
deleted file mode 100644
index 79f081bb8312..000000000000
--- a/lib/libshare/libshare_impl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 Gunnar Beutner
- * Copyright (c) 2019, 2022 by Delphix. All rights reserved.
- */
-#ifndef _LIBSPL_LIBSHARE_IMPL_H
-#define _LIBSPL_LIBSHARE_IMPL_H
-
-typedef const struct sa_share_impl {
- const char *sa_zfsname;
- const char *sa_mountpoint;
- const char *sa_shareopts;
-} *sa_share_impl_t;
-
-typedef struct {
- int (*const enable_share)(sa_share_impl_t share);
- int (*const disable_share)(sa_share_impl_t share);
- boolean_t (*const is_shared)(sa_share_impl_t share);
- int (*const validate_shareopts)(const char *shareopts);
- int (*const commit_shares)(void);
- void (*const truncate_shares)(void);
-} sa_fstype_t;
-
-extern const sa_fstype_t libshare_nfs_type, libshare_smb_type;
-
-#endif /* _LIBSPL_LIBSHARE_IMPL_H */
diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c
deleted file mode 100644
index e4c5b904f51f..000000000000
--- a/lib/libshare/nfs.c
+++ /dev/null
@@ -1,318 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#include <libshare.h>
-#include <unistd.h>
-#include <libzutil.h>
-#include "nfs.h"
-
-
-/*
- * nfs_exports_[lock|unlock] are used to guard against conconcurrent
- * updates to the exports file. Each protocol is responsible for
- * providing the necessary locking to ensure consistency.
- */
-static int
-nfs_exports_lock(const char *name, int *nfs_lock_fd)
-{
- int err;
-
- *nfs_lock_fd = open(name, O_RDWR | O_CREAT | O_CLOEXEC, 0600);
- if (*nfs_lock_fd == -1) {
- err = errno;
- fprintf(stderr, "failed to lock %s: %s\n", name,
- zfs_strerror(err));
- return (err);
- }
-
- while ((err = flock(*nfs_lock_fd, LOCK_EX)) != 0 && errno == EINTR)
- ;
- if (err != 0) {
- err = errno;
- fprintf(stderr, "failed to lock %s: %s\n", name,
- zfs_strerror(err));
- (void) close(*nfs_lock_fd);
- *nfs_lock_fd = -1;
- return (err);
- }
-
- return (0);
-}
-
-static void
-nfs_exports_unlock(const char *name, int *nfs_lock_fd)
-{
- verify(*nfs_lock_fd > 0);
-
- if (flock(*nfs_lock_fd, LOCK_UN) != 0)
- fprintf(stderr, "failed to unlock %s: %s\n",
- name, zfs_strerror(errno));
-
- (void) close(*nfs_lock_fd);
- *nfs_lock_fd = -1;
-}
-
-struct tmpfile {
- /*
- * This only needs to be as wide as ZFS_EXPORTS_FILE and mktemp suffix,
- * 64 is more than enough.
- */
- char name[64];
- FILE *fp;
-};
-
-static boolean_t
-nfs_init_tmpfile(const char *prefix, const char *mdir, struct tmpfile *tmpf)
-{
- if (mdir != NULL &&
- mkdir(mdir, 0755) < 0 &&
- errno != EEXIST) {
- fprintf(stderr, "failed to create %s: %s\n",
- // cppcheck-suppress uninitvar
- mdir, zfs_strerror(errno));
- return (B_FALSE);
- }
-
- strlcpy(tmpf->name, prefix, sizeof (tmpf->name));
- strlcat(tmpf->name, ".XXXXXXXX", sizeof (tmpf->name));
-
- int fd = mkostemp(tmpf->name, O_CLOEXEC);
- if (fd == -1) {
- fprintf(stderr, "Unable to create temporary file: %s",
- zfs_strerror(errno));
- return (B_FALSE);
- }
-
- tmpf->fp = fdopen(fd, "w+");
- if (tmpf->fp == NULL) {
- fprintf(stderr, "Unable to reopen temporary file: %s",
- zfs_strerror(errno));
- close(fd);
- return (B_FALSE);
- }
-
- return (B_TRUE);
-}
-
-static void
-nfs_abort_tmpfile(struct tmpfile *tmpf)
-{
- unlink(tmpf->name);
- fclose(tmpf->fp);
-}
-
-static int
-nfs_fini_tmpfile(const char *exports, struct tmpfile *tmpf)
-{
- if (fflush(tmpf->fp) != 0) {
- fprintf(stderr, "Failed to write to temporary file: %s\n",
- zfs_strerror(errno));
- nfs_abort_tmpfile(tmpf);
- return (SA_SYSTEM_ERR);
- }
-
- if (rename(tmpf->name, exports) == -1) {
- fprintf(stderr, "Unable to rename %s -> %s: %s\n",
- tmpf->name, exports, zfs_strerror(errno));
- nfs_abort_tmpfile(tmpf);
- return (SA_SYSTEM_ERR);
- }
-
- (void) fchmod(fileno(tmpf->fp), 0644);
- fclose(tmpf->fp);
- return (SA_OK);
-}
-
-int
-nfs_escape_mountpoint(const char *mp, char **out, boolean_t *need_free)
-{
- if (strpbrk(mp, "\t\n\v\f\r \\") == NULL) {
- *out = (char *)mp;
- *need_free = B_FALSE;
- return (SA_OK);
- } else {
- size_t len = strlen(mp);
- *out = malloc(len * 4 + 1);
- if (!*out)
- return (SA_NO_MEMORY);
- *need_free = B_TRUE;
-
- char *oc = *out;
- for (const char *c = mp; c < mp + len; ++c)
- if (memchr("\t\n\v\f\r \\", *c,
- strlen("\t\n\v\f\r \\"))) {
- sprintf(oc, "\\%03hho", *c);
- oc += 4;
- } else
- *oc++ = *c;
- *oc = '\0';
- }
-
- return (SA_OK);
-}
-
-static int
-nfs_process_exports(const char *exports, const char *mountpoint,
- boolean_t (*cbk)(void *userdata, char *line, boolean_t found_mountpoint),
- void *userdata)
-{
- int error = SA_OK;
- boolean_t cont = B_TRUE;
-
- FILE *oldfp = fopen(exports, "re");
- if (oldfp != NULL) {
- boolean_t need_mp_free;
- char *mp;
- if ((error = nfs_escape_mountpoint(mountpoint,
- &mp, &need_mp_free)) != SA_OK) {
- (void) fclose(oldfp);
- return (error);
- }
-
- char *buf = NULL, *sep;
- size_t buflen = 0, mplen = strlen(mp);
-
- while (cont && getline(&buf, &buflen, oldfp) != -1) {
- if (buf[0] == '\n' || buf[0] == '#')
- continue;
-
- cont = cbk(userdata, buf,
- (sep = strpbrk(buf, "\t \n")) != NULL &&
- sep - buf == mplen &&
- strncmp(buf, mp, mplen) == 0);
- }
- free(buf);
- if (need_mp_free)
- free(mp);
-
- if (ferror(oldfp) != 0)
- error = ferror(oldfp);
-
- if (fclose(oldfp) != 0) {
- fprintf(stderr, "Unable to close file %s: %s\n",
- exports, zfs_strerror(errno));
- error = error != SA_OK ? error : SA_SYSTEM_ERR;
- }
- }
-
- return (error);
-}
-
-static boolean_t
-nfs_copy_entries_cb(void *userdata, char *line, boolean_t found_mountpoint)
-{
- FILE *newfp = userdata;
- if (!found_mountpoint)
- fputs(line, newfp);
- return (B_TRUE);
-}
-
-/*
- * Copy all entries from the exports file (if it exists) to newfp,
- * omitting any entries for the specified mountpoint.
- */
-static int
-nfs_copy_entries(FILE *newfp, const char *exports, const char *mountpoint)
-{
- fputs(FILE_HEADER, newfp);
-
- int error = nfs_process_exports(
- exports, mountpoint, nfs_copy_entries_cb, newfp);
-
- if (error == SA_OK && ferror(newfp) != 0)
- error = ferror(newfp);
-
- return (error);
-}
-
-int
-nfs_toggle_share(const char *lockfile, const char *exports,
- const char *expdir, sa_share_impl_t impl_share,
- int(*cbk)(sa_share_impl_t impl_share, FILE *tmpfile))
-{
- int error, nfs_lock_fd = -1;
- struct tmpfile tmpf;
-
- if (!nfs_init_tmpfile(exports, expdir, &tmpf))
- return (SA_SYSTEM_ERR);
-
- error = nfs_exports_lock(lockfile, &nfs_lock_fd);
- if (error != 0) {
- nfs_abort_tmpfile(&tmpf);
- return (error);
- }
-
- error = nfs_copy_entries(tmpf.fp, exports, impl_share->sa_mountpoint);
- if (error != SA_OK)
- goto fullerr;
-
- error = cbk(impl_share, tmpf.fp);
- if (error != SA_OK)
- goto fullerr;
-
- error = nfs_fini_tmpfile(exports, &tmpf);
- nfs_exports_unlock(lockfile, &nfs_lock_fd);
- return (error);
-
-fullerr:
- nfs_abort_tmpfile(&tmpf);
- nfs_exports_unlock(lockfile, &nfs_lock_fd);
- return (error);
-}
-
-void
-nfs_reset_shares(const char *lockfile, const char *exports)
-{
- int nfs_lock_fd = -1;
-
- if (nfs_exports_lock(lockfile, &nfs_lock_fd) == 0) {
- (void) ! truncate(exports, 0);
- nfs_exports_unlock(lockfile, &nfs_lock_fd);
- }
-}
-
-static boolean_t
-nfs_is_shared_cb(void *userdata, char *line, boolean_t found_mountpoint)
-{
- (void) line;
-
- boolean_t *found = userdata;
- *found = found_mountpoint;
- return (!found_mountpoint);
-}
-
-boolean_t
-nfs_is_shared_impl(const char *exports, sa_share_impl_t impl_share)
-{
- boolean_t found = B_FALSE;
- nfs_process_exports(exports, impl_share->sa_mountpoint,
- nfs_is_shared_cb, &found);
- return (found);
-}
diff --git a/lib/libshare/nfs.h b/lib/libshare/nfs.h
deleted file mode 100644
index 1b8ed890d7bd..000000000000
--- a/lib/libshare/nfs.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 Gunnar Beutner
- * Copyright (c) 2022 by Delphix. All rights reserved.
- */
-
-#include "libshare_impl.h"
-
-#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n"
-
-int nfs_escape_mountpoint(const char *mp, char **out, boolean_t *need_free);
-boolean_t nfs_is_shared_impl(const char *exports, sa_share_impl_t impl_share);
-int nfs_toggle_share(const char *lockfile, const char *exports,
- const char *expdir, sa_share_impl_t impl_share,
- int(*cbk)(sa_share_impl_t impl_share, FILE *tmpfile));
-void nfs_reset_shares(const char *lockfile, const char *exports);
diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c
deleted file mode 100644
index 969194f2881a..000000000000
--- a/lib/libshare/os/freebsd/nfs.c
+++ /dev/null
@@ -1,244 +0,0 @@
-// SPDX-License-Identifier: BSD-2-Clause
-/*
- * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Copyright (c) 2020, 2022 by Delphix. All rights reserved.
- */
-
-#include <sys/param.h>
-#include <sys/vfs.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <libutil.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <libintl.h>
-
-#include <libshare.h>
-#include "libshare_impl.h"
-#include "nfs.h"
-
-#define _PATH_MOUNTDPID "/var/run/mountd.pid"
-#define ZFS_EXPORTS_FILE "/etc/zfs/exports"
-#define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock"
-
-/*
- * This function translates options to a format acceptable by exports(5), eg.
- *
- * -ro -network=192.168.0.0 -mask=255.255.255.0 -maproot=0 \
- * zfs.freebsd.org 69.147.83.54
- *
- * Accepted input formats:
- *
- * ro,network=192.168.0.0,mask=255.255.255.0,maproot=0,zfs.freebsd.org
- * ro network=192.168.0.0 mask=255.255.255.0 maproot=0 zfs.freebsd.org
- * -ro,-network=192.168.0.0,-mask=255.255.255.0,-maproot=0,zfs.freebsd.org
- * -ro -network=192.168.0.0 -mask=255.255.255.0 -maproot=0 \
- * zfs.freebsd.org
- *
- * Recognized keywords:
- *
- * ro, maproot, mapall, mask, network, sec, alldirs, public, webnfs,
- * index, quiet
- */
-static int
-translate_opts(char *oldopts, FILE *out)
-{
- static const char *const known_opts[] = { "ro", "maproot", "mapall",
- "mask", "network", "sec", "alldirs", "public", "webnfs", "index",
- "quiet" };
- char *newopts, *o, *s = NULL;
- unsigned int i;
- size_t len, newopts_len;
- int ret;
-
- /*
- * Calculate the length needed for the worst case of a single
- * character option:
- * - Add one to strlen(oldopts) so that the trailing nul is counted
- * as a separator.
- * - Multiply by 3/2 since the single character option plus separator
- * is expanded to 3 characters.
- * - Add one for the trailing nul. Needed for a single repetition of
- * the single character option and certain other cases.
- */
- newopts_len = (strlen(oldopts) + 1) * 3 / 2 + 1;
- newopts = malloc(newopts_len);
- if (newopts == NULL)
- return (EOF);
- newopts[0] = '\0';
- s = oldopts;
- while ((o = strsep(&s, ", ")) != NULL) {
- if (o[0] == '-')
- o++;
- if (o[0] == '\0')
- continue;
- for (i = 0; i < ARRAY_SIZE(known_opts); ++i) {
- len = strlen(known_opts[i]);
- if (strncmp(known_opts[i], o, len) == 0 &&
- (o[len] == '\0' || o[len] == '=')) {
- strlcat(newopts, "-", newopts_len);
- break;
- }
- }
- strlcat(newopts, o, newopts_len);
- strlcat(newopts, " ", newopts_len);
- }
- ret = fputs(newopts, out);
- free(newopts);
- return (ret);
-}
-
-static int
-nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
-{
- const char *shareopts = impl_share->sa_shareopts;
- if (strcmp(shareopts, "on") == 0)
- shareopts = "";
-
- boolean_t need_free, fnd_semi;
- char *mp, *lineopts, *exportopts, *s;
- size_t whitelen;
- int rc = nfs_escape_mountpoint(impl_share->sa_mountpoint, &mp,
- &need_free);
- if (rc != SA_OK)
- return (rc);
-
- lineopts = strdup(shareopts);
- if (lineopts == NULL)
- return (SA_SYSTEM_ERR);
- s = lineopts;
- fnd_semi = B_FALSE;
- while ((exportopts = strsep(&s, ";")) != NULL) {
- if (s != NULL)
- fnd_semi = B_TRUE;
- /* Ignore only whitespace between ';' separated option sets. */
- if (fnd_semi) {
- whitelen = strspn(exportopts, "\t ");
- if (exportopts[whitelen] == '\0')
- continue;
- }
- if (fputs(mp, tmpfile) == EOF ||
- fputc('\t', tmpfile) == EOF ||
- translate_opts(exportopts, tmpfile) == EOF ||
- fputc('\n', tmpfile) == EOF) {
- fprintf(stderr, "failed to write to temporary file\n");
- rc = SA_SYSTEM_ERR;
- break;
- }
- }
- free(lineopts);
-
- if (need_free)
- free(mp);
- return (rc);
-}
-
-static int
-nfs_enable_share(sa_share_impl_t impl_share)
-{
- return (nfs_toggle_share(
- ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share,
- nfs_enable_share_impl));
-}
-
-static int
-nfs_disable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
-{
- (void) impl_share, (void) tmpfile;
- return (SA_OK);
-}
-
-static int
-nfs_disable_share(sa_share_impl_t impl_share)
-{
- return (nfs_toggle_share(
- ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share,
- nfs_disable_share_impl));
-}
-
-static boolean_t
-nfs_is_shared(sa_share_impl_t impl_share)
-{
- return (nfs_is_shared_impl(ZFS_EXPORTS_FILE, impl_share));
-}
-
-static int
-nfs_validate_shareopts(const char *shareopts)
-{
- if (strlen(shareopts) == 0)
- return (SA_SYNTAX_ERR);
- return (SA_OK);
-}
-
-/*
- * Commit the shares by restarting mountd.
- */
-static int
-nfs_commit_shares(void)
-{
- struct pidfh *pfh;
- pid_t mountdpid;
-
-start:
- pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid);
- if (pfh != NULL) {
- /* mountd(8) is not running. */
- pidfile_remove(pfh);
- return (SA_OK);
- }
- if (errno != EEXIST) {
- /* Cannot open pidfile for some reason. */
- return (SA_SYSTEM_ERR);
- }
- if (mountdpid == -1) {
- /* mountd(8) exists, but didn't write the PID yet */
- usleep(500);
- goto start;
- }
- /* We have mountd(8) PID in mountdpid variable. */
- kill(mountdpid, SIGHUP);
- return (SA_OK);
-}
-
-static void
-nfs_truncate_shares(void)
-{
- nfs_reset_shares(ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE);
-}
-
-const sa_fstype_t libshare_nfs_type = {
- .enable_share = nfs_enable_share,
- .disable_share = nfs_disable_share,
- .is_shared = nfs_is_shared,
-
- .validate_shareopts = nfs_validate_shareopts,
- .commit_shares = nfs_commit_shares,
- .truncate_shares = nfs_truncate_shares,
-};
diff --git a/lib/libshare/os/freebsd/smb.c b/lib/libshare/os/freebsd/smb.c
deleted file mode 100644
index c6b8bdde2d41..000000000000
--- a/lib/libshare/os/freebsd/smb.c
+++ /dev/null
@@ -1,87 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2020 by Delphix. All rights reserved.
- */
-
-#include <stdio.h>
-#include <libshare.h>
-#include "libshare_impl.h"
-
-/*
- * Enables SMB sharing for the specified share.
- */
-static int
-smb_enable_share(sa_share_impl_t impl_share)
-{
- (void) impl_share;
- fputs("No SMB support in FreeBSD yet.\n", stderr);
- return (SA_NOT_SUPPORTED);
-}
-/*
- * Disables SMB sharing for the specified share.
- */
-static int
-smb_disable_share(sa_share_impl_t impl_share)
-{
- (void) impl_share;
- fputs("No SMB support in FreeBSD yet.\n", stderr);
- return (SA_NOT_SUPPORTED);
-}
-
-/*
- * Checks whether the specified SMB share options are syntactically correct.
- */
-static int
-smb_validate_shareopts(const char *shareopts)
-{
- (void) shareopts;
- fputs("No SMB support in FreeBSD yet.\n", stderr);
- return (SA_NOT_SUPPORTED);
-}
-
-/*
- * Checks whether a share is currently active.
- */
-static boolean_t
-smb_is_share_active(sa_share_impl_t impl_share)
-{
- (void) impl_share;
- return (B_FALSE);
-}
-
-static int
-smb_update_shares(void)
-{
- /* Not implemented */
- return (0);
-}
-
-const sa_fstype_t libshare_smb_type = {
- .enable_share = smb_enable_share,
- .disable_share = smb_disable_share,
- .is_shared = smb_is_share_active,
-
- .validate_shareopts = smb_validate_shareopts,
- .commit_shares = smb_update_shares,
-};
diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c
deleted file mode 100644
index 6a9bb3788523..000000000000
--- a/lib/libshare/os/linux/nfs.c
+++ /dev/null
@@ -1,587 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 Gunnar Beutner
- * Copyright (c) 2012 Cyril Plisko. All rights reserved.
- * Copyright (c) 2019, 2022 by Delphix. All rights reserved.
- */
-
-#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <libzfs.h>
-#include <libshare.h>
-#include "libshare_impl.h"
-#include "nfs.h"
-
-#define ZFS_EXPORTS_DIR "/etc/exports.d"
-#define ZFS_EXPORTS_FILE ZFS_EXPORTS_DIR"/zfs.exports"
-#define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock"
-
-
-static boolean_t nfs_available(void);
-static boolean_t exports_available(void);
-
-typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value,
- void *cookie);
-
-typedef int (*nfs_host_callback_t)(FILE *tmpfile, const char *sharepath,
- const char *host, const char *security, const char *access, void *cookie);
-
-/*
- * Invokes the specified callback function for each Solaris share option
- * listed in the specified string.
- */
-static int
-foreach_nfs_shareopt(const char *shareopts,
- nfs_shareopt_callback_t callback, void *cookie)
-{
- char *shareopts_dup, *opt, *cur, *value;
- int was_nul, error;
-
- if (shareopts == NULL)
- return (SA_OK);
-
- if (strcmp(shareopts, "on") == 0)
- shareopts = "rw,crossmnt";
-
- shareopts_dup = strdup(shareopts);
-
-
- if (shareopts_dup == NULL)
- return (SA_NO_MEMORY);
-
- opt = shareopts_dup;
- was_nul = 0;
-
- while (1) {
- cur = opt;
-
- while (*cur != ',' && *cur != '\0')
- cur++;
-
- if (*cur == '\0')
- was_nul = 1;
-
- *cur = '\0';
-
- if (cur > opt) {
- value = strchr(opt, '=');
-
- if (value != NULL) {
- *value = '\0';
- value++;
- }
-
- error = callback(opt, value, cookie);
-
- if (error != SA_OK) {
- free(shareopts_dup);
- return (error);
- }
- }
-
- opt = cur + 1;
-
- if (was_nul)
- break;
- }
-
- free(shareopts_dup);
-
- return (SA_OK);
-}
-
-typedef struct nfs_host_cookie_s {
- nfs_host_callback_t callback;
- const char *sharepath;
- void *cookie;
- FILE *tmpfile;
- const char *security;
-} nfs_host_cookie_t;
-
-/*
- * Helper function for foreach_nfs_host. This function checks whether the
- * current share option is a host specification and invokes a callback
- * function with information about the host.
- */
-static int
-foreach_nfs_host_cb(const char *opt, const char *value, void *pcookie)
-{
- int error;
- const char *access;
- char *host_dup, *host, *next, *v6Literal;
- nfs_host_cookie_t *udata = (nfs_host_cookie_t *)pcookie;
- int cidr_len;
-
-#ifdef DEBUG
- fprintf(stderr, "foreach_nfs_host_cb: key=%s, value=%s\n", opt, value);
-#endif
-
- if (strcmp(opt, "sec") == 0)
- udata->security = value;
-
- if (strcmp(opt, "rw") == 0 || strcmp(opt, "ro") == 0) {
- if (value == NULL)
- value = "*";
-
- access = opt;
-
- host_dup = strdup(value);
-
- if (host_dup == NULL)
- return (SA_NO_MEMORY);
-
- host = host_dup;
-
- do {
- if (*host == '[') {
- host++;
- v6Literal = strchr(host, ']');
- if (v6Literal == NULL) {
- free(host_dup);
- return (SA_SYNTAX_ERR);
- }
- if (v6Literal[1] == '\0') {
- *v6Literal = '\0';
- next = NULL;
- } else if (v6Literal[1] == '/') {
- next = strchr(v6Literal + 2, ':');
- if (next == NULL) {
- cidr_len =
- strlen(v6Literal + 1);
- memmove(v6Literal,
- v6Literal + 1,
- cidr_len);
- v6Literal[cidr_len] = '\0';
- } else {
- cidr_len = next - v6Literal - 1;
- memmove(v6Literal,
- v6Literal + 1,
- cidr_len);
- v6Literal[cidr_len] = '\0';
- next++;
- }
- } else if (v6Literal[1] == ':') {
- *v6Literal = '\0';
- next = v6Literal + 2;
- } else {
- free(host_dup);
- return (SA_SYNTAX_ERR);
- }
- } else {
- next = strchr(host, ':');
- if (next != NULL) {
- *next = '\0';
- next++;
- }
- }
-
- error = udata->callback(udata->tmpfile,
- udata->sharepath, host, udata->security,
- access, udata->cookie);
-
- if (error != SA_OK) {
- free(host_dup);
-
- return (error);
- }
-
- host = next;
- } while (host != NULL);
-
- free(host_dup);
- }
-
- return (SA_OK);
-}
-
-/*
- * Invokes a callback function for all NFS hosts that are set for a share.
- */
-static int
-foreach_nfs_host(sa_share_impl_t impl_share, FILE *tmpfile,
- nfs_host_callback_t callback, void *cookie)
-{
- nfs_host_cookie_t udata;
-
- udata.callback = callback;
- udata.sharepath = impl_share->sa_mountpoint;
- udata.cookie = cookie;
- udata.tmpfile = tmpfile;
- udata.security = "sys";
-
- return (foreach_nfs_shareopt(impl_share->sa_shareopts,
- foreach_nfs_host_cb, &udata));
-}
-
-/*
- * Converts a Solaris NFS host specification to its Linux equivalent.
- */
-static const char *
-get_linux_hostspec(const char *solaris_hostspec)
-{
- /*
- * For now we just support CIDR masks (e.g. @192.168.0.0/16) and host
- * wildcards (e.g. *.example.org).
- */
- if (solaris_hostspec[0] == '@') {
- /*
- * Solaris host specifier, e.g. @192.168.0.0/16; we just need
- * to skip the @ in this case
- */
- return (solaris_hostspec + 1);
- } else {
- return (solaris_hostspec);
- }
-}
-
-/*
- * Adds a Linux share option to an array of NFS options.
- */
-static int
-add_linux_shareopt(char **plinux_opts, const char *key, const char *value)
-{
- size_t len = 0;
- char *new_linux_opts;
-
- if (*plinux_opts != NULL)
- len = strlen(*plinux_opts);
-
- new_linux_opts = realloc(*plinux_opts, len + 1 + strlen(key) +
- (value ? 1 + strlen(value) : 0) + 1);
-
- if (new_linux_opts == NULL)
- return (SA_NO_MEMORY);
-
- new_linux_opts[len] = '\0';
-
- if (len > 0)
- strcat(new_linux_opts, ",");
-
- strcat(new_linux_opts, key);
-
- if (value != NULL) {
- strcat(new_linux_opts, "=");
- strcat(new_linux_opts, value);
- }
-
- *plinux_opts = new_linux_opts;
-
- return (SA_OK);
-}
-
-static int string_cmp(const void *lhs, const void *rhs) {
- const char *const *l = lhs, *const *r = rhs;
- return (strcmp(*l, *r));
-}
-
-/*
- * Validates and converts a single Solaris share option to its Linux
- * equivalent.
- */
-static int
-get_linux_shareopts_cb(const char *key, const char *value, void *cookie)
-{
- /* This list must remain sorted, since we bsearch() it */
- static const char *const valid_keys[] = { "all_squash", "anongid",
- "anonuid", "async", "auth_nlm", "crossmnt", "fsid", "fsuid", "hide",
- "insecure", "insecure_locks", "mountpoint", "mp", "no_acl",
- "no_all_squash", "no_auth_nlm", "no_root_squash",
- "no_subtree_check", "no_wdelay", "nohide", "refer", "replicas",
- "root_squash", "secure", "secure_locks", "subtree_check", "sync",
- "wdelay" };
-
- char **plinux_opts = (char **)cookie;
- char *host, *val_dup, *literal, *next;
-
- if (strcmp(key, "sec") == 0)
- return (SA_OK);
-
- if (strcmp(key, "ro") == 0 || strcmp(key, "rw") == 0) {
- if (value == NULL || strlen(value) == 0)
- return (SA_OK);
- val_dup = strdup(value);
- host = val_dup;
- if (host == NULL)
- return (SA_NO_MEMORY);
- do {
- if (*host == '[') {
- host++;
- literal = strchr(host, ']');
- if (literal == NULL) {
- free(val_dup);
- return (SA_SYNTAX_ERR);
- }
- if (literal[1] == '\0')
- next = NULL;
- else if (literal[1] == '/') {
- next = strchr(literal + 2, ':');
- if (next != NULL)
- ++next;
- } else if (literal[1] == ':')
- next = literal + 2;
- else {
- free(val_dup);
- return (SA_SYNTAX_ERR);
- }
- } else {
- next = strchr(host, ':');
- if (next != NULL)
- ++next;
- }
- host = next;
- } while (host != NULL);
- free(val_dup);
- return (SA_OK);
- }
-
- if (strcmp(key, "anon") == 0)
- key = "anonuid";
-
- if (strcmp(key, "root_mapping") == 0) {
- (void) add_linux_shareopt(plinux_opts, "root_squash", NULL);
- key = "anonuid";
- }
-
- if (strcmp(key, "nosub") == 0)
- key = "subtree_check";
-
- if (bsearch(&key, valid_keys, ARRAY_SIZE(valid_keys),
- sizeof (*valid_keys), string_cmp) == NULL)
- return (SA_SYNTAX_ERR);
-
- (void) add_linux_shareopt(plinux_opts, key, value);
-
- return (SA_OK);
-}
-
-/*
- * Takes a string containing Solaris share options (e.g. "sync,no_acl") and
- * converts them to a NULL-terminated array of Linux NFS options.
- */
-static int
-get_linux_shareopts(const char *shareopts, char **plinux_opts)
-{
- int error;
-
- assert(plinux_opts != NULL);
-
- *plinux_opts = NULL;
-
- /* no_subtree_check - Default as of nfs-utils v1.1.0 */
- (void) add_linux_shareopt(plinux_opts, "no_subtree_check", NULL);
-
- /* mountpoint - Restrict exports to ZFS mountpoints */
- (void) add_linux_shareopt(plinux_opts, "mountpoint", NULL);
-
- error = foreach_nfs_shareopt(shareopts, get_linux_shareopts_cb,
- plinux_opts);
-
- if (error != SA_OK) {
- free(*plinux_opts);
- *plinux_opts = NULL;
- }
-
- return (error);
-}
-
-/*
- * This function populates an entry into /etc/exports.d/zfs.exports.
- * This file is consumed by the linux nfs server so that zfs shares are
- * automatically exported upon boot or whenever the nfs server restarts.
- */
-static int
-nfs_add_entry(FILE *tmpfile, const char *sharepath,
- const char *host, const char *security, const char *access_opts,
- void *pcookie)
-{
- const char *linux_opts = (const char *)pcookie;
-
- if (linux_opts == NULL)
- linux_opts = "";
-
- boolean_t need_free;
- char *mp;
- int rc = nfs_escape_mountpoint(sharepath, &mp, &need_free);
- if (rc != SA_OK)
- return (rc);
- if (fprintf(tmpfile, "%s %s(sec=%s,%s,%s)\n", mp,
- get_linux_hostspec(host), security, access_opts,
- linux_opts) < 0) {
- fprintf(stderr, "failed to write to temporary file\n");
- rc = SA_SYSTEM_ERR;
- }
-
- if (need_free)
- free(mp);
- return (rc);
-}
-
-/*
- * Enables NFS sharing for the specified share.
- */
-static int
-nfs_enable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
-{
- char *linux_opts = NULL;
- int error = get_linux_shareopts(impl_share->sa_shareopts, &linux_opts);
- if (error != SA_OK)
- return (error);
-
- error = foreach_nfs_host(impl_share, tmpfile, nfs_add_entry,
- linux_opts);
- free(linux_opts);
- return (error);
-}
-
-static int
-nfs_enable_share(sa_share_impl_t impl_share)
-{
- if (!nfs_available())
- return (SA_SYSTEM_ERR);
-
- return (nfs_toggle_share(
- ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share,
- nfs_enable_share_impl));
-}
-
-/*
- * Disables NFS sharing for the specified share.
- */
-static int
-nfs_disable_share_impl(sa_share_impl_t impl_share, FILE *tmpfile)
-{
- (void) impl_share, (void) tmpfile;
- return (SA_OK);
-}
-
-static int
-nfs_disable_share(sa_share_impl_t impl_share)
-{
- if (!nfs_available())
- return (SA_OK);
-
- return (nfs_toggle_share(
- ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share,
- nfs_disable_share_impl));
-}
-
-static boolean_t
-nfs_is_shared(sa_share_impl_t impl_share)
-{
- if (!nfs_available())
- return (SA_SYSTEM_ERR);
-
- return (nfs_is_shared_impl(ZFS_EXPORTS_FILE, impl_share));
-}
-
-/*
- * Checks whether the specified NFS share options are syntactically correct.
- */
-static int
-nfs_validate_shareopts(const char *shareopts)
-{
- char *linux_opts = NULL;
-
- if (strlen(shareopts) == 0)
- return (SA_SYNTAX_ERR);
-
- int error = get_linux_shareopts(shareopts, &linux_opts);
- if (error != SA_OK)
- return (error);
-
- free(linux_opts);
- return (SA_OK);
-}
-
-static int
-nfs_commit_shares(void)
-{
- if (!nfs_available())
- return (SA_SYSTEM_ERR);
-
- char *argv[] = {
- (char *)"/usr/sbin/exportfs",
- (char *)"-ra",
- NULL
- };
-
- return (libzfs_run_process(argv[0], argv, 0));
-}
-
-static void
-nfs_truncate_shares(void)
-{
- if (!exports_available())
- return;
- nfs_reset_shares(ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE);
-}
-
-const sa_fstype_t libshare_nfs_type = {
- .enable_share = nfs_enable_share,
- .disable_share = nfs_disable_share,
- .is_shared = nfs_is_shared,
-
- .validate_shareopts = nfs_validate_shareopts,
- .commit_shares = nfs_commit_shares,
- .truncate_shares = nfs_truncate_shares,
-};
-
-static boolean_t
-nfs_available(void)
-{
- static int avail;
-
- if (!avail) {
- if (access("/usr/sbin/exportfs", F_OK) != 0)
- avail = -1;
- else
- avail = 1;
- }
-
- return (avail == 1);
-}
-
-static boolean_t
-exports_available(void)
-{
- static int avail;
-
- if (!avail) {
- if (access(ZFS_EXPORTS_DIR, F_OK) != 0)
- avail = -1;
- else
- avail = 1;
- }
-
- return (avail == 1);
-}
diff --git a/lib/libshare/os/linux/smb.c b/lib/libshare/os/linux/smb.c
deleted file mode 100644
index 40996ecc8f89..000000000000
--- a/lib/libshare/os/linux/smb.c
+++ /dev/null
@@ -1,407 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011,2012 Turbo Fredriksson <turbo@bayour.com>, based on nfs.c
- * by Gunnar Beutner
- * Copyright (c) 2019, 2020 by Delphix. All rights reserved.
- *
- * This is an addition to the zfs device driver to add, modify and remove SMB
- * shares using the 'net share' command that comes with Samba.
- *
- * TESTING
- * Make sure that samba listens to 'localhost' (127.0.0.1) and that the options
- * 'usershare max shares' and 'usershare owner only' have been reviewed/set
- * accordingly (see zfs(8) for information).
- *
- * Once configuration in samba have been done, test that this
- * works with the following three commands (in this case, my ZFS
- * filesystem is called 'share/Test1'):
- *
- * (root)# net -U root -S 127.0.0.1 usershare add Test1 /share/Test1 \
- * "Comment: /share/Test1" "Everyone:F"
- * (root)# net usershare list | grep -i test
- * (root)# net -U root -S 127.0.0.1 usershare delete Test1
- *
- * The first command will create a user share that gives everyone full access.
- * To limit the access below that, use normal UNIX commands (chmod, chown etc).
- */
-
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <libzfs.h>
-#include <libshare.h>
-#include "libshare_impl.h"
-#include "smb.h"
-
-static boolean_t smb_available(void);
-
-static smb_share_t *smb_shares;
-static int smb_disable_share(sa_share_impl_t impl_share);
-static boolean_t smb_is_share_active(sa_share_impl_t impl_share);
-
-/*
- * Retrieve the list of SMB shares.
- */
-static int
-smb_retrieve_shares(void)
-{
- int rc = SA_OK;
- char file_path[PATH_MAX], line[512], *token, *key, *value;
- char *dup_value = NULL, *path = NULL, *comment = NULL, *name = NULL;
- char *guest_ok = NULL;
- DIR *shares_dir;
- FILE *share_file_fp = NULL;
- struct dirent *directory;
- struct stat eStat;
- smb_share_t *shares, *new_shares = NULL;
-
- /* opendir(), stat() */
- shares_dir = opendir(SHARE_DIR);
- if (shares_dir == NULL)
- return (SA_SYSTEM_ERR);
-
- /* Go through the directory, looking for shares */
- while ((directory = readdir(shares_dir))) {
- int fd;
-
- if (directory->d_name[0] == '.')
- continue;
-
- snprintf(file_path, sizeof (file_path),
- "%s/%s", SHARE_DIR, directory->d_name);
-
- if ((fd = open(file_path, O_RDONLY | O_CLOEXEC)) == -1) {
- rc = SA_SYSTEM_ERR;
- goto out;
- }
-
- if (fstat(fd, &eStat) == -1) {
- close(fd);
- rc = SA_SYSTEM_ERR;
- goto out;
- }
-
- if (!S_ISREG(eStat.st_mode)) {
- close(fd);
- continue;
- }
-
- if ((share_file_fp = fdopen(fd, "r")) == NULL) {
- close(fd);
- rc = SA_SYSTEM_ERR;
- goto out;
- }
-
- name = strdup(directory->d_name);
- if (name == NULL) {
- rc = SA_NO_MEMORY;
- goto out;
- }
-
- while (fgets(line, sizeof (line), share_file_fp)) {
- if (line[0] == '#')
- continue;
-
- /* Trim trailing new-line character(s). */
- while (line[strlen(line) - 1] == '\r' ||
- line[strlen(line) - 1] == '\n')
- line[strlen(line) - 1] = '\0';
-
- /* Split the line in two, separated by '=' */
- token = strchr(line, '=');
- if (token == NULL)
- continue;
-
- key = line;
- value = token + 1;
- *token = '\0';
-
- dup_value = strdup(value);
- if (dup_value == NULL) {
- rc = SA_NO_MEMORY;
- goto out;
- }
-
- if (strcmp(key, "path") == 0) {
- free(path);
- path = dup_value;
- } else if (strcmp(key, "comment") == 0) {
- free(comment);
- comment = dup_value;
- } else if (strcmp(key, "guest_ok") == 0) {
- free(guest_ok);
- guest_ok = dup_value;
- } else
- free(dup_value);
-
- dup_value = NULL;
-
- if (path == NULL || comment == NULL || guest_ok == NULL)
- continue; /* Incomplete share definition */
- else {
- shares = (smb_share_t *)
- malloc(sizeof (smb_share_t));
- if (shares == NULL) {
- rc = SA_NO_MEMORY;
- goto out;
- }
-
- (void) strlcpy(shares->name, name,
- sizeof (shares->name));
-
- (void) strlcpy(shares->path, path,
- sizeof (shares->path));
-
- (void) strlcpy(shares->comment, comment,
- sizeof (shares->comment));
-
- shares->guest_ok = atoi(guest_ok);
-
- shares->next = new_shares;
- new_shares = shares;
-
- free(path);
- free(comment);
- free(guest_ok);
-
- path = NULL;
- comment = NULL;
- guest_ok = NULL;
- }
- }
-
-out:
- if (share_file_fp != NULL) {
- fclose(share_file_fp);
- share_file_fp = NULL;
- }
-
- free(name);
- free(path);
- free(comment);
- free(guest_ok);
-
- name = NULL;
- path = NULL;
- comment = NULL;
- guest_ok = NULL;
- }
- closedir(shares_dir);
-
- smb_shares = new_shares;
-
- return (rc);
-}
-
-/*
- * Used internally by smb_enable_share to enable sharing for a single host.
- */
-static int
-smb_enable_share_one(const char *sharename, const char *sharepath)
-{
- char name[SMB_NAME_MAX], comment[SMB_COMMENT_MAX];
-
- /* Support ZFS share name regexp '[[:alnum:]_-.: ]' */
- strlcpy(name, sharename, sizeof (name));
- for (char *itr = name; *itr != '\0'; ++itr)
- switch (*itr) {
- case '/':
- case '-':
- case ':':
- case ' ':
- *itr = '_';
- }
-
- /*
- * CMD: net -S NET_CMD_ARG_HOST usershare add Test1 /share/Test1 \
- * "Comment" "Everyone:F"
- */
- snprintf(comment, sizeof (comment), "Comment: %s", sharepath);
-
- char *argv[] = {
- (char *)NET_CMD_PATH,
- (char *)"-S",
- (char *)NET_CMD_ARG_HOST,
- (char *)"usershare",
- (char *)"add",
- name,
- (char *)sharepath,
- comment,
- (char *)"Everyone:F",
- NULL,
- };
-
- if (libzfs_run_process(argv[0], argv, 0) != 0)
- return (SA_SYSTEM_ERR);
-
- /* Reload the share file */
- (void) smb_retrieve_shares();
-
- return (SA_OK);
-}
-
-/*
- * Enables SMB sharing for the specified share.
- */
-static int
-smb_enable_share(sa_share_impl_t impl_share)
-{
- if (!smb_available())
- return (SA_SYSTEM_ERR);
-
- if (smb_is_share_active(impl_share))
- smb_disable_share(impl_share);
-
- if (impl_share->sa_shareopts == NULL) /* on/off */
- return (SA_SYSTEM_ERR);
-
- if (strcmp(impl_share->sa_shareopts, "off") == 0)
- return (SA_OK);
-
- /* Magic: Enable (i.e., 'create new') share */
- return (smb_enable_share_one(impl_share->sa_zfsname,
- impl_share->sa_mountpoint));
-}
-
-/*
- * Used internally by smb_disable_share to disable sharing for a single host.
- */
-static int
-smb_disable_share_one(const char *sharename)
-{
- /* CMD: net -S NET_CMD_ARG_HOST usershare delete Test1 */
- char *argv[] = {
- (char *)NET_CMD_PATH,
- (char *)"-S",
- (char *)NET_CMD_ARG_HOST,
- (char *)"usershare",
- (char *)"delete",
- (char *)sharename,
- NULL,
- };
-
- if (libzfs_run_process(argv[0], argv, 0) != 0)
- return (SA_SYSTEM_ERR);
- else
- return (SA_OK);
-}
-
-/*
- * Disables SMB sharing for the specified share.
- */
-static int
-smb_disable_share(sa_share_impl_t impl_share)
-{
- if (!smb_available()) {
- /*
- * The share can't possibly be active, so nothing
- * needs to be done to disable it.
- */
- return (SA_OK);
- }
-
- for (const smb_share_t *i = smb_shares; i != NULL; i = i->next)
- if (strcmp(impl_share->sa_mountpoint, i->path) == 0)
- return (smb_disable_share_one(i->name));
-
- return (SA_OK);
-}
-
-/*
- * Checks whether the specified SMB share options are syntactically correct.
- */
-static int
-smb_validate_shareopts(const char *shareopts)
-{
- /* TODO: Accept 'name' and sec/acl (?) */
- if ((strcmp(shareopts, "off") == 0) || (strcmp(shareopts, "on") == 0))
- return (SA_OK);
-
- return (SA_SYNTAX_ERR);
-}
-
-/*
- * Checks whether a share is currently active.
- */
-static boolean_t
-smb_is_share_active(sa_share_impl_t impl_share)
-{
- if (!smb_available())
- return (B_FALSE);
-
- /* Retrieve the list of (possible) active shares */
- smb_retrieve_shares();
-
- for (const smb_share_t *i = smb_shares; i != NULL; i = i->next)
- if (strcmp(impl_share->sa_mountpoint, i->path) == 0)
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-static int
-smb_update_shares(void)
-{
- /* Not implemented */
- return (0);
-}
-
-const sa_fstype_t libshare_smb_type = {
- .enable_share = smb_enable_share,
- .disable_share = smb_disable_share,
- .is_shared = smb_is_share_active,
-
- .validate_shareopts = smb_validate_shareopts,
- .commit_shares = smb_update_shares,
-};
-
-/*
- * Provides a convenient wrapper for determining SMB availability
- */
-static boolean_t
-smb_available(void)
-{
- static int avail;
-
- if (!avail) {
- struct stat statbuf;
-
- if (access(NET_CMD_PATH, F_OK) != 0 ||
- lstat(SHARE_DIR, &statbuf) != 0 ||
- !S_ISDIR(statbuf.st_mode))
- avail = -1;
- else
- avail = 1;
- }
-
- return (avail == 1);
-}
diff --git a/lib/libshare/smb.h b/lib/libshare/smb.h
deleted file mode 100644
index 79e67bd7c45a..000000000000
--- a/lib/libshare/smb.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or https://opensource.org/licenses/CDDL-1.0.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2011 Turbo Fredriksson <turbo@bayour.com>.
- */
-
-/*
- * The maximum SMB share name seems to be 254 characters, though good
- * references are hard to find.
- */
-
-#define SMB_NAME_MAX 255
-#define SMB_COMMENT_MAX 255
-
-#define SHARE_DIR "/var/lib/samba/usershares"
-#define NET_CMD_PATH "/usr/bin/net"
-#define NET_CMD_ARG_HOST "127.0.0.1"
-
-typedef struct smb_share_s {
- char name[SMB_NAME_MAX]; /* Share name */
- char path[PATH_MAX]; /* Share path */
- char comment[SMB_COMMENT_MAX]; /* Share's comment */
- boolean_t guest_ok; /* 'y' or 'n' */
-
- struct smb_share_s *next;
-} smb_share_t;