5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27 * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
28 * Copyright 2017 RackTop Systems.
29 */
30
31 #include <stdio.h>
32 #include <libzfs.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <errno.h>
36 #include <libshare.h>
37 #include "libshare_impl.h"
38 #include <libintl.h>
39 #include <sys/mnttab.h>
40 #include <sys/mntent.h>
41 #include <assert.h>
42
43 extern sa_share_t _sa_add_share(sa_group_t, char *, int, int *, uint64_t);
44 extern sa_group_t _sa_create_zfs_group(sa_group_t, char *);
45 extern char *sa_fstype(char *);
46 extern void set_node_attr(void *, char *, char *);
47 extern int sa_is_share(void *);
48 extern void sa_update_sharetab_ts(sa_handle_t);
49
50 /*
51 * File system specific code for ZFS. The original code was stolen
52 * from the "zfs" command and modified to better suit this library's
53 * usage.
54 */
55
221 char mountb[MAXPATHLEN];
222
223 verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
224 sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
225 verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
226 sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
227
228 return (strcmp(mounta, mountb));
229 }
230
231 /*
232 * return legacy mountpoint. Caller provides space for mountpoint and
233 * dataset.
234 */
235 int
236 get_legacy_mountpoint(const char *path, char *dataset, size_t dlen,
237 char *mountpoint, size_t mlen)
238 {
239 FILE *fp;
240 struct mnttab entry;
241
242 if ((fp = fopen(MNTTAB, "r")) == NULL) {
243 return (1);
244 }
245
246 while (getmntent(fp, &entry) == 0) {
247
248 if (entry.mnt_fstype == NULL ||
249 strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
250 continue;
251
252 if (strcmp(entry.mnt_mountp, path) == 0) {
253 if (mlen > 0)
254 (void) strlcpy(mountpoint, entry.mnt_mountp,
255 mlen);
256 if (dlen > 0)
257 (void) strlcpy(dataset, entry.mnt_special,
258 dlen);
259 break;
260 }
261 }
262 (void) fclose(fp);
263 return (1);
264 }
265
266
267 /*
268 * Verifies that a specific zfs filesystem handle meets the criteria necessary
269 * to be used by libshare operations. See get_zfs_dataset.
270 */
271 static char *
272 verify_zfs_handle(zfs_handle_t *hdl, const char *path, boolean_t search_mnttab)
273 {
274 char mountpoint[ZFS_MAXPROPLEN];
275 char canmount[ZFS_MAXPROPLEN] = { 0 };
276 /* must have a mountpoint */
277 if (zfs_prop_get(hdl, ZFS_PROP_MOUNTPOINT, mountpoint,
278 sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
279 /* no mountpoint */
280 return (NULL);
281 }
282
283 /* mountpoint must be a path */
800 B_FALSE) != 0)
801 return (SA_SYSTEM_ERR);
802
803 if (path != NULL)
804 (void) strncpy(path, mountpoint, sizeof (mountpoint));
805 /*
806 * zfs_get_name value must not be freed. It is just a
807 * pointer to a value in the handle.
808 */
809 if ((dataset = (char *)zfs_get_name(fs_handle)) == NULL)
810 return (SA_SYSTEM_ERR);
811
812 /*
813 * only deal with "mounted" file systems since
814 * unmounted file systems can't actually be shared.
815 */
816
817 if (!zfs_is_mounted(fs_handle, NULL))
818 return (SA_SYSTEM_ERR);
819
820 nfs = nfs_inherited = B_FALSE;
821
822 if (zfs_prop_get(fs_handle, ZFS_PROP_SHARENFS, nfsshareopts,
823 sizeof (nfsshareopts), &source, nfssourcestr,
824 ZFS_MAXPROPLEN, B_FALSE) == 0 &&
825 strcmp(nfsshareopts, "off") != 0) {
826 if (source & ZPROP_SRC_INHERITED)
827 nfs_inherited = B_TRUE;
828 else
829 nfs = B_TRUE;
830 }
831
832 smb = smb_inherited = B_FALSE;
833 if (zfs_prop_get(fs_handle, ZFS_PROP_SHARESMB, smbshareopts,
834 sizeof (smbshareopts), &source, smbsourcestr,
835 ZFS_MAXPROPLEN, B_FALSE) == 0 &&
836 strcmp(smbshareopts, "off") != 0) {
837 if (source & ZPROP_SRC_INHERITED)
838 smb_inherited = B_TRUE;
839 else
958 if (zfsgroup == NULL)
959 return (SA_OK);
960
961 /*
962 * need to walk the mounted ZFS pools and datasets to
963 * find shares that are possible.
964 */
965 get_all_filesystems((sa_handle_impl_t)handle, &zlist, &count);
966 qsort(zlist, count, sizeof (void *), mountpoint_compare);
967
968 for (int i = 0; i < count; i++) {
969 err = sa_get_zfs_share_common(handle, zlist[i], NULL, zfsgroup);
970 }
971 /*
972 * Don't need to free the "zlist" variable since it is only a
973 * pointer to a cached value that will be freed when
974 * sa_fini() is called.
975 */
976 return (err);
977 }
978
979 /*
980 * Initializes only the handles specified in the sharearg for use with libshare.
981 * This is used as a performance optimization relative to sa_get_zfs_shares.
982 */
983 int
984 sa_get_one_zfs_share(sa_handle_t handle, char *groupname,
985 sa_init_selective_arg_t *sharearg, char ***paths, size_t *paths_len)
986 {
987 sa_group_t zfsgroup;
988 libzfs_handle_t *zfs_libhandle;
989 int err;
990
991 if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
992 &zfsgroup, &err)) != SA_OK) {
993 return (err);
994 }
995 /* Not an error, this could be a legacy condition */
996 if (zfsgroup == NULL)
997 return (SA_OK);
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
28 * Copyright 2017 RackTop Systems.
29 * Copyright 2019 Nexenta Systems, Inc.
30 */
31
32 #include <stdio.h>
33 #include <libzfs.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <errno.h>
37 #include <zone.h>
38 #include <libshare.h>
39 #include "libshare_impl.h"
40 #include <libintl.h>
41 #include <sys/mnttab.h>
42 #include <sys/mntent.h>
43 #include <assert.h>
44
45 extern sa_share_t _sa_add_share(sa_group_t, char *, int, int *, uint64_t);
46 extern sa_group_t _sa_create_zfs_group(sa_group_t, char *);
47 extern char *sa_fstype(char *);
48 extern void set_node_attr(void *, char *, char *);
49 extern int sa_is_share(void *);
50 extern void sa_update_sharetab_ts(sa_handle_t);
51
52 /*
53 * File system specific code for ZFS. The original code was stolen
54 * from the "zfs" command and modified to better suit this library's
55 * usage.
56 */
57
223 char mountb[MAXPATHLEN];
224
225 verify(zfs_prop_get(*za, ZFS_PROP_MOUNTPOINT, mounta,
226 sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0);
227 verify(zfs_prop_get(*zb, ZFS_PROP_MOUNTPOINT, mountb,
228 sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0);
229
230 return (strcmp(mounta, mountb));
231 }
232
233 /*
234 * return legacy mountpoint. Caller provides space for mountpoint and
235 * dataset.
236 */
237 int
238 get_legacy_mountpoint(const char *path, char *dataset, size_t dlen,
239 char *mountpoint, size_t mlen)
240 {
241 FILE *fp;
242 struct mnttab entry;
243 int rc = 1;
244
245 if ((fp = fopen(MNTTAB, "r")) == NULL) {
246 return (1);
247 }
248
249 while (getmntent(fp, &entry) == 0) {
250
251 if (entry.mnt_fstype == NULL ||
252 strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
253 continue;
254
255 if (strcmp(entry.mnt_mountp, path) == 0) {
256 if (mlen > 0)
257 (void) strlcpy(mountpoint, entry.mnt_mountp,
258 mlen);
259 if (dlen > 0)
260 (void) strlcpy(dataset, entry.mnt_special,
261 dlen);
262 rc = 0;
263 break;
264 }
265 }
266 (void) fclose(fp);
267 return (rc);
268 }
269
270
271 /*
272 * Verifies that a specific zfs filesystem handle meets the criteria necessary
273 * to be used by libshare operations. See get_zfs_dataset.
274 */
275 static char *
276 verify_zfs_handle(zfs_handle_t *hdl, const char *path, boolean_t search_mnttab)
277 {
278 char mountpoint[ZFS_MAXPROPLEN];
279 char canmount[ZFS_MAXPROPLEN] = { 0 };
280 /* must have a mountpoint */
281 if (zfs_prop_get(hdl, ZFS_PROP_MOUNTPOINT, mountpoint,
282 sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
283 /* no mountpoint */
284 return (NULL);
285 }
286
287 /* mountpoint must be a path */
804 B_FALSE) != 0)
805 return (SA_SYSTEM_ERR);
806
807 if (path != NULL)
808 (void) strncpy(path, mountpoint, sizeof (mountpoint));
809 /*
810 * zfs_get_name value must not be freed. It is just a
811 * pointer to a value in the handle.
812 */
813 if ((dataset = (char *)zfs_get_name(fs_handle)) == NULL)
814 return (SA_SYSTEM_ERR);
815
816 /*
817 * only deal with "mounted" file systems since
818 * unmounted file systems can't actually be shared.
819 */
820
821 if (!zfs_is_mounted(fs_handle, NULL))
822 return (SA_SYSTEM_ERR);
823
824 /*
825 * Ignore "zoned" datasets in global zone.
826 */
827 if (getzoneid() == GLOBAL_ZONEID &&
828 zfs_prop_get_int(fs_handle, ZFS_PROP_ZONED))
829 return (SA_SYSTEM_ERR);
830
831 nfs = nfs_inherited = B_FALSE;
832
833 if (zfs_prop_get(fs_handle, ZFS_PROP_SHARENFS, nfsshareopts,
834 sizeof (nfsshareopts), &source, nfssourcestr,
835 ZFS_MAXPROPLEN, B_FALSE) == 0 &&
836 strcmp(nfsshareopts, "off") != 0) {
837 if (source & ZPROP_SRC_INHERITED)
838 nfs_inherited = B_TRUE;
839 else
840 nfs = B_TRUE;
841 }
842
843 smb = smb_inherited = B_FALSE;
844 if (zfs_prop_get(fs_handle, ZFS_PROP_SHARESMB, smbshareopts,
845 sizeof (smbshareopts), &source, smbsourcestr,
846 ZFS_MAXPROPLEN, B_FALSE) == 0 &&
847 strcmp(smbshareopts, "off") != 0) {
848 if (source & ZPROP_SRC_INHERITED)
849 smb_inherited = B_TRUE;
850 else
969 if (zfsgroup == NULL)
970 return (SA_OK);
971
972 /*
973 * need to walk the mounted ZFS pools and datasets to
974 * find shares that are possible.
975 */
976 get_all_filesystems((sa_handle_impl_t)handle, &zlist, &count);
977 qsort(zlist, count, sizeof (void *), mountpoint_compare);
978
979 for (int i = 0; i < count; i++) {
980 err = sa_get_zfs_share_common(handle, zlist[i], NULL, zfsgroup);
981 }
982 /*
983 * Don't need to free the "zlist" variable since it is only a
984 * pointer to a cached value that will be freed when
985 * sa_fini() is called.
986 */
987 return (err);
988 }
989
990 /*
991 * Initializes shares for only the dataset specified fs_handle.
992 * This is used as a performance optimization relative to sa_get_zfs_shares.
993 */
994 int
995 sa_get_zfs_share(sa_handle_t handle, char *groupname, zfs_handle_t *fs_handle)
996 {
997 sa_group_t zfsgroup;
998 libzfs_handle_t *zfs_libhandle;
999 int err;
1000
1001 if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
1002 &zfsgroup, &err)) != SA_OK) {
1003 return (err);
1004 }
1005 /* Not an error, this could be a legacy condition */
1006 if (zfsgroup == NULL)
1007 return (SA_OK);
1008
1009 err = sa_get_zfs_share_common(handle, fs_handle, NULL, zfsgroup);
1010 return (err);
1011 }
1012
1013 /*
1014 * Initializes only the handles specified in the sharearg for use with libshare.
1015 * This is used as a performance optimization relative to sa_get_zfs_shares.
1016 */
1017 int
1018 sa_get_one_zfs_share(sa_handle_t handle, char *groupname,
1019 sa_init_selective_arg_t *sharearg, char ***paths, size_t *paths_len)
1020 {
1021 sa_group_t zfsgroup;
1022 libzfs_handle_t *zfs_libhandle;
1023 int err;
1024
1025 if ((err = prep_zfs_handle_and_group(handle, groupname, &zfs_libhandle,
1026 &zfsgroup, &err)) != SA_OK) {
1027 return (err);
1028 }
1029 /* Not an error, this could be a legacy condition */
1030 if (zfsgroup == NULL)
1031 return (SA_OK);
|