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