1 /*
2  * CDDL HEADER START
3  *
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.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or https://opensource.org/licenses/CDDL-1.0.
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) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
24  */
25 #include "../../libzfs_impl.h"
26 #include <libzfs.h>
27 #include <libzutil.h>
28 #include <sys/sysctl.h>
29 #include <libintl.h>
30 #include <sys/linker.h>
31 #include <sys/module.h>
32 #include <sys/stat.h>
33 #include <sys/param.h>
34 
35 #ifdef IN_BASE
36 #define	ZFS_KMOD	"zfs"
37 #else
38 #define	ZFS_KMOD	"openzfs"
39 #endif
40 
41 #ifndef HAVE_EXECVPE
42 /* FreeBSD prior to 15 lacks execvpe */
43 static int
44 execvPe(const char *name, const char *path, char * const *argv,
45     char * const *envp)
46 {
47 	const char **memp;
48 	size_t cnt, lp, ln;
49 	int eacces, save_errno;
50 	char buf[MAXPATHLEN];
51 	const char *bp, *np, *op, *p;
52 	struct stat sb;
53 
54 	eacces = 0;
55 
56 	/* If it's an absolute or relative path name, it's easy. */
57 	if (strchr(name, '/')) {
58 		bp = name;
59 		op = NULL;
60 		goto retry;
61 	}
62 	bp = buf;
63 
64 	/* If it's an empty path name, fail in the usual POSIX way. */
65 	if (*name == '\0') {
66 		errno = ENOENT;
67 		return (-1);
68 	}
69 
70 	op = path;
71 	ln = strlen(name);
72 	while (op != NULL) {
73 		np = strchrnul(op, ':');
74 
75 		/*
76 		 * It's a SHELL path -- double, leading and trailing colons
77 		 * mean the current directory.
78 		 */
79 		if (np == op) {
80 			/* Empty component. */
81 			p = ".";
82 			lp = 1;
83 		} else {
84 			/* Non-empty component. */
85 			p = op;
86 			lp = np - op;
87 		}
88 
89 		/* Advance to the next component or terminate after this. */
90 		if (*np == '\0')
91 			op = NULL;
92 		else
93 			op = np + 1;
94 
95 		/*
96 		 * If the path is too long complain.  This is a possible
97 		 * security issue; given a way to make the path too long
98 		 * the user may execute the wrong program.
99 		 */
100 		if (lp + ln + 2 > sizeof (buf)) {
101 			(void) write(STDERR_FILENO, "execvP: ", 8);
102 			(void) write(STDERR_FILENO, p, lp);
103 			(void) write(STDERR_FILENO, ": path too long\n",
104 			    16);
105 			continue;
106 		}
107 		memcpy(buf, p, lp);
108 		buf[lp] = '/';
109 		memcpy(buf + lp + 1, name, ln);
110 		buf[lp + ln + 1] = '\0';
111 
112 retry:		(void) execve(bp, argv, envp);
113 		switch (errno) {
114 		case E2BIG:
115 			goto done;
116 		case ELOOP:
117 		case ENAMETOOLONG:
118 		case ENOENT:
119 			break;
120 		case ENOEXEC:
121 			for (cnt = 0; argv[cnt]; ++cnt)
122 				;
123 
124 			/*
125 			 * cnt may be 0 above; always allocate at least
126 			 * 3 entries so that we can at least fit "sh", bp, and
127 			 * the NULL terminator.  We can rely on cnt to take into
128 			 * account the NULL terminator in all other scenarios,
129 			 * as we drop argv[0].
130 			 */
131 			memp = alloca(MAX(3, cnt + 2) * sizeof (char *));
132 			if (memp == NULL) {
133 				/* errno = ENOMEM; XXX override ENOEXEC? */
134 				goto done;
135 			}
136 			if (cnt > 0) {
137 				memp[0] = argv[0];
138 				memp[1] = bp;
139 				memcpy(memp + 2, argv + 1,
140 				    cnt * sizeof (char *));
141 			} else {
142 				memp[0] = "sh";
143 				memp[1] = bp;
144 				memp[2] = NULL;
145 			}
146 			(void) execve(_PATH_BSHELL,
147 			    __DECONST(char **, memp), envp);
148 			goto done;
149 		case ENOMEM:
150 			goto done;
151 		case ENOTDIR:
152 			break;
153 		case ETXTBSY:
154 			/*
155 			 * We used to retry here, but sh(1) doesn't.
156 			 */
157 			goto done;
158 		default:
159 			/*
160 			 * EACCES may be for an inaccessible directory or
161 			 * a non-executable file.  Call stat() to decide
162 			 * which.  This also handles ambiguities for EFAULT
163 			 * and EIO, and undocumented errors like ESTALE.
164 			 * We hope that the race for a stat() is unimportant.
165 			 */
166 			save_errno = errno;
167 			if (stat(bp, &sb) != 0)
168 				break;
169 			if (save_errno == EACCES) {
170 				eacces = 1;
171 				continue;
172 			}
173 			errno = save_errno;
174 			goto done;
175 		}
176 	}
177 	if (eacces)
178 		errno = EACCES;
179 	else
180 		errno = ENOENT;
181 done:
182 	return (-1);
183 }
184 
185 int
186 execvpe(const char *name, char * const argv[], char * const envp[])
187 {
188 	const char *path;
189 
190 	/* Get the path we're searching. */
191 	if ((path = getenv("PATH")) == NULL)
192 		path = _PATH_DEFPATH;
193 
194 	return (execvPe(name, path, argv, envp));
195 }
196 #endif /* !HAVE_EXECVPE */
197 
198 static __thread char errbuf[ERRBUFLEN];
199 
200 const char *
201 libzfs_error_init(int error)
202 {
203 	char *msg = errbuf;
204 	size_t msglen = sizeof (errbuf);
205 
206 	if (modfind("zfs") < 0) {
207 		size_t len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
208 		    "Failed to load %s module: "), ZFS_KMOD);
209 		if (len >= msglen)
210 			len = msglen - 1;
211 		msg += len;
212 		msglen -= len;
213 	}
214 
215 	(void) snprintf(msg, msglen, "%s", zfs_strerror(error));
216 
217 	return (errbuf);
218 }
219 
220 int
221 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
222 {
223 	return (lzc_ioctl_fd(hdl->libzfs_fd, request, zc));
224 }
225 
226 /*
227  * Verify the required ZFS_DEV device is available and optionally attempt
228  * to load the ZFS modules.  Under normal circumstances the modules
229  * should already have been loaded by some external mechanism.
230  */
231 int
232 libzfs_load_module(void)
233 {
234 	/*
235 	 * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain
236 	 * modfind("zfs") so out-of-base openzfs userland works with the
237 	 * in-base module.
238 	 */
239 	if (modfind("zfs") < 0) {
240 		/* Not present in kernel, try loading it. */
241 		if (kldload(ZFS_KMOD) < 0 && errno != EEXIST) {
242 			return (errno);
243 		}
244 	}
245 	return (0);
246 }
247 
248 int
249 zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
250 {
251 	(void) hdl, (void) path, (void) msg;
252 	return (0);
253 }
254 
255 int
256 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
257 {
258 	(void) hdl, (void) zhp, (void) name;
259 	return (0);
260 }
261 
262 int
263 find_shares_object(differ_info_t *di)
264 {
265 	(void) di;
266 	return (0);
267 }
268 
269 int
270 zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
271 {
272 	(void) hdl, (void) snaps;
273 	return (0);
274 }
275 
276 /*
277  * Attach/detach the given filesystem to/from the given jail.
278  */
279 int
280 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
281 {
282 	libzfs_handle_t *hdl = zhp->zfs_hdl;
283 	zfs_cmd_t zc = {"\0"};
284 	unsigned long cmd;
285 	int ret;
286 
287 	if (attach) {
288 		(void) snprintf(errbuf, sizeof (errbuf),
289 		    dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
290 	} else {
291 		(void) snprintf(errbuf, sizeof (errbuf),
292 		    dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name);
293 	}
294 
295 	switch (zhp->zfs_type) {
296 	case ZFS_TYPE_VOLUME:
297 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
298 		    "volumes can not be jailed"));
299 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
300 	case ZFS_TYPE_SNAPSHOT:
301 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
302 		    "snapshots can not be jailed"));
303 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
304 	case ZFS_TYPE_BOOKMARK:
305 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
306 		    "bookmarks can not be jailed"));
307 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
308 	case ZFS_TYPE_VDEV:
309 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
310 		    "vdevs can not be jailed"));
311 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
312 	case ZFS_TYPE_INVALID:
313 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
314 		    "invalid zfs_type_t: ZFS_TYPE_INVALID"));
315 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
316 	case ZFS_TYPE_POOL:
317 	case ZFS_TYPE_FILESYSTEM:
318 		/* OK */
319 		;
320 	}
321 	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
322 
323 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
324 	zc.zc_objset_type = DMU_OST_ZFS;
325 	zc.zc_zoneid = jailid;
326 
327 	cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
328 	if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0)
329 		zfs_standard_error(hdl, errno, errbuf);
330 
331 	return (ret);
332 }
333 
334 /*
335  * Set loader options for next boot.
336  */
337 int
338 zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
339     const char *command)
340 {
341 	zfs_cmd_t zc = {"\0"};
342 	nvlist_t *args;
343 
344 	args = fnvlist_alloc();
345 	fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid);
346 	fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid);
347 	fnvlist_add_string(args, "command", command);
348 	zcmd_write_src_nvlist(hdl, &zc, args);
349 	int error = zfs_ioctl(hdl, ZFS_IOC_NEXTBOOT, &zc);
350 	zcmd_free_nvlists(&zc);
351 	nvlist_free(args);
352 	return (error);
353 }
354 
355 /*
356  * Return allocated loaded module version, or NULL on error (with errno set)
357  */
358 char *
359 zfs_version_kernel(void)
360 {
361 	size_t l;
362 	if (sysctlbyname("vfs.zfs.version.module",
363 	    NULL, &l, NULL, 0) == -1)
364 		return (NULL);
365 	char *version = malloc(l);
366 	if (version == NULL)
367 		return (NULL);
368 	if (sysctlbyname("vfs.zfs.version.module",
369 	    version, &l, NULL, 0) == -1) {
370 		free(version);
371 		return (NULL);
372 	}
373 	return (version);
374 }
375