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