summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2019-05-29 11:18:13 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-05-29 11:18:13 +0000
commitfd807bef73987a10c8851965bae1f29ababa5f2b (patch)
tree7213c9d8c36f76303c79a89e0ee9a7ad6088057f
parent69833aafa8de6b8142d53d1a6f43e799e39fec21 (diff)
parentc938dc67d93d6388d698ee0d599fb7fce2963f92 (diff)
downloadillumos-joyent-fd807bef73987a10c8851965bae1f29ababa5f2b.tar.gz
[illumos-gate merge]
commit c938dc67d93d6388d698ee0d599fb7fce2963f92 11071 unused files after 9735 commit 2a2cfba00d7208e9a92d12f89a6a099b9c6d8c3a 10986 SMB should support "Resource SID Compression" commit c720f3a7cb73a788632c8431403e7bf9fd70717e 10984 kernel share list fails to be updated after fs import commit e0687fa3d7ea3b0bb17ed079bd9679fc2dffbf4b 10983 add mdb walker for smbd share cache commit db46347b25b03d61611dcb9b588ee786da62c918 7529 SMB shares with no permission for root fail after restart commit ca5fb90aeb170c859034d04499c5c0925679710e 10982 Would like an SMB share property to enable/disable quotas commit d4c7367e08269b5554f55db1e77ddeb28a011771 10981 Can't remove the Domain Admin from the local administrators group commit 0eb1a43f254994988a92928ccf6369af53b62774 11046 loader: module.c cstyle cleanup commit fa88c70fa54c01be933cc49fd271e5c4468f7eb8 11056 vdev_disk_io_start will panic the system if ldi_strategy returns an error. Conflicts: usr/src/uts/common/fs/zfs/vdev_disk.c
-rw-r--r--exception_lists/packaging2
-rw-r--r--manifest1
-rw-r--r--usr/src/boot/sys/boot/common/module.c1587
-rw-r--r--usr/src/cmd/mdb/Makefile.common3
-rw-r--r--usr/src/cmd/mdb/common/modules/libmlsvc/mlsvc.c197
-rw-r--r--usr/src/cmd/mdb/common/modules/libmlsvc/smb_ht.c106
-rw-r--r--usr/src/cmd/mdb/intel/amd64/libmlsvc/Makefile46
-rw-r--r--usr/src/cmd/mdb/intel/ia32/libmlsvc/Makefile45
-rw-r--r--usr/src/cmd/smbsrv/fksmbd/fksmbd_shr.c10
-rw-r--r--usr/src/cmd/smbsrv/smbadm/smbadm.c7
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_main.c12
-rw-r--r--usr/src/lib/libshare/smb/libshare_smb.c35
-rw-r--r--usr/src/lib/smbclnt/libfknsmb/common/llib-lfknsmb19
-rw-r--r--usr/src/lib/smbclnt/libfksmbfs/common/llib-lfksmbfs19
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers3
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c139
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_share.c221
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c13
-rw-r--r--usr/src/pkg/manifests/service-file-system-smb.mf4
-rwxr-xr-xusr/src/tools/quick/make-smbsrv15
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_kshare.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree.c7
-rw-r--r--usr/src/uts/common/smbsrv/smb_share.h22
23 files changed, 1534 insertions, 983 deletions
diff --git a/exception_lists/packaging b/exception_lists/packaging
index 4e54e33210..3339cfb28e 100644
--- a/exception_lists/packaging
+++ b/exception_lists/packaging
@@ -594,6 +594,8 @@ usr/lib/sparcv9/libfakekernel.so sparc
usr/lib/mdb/proc/libfksmbsrv.so
usr/lib/mdb/proc/amd64/libfksmbsrv.so i386
usr/lib/mdb/proc/sparcv9/libfksmbsrv.so sparc
+usr/lib/mdb/proc/amd64/libmlsvc.so i386
+usr/lib/mdb/proc/sparcv9/libmlsvc.so sparc
usr/lib/smbsrv/bind-helper
usr/lib/smbsrv/fksmbd
usr/lib/smbsrv/libfksmbsrv.so
diff --git a/manifest b/manifest
index aca797785d..1edaef266f 100644
--- a/manifest
+++ b/manifest
@@ -9885,6 +9885,7 @@ f usr/lib/mdb/proc/ld.so 0555 root sys
f usr/lib/mdb/proc/libavl.so 0555 root sys
f usr/lib/mdb/proc/libc.so 0555 root sys
f usr/lib/mdb/proc/libcmdutils.so 0555 root sys
+f usr/lib/mdb/proc/libmlsvc.so 0555 root sys
f usr/lib/mdb/proc/libnvpair.so 0555 root sys
f usr/lib/mdb/proc/libproc.so 0555 root sys
f usr/lib/mdb/proc/libpython2.6.so 0555 root sys
diff --git a/usr/src/boot/sys/boot/common/module.c b/usr/src/boot/sys/boot/common/module.c
index cc254b6ed6..ab16b6b8a4 100644
--- a/usr/src/boot/sys/boot/common/module.c
+++ b/usr/src/boot/sys/boot/common/module.c
@@ -54,42 +54,43 @@
struct moduledir {
char *d_path; /* path of modules directory */
- u_char *d_hints; /* content of linker.hints file */
+ uchar_t *d_hints; /* content of linker.hints file */
int d_hintsz; /* size of hints data */
int d_flags;
STAILQ_ENTRY(moduledir) d_link;
};
-static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
-static int file_load_dependencies(struct preloaded_file *base_mod);
-static char * file_search(const char *name, const char **extlist);
-static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo);
-static int file_havepath(const char *name);
-static char *mod_searchmodule(char *name, struct mod_depend *verinfo);
-static void file_insert_tail(struct preloaded_file *mp);
-struct file_metadata* metadata_next(struct file_metadata *base_mp, int type);
-static void moduledir_readhints(struct moduledir *mdp);
-static void moduledir_rebuild(void);
+static int file_load(char *, vm_offset_t, struct preloaded_file **);
+static int file_load_dependencies(struct preloaded_file *);
+static char *file_search(const char *, const char **);
+static struct kernel_module *file_findmodule(struct preloaded_file *, char *,
+ struct mod_depend *);
+static int file_havepath(const char *);
+static char *mod_searchmodule(char *, struct mod_depend *);
+static void file_insert_tail(struct preloaded_file *);
+struct file_metadata *metadata_next(struct file_metadata *, int);
+static void moduledir_readhints(struct moduledir *);
+static void moduledir_rebuild(void);
/* load address should be tweaked by first module loaded (kernel) */
-static vm_offset_t loadaddr = 0;
+static vm_offset_t loadaddr = 0;
#if defined(LOADER_FDT_SUPPORT)
-static const char *default_searchpath =
- "/boot/kernel;/boot/modules;/boot/dtb";
+static const char *default_searchpath = "/boot/kernel;/boot/modules;/boot/dtb";
#else
-static const char *default_searchpath ="/platform/i86pc";
+static const char *default_searchpath = "/platform/i86pc";
#endif
-static STAILQ_HEAD(, moduledir) moduledir_list = STAILQ_HEAD_INITIALIZER(moduledir_list);
+static STAILQ_HEAD(, moduledir) moduledir_list =
+ STAILQ_HEAD_INITIALIZER(moduledir_list);
struct preloaded_file *preloaded_files = NULL;
static const char *kld_ext_list[] = {
- ".ko",
- "",
- ".debug",
- NULL
+ ".ko",
+ "",
+ ".debug",
+ NULL
};
@@ -110,149 +111,110 @@ COMMAND_SET(load, "load", "load a kernel or module", command_load);
static int
command_load(int argc, char *argv[])
{
- char *typestr;
- int dofile, dokld, ch, error;
-
- dokld = dofile = 0;
- optind = 1;
- optreset = 1;
- typestr = NULL;
- if (argc == 1) {
- command_errmsg = "no filename specified";
- return (CMD_CRIT);
- }
- while ((ch = getopt(argc, argv, "kt:")) != -1) {
- switch(ch) {
- case 'k':
- dokld = 1;
- break;
- case 't':
- typestr = optarg;
- dofile = 1;
- break;
- case '?':
- default:
- /* getopt has already reported an error */
- return (CMD_OK);
+ char *typestr;
+ int dofile, dokld, ch, error;
+
+ dokld = dofile = 0;
+ optind = 1;
+ optreset = 1;
+ typestr = NULL;
+ if (argc == 1) {
+ command_errmsg = "no filename specified";
+ return (CMD_CRIT);
}
- }
- argv += (optind - 1);
- argc -= (optind - 1);
-
- printf("Loading %s...\n", argv[1]);
- /*
- * Request to load a raw file?
- */
- if (dofile) {
- if ((typestr == NULL) || (*typestr == 0)) {
- command_errmsg = "invalid load type";
- return (CMD_CRIT);
+ while ((ch = getopt(argc, argv, "kt:")) != -1) {
+ switch (ch) {
+ case 'k':
+ dokld = 1;
+ break;
+ case 't':
+ typestr = optarg;
+ dofile = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return (CMD_OK);
+ }
}
+ argv += (optind - 1);
+ argc -= (optind - 1);
- if (file_findfile(argv[1], typestr) != NULL) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "warning: file '%s' already loaded", argv[1]);
- return (CMD_WARN);
- }
+ printf("Loading %s...\n", argv[1]);
+ /*
+ * Request to load a raw file?
+ */
+ if (dofile) {
+ struct preloaded_file *fp;
- if (file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1) != NULL)
- return (CMD_OK);
+ if ((typestr == NULL) || (*typestr == 0)) {
+ command_errmsg = "invalid load type";
+ return (CMD_CRIT);
+ }
- /* Failing to load mfs_root is never going to end well! */
- if (strcmp("mfs_root", typestr) == 0)
- return (CMD_FATAL);
+ if (file_findfile(argv[1], typestr) != NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: file '%s' already loaded", argv[1]);
+ return (CMD_WARN);
+ }
- return (CMD_ERROR);
- }
- /*
- * Do we have explicit KLD load ?
- */
- if (dokld || file_havepath(argv[1])) {
- error = mod_loadkld(argv[1], argc - 2, argv + 2);
- if (error == EEXIST) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "warning: KLD '%s' already loaded", argv[1]);
- return (CMD_WARN);
- }
+ fp = file_loadraw(argv[1], typestr, argc - 2, argv + 2, 1);
+ if (fp != NULL)
+ return (CMD_OK);
- return (error == 0 ? CMD_OK : CMD_CRIT);
- }
- /*
- * Looks like a request for a module.
- */
- error = mod_load(argv[1], NULL, argc - 2, argv + 2);
- if (error == EEXIST) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "warning: module '%s' already loaded", argv[1]);
- return (CMD_WARN);
- }
-
- return (error == 0 ? CMD_OK : CMD_CRIT);
-}
+ /* Failing to load mfs_root is never going to end well! */
+ if (strcmp("mfs_root", typestr) == 0)
+ return (CMD_FATAL);
-#ifdef __FreeBSD__
-COMMAND_SET(load_geli, "load_geli", "load a geli key", command_load_geli);
+ return (CMD_ERROR);
+ }
+ /*
+ * Do we have explicit KLD load ?
+ */
+ if (dokld || file_havepath(argv[1])) {
+ error = mod_loadkld(argv[1], argc - 2, argv + 2);
+ if (error == EEXIST) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: KLD '%s' already loaded", argv[1]);
+ return (CMD_WARN);
+ }
-static int
-command_load_geli(int argc, char *argv[])
-{
- char typestr[80];
- char *cp;
- int ch, num;
-
- if (argc < 3) {
- command_errmsg = "usage is [-n key#] <prov> <file>";
- return(CMD_ERROR);
- }
-
- num = 0;
- optind = 1;
- optreset = 1;
- while ((ch = getopt(argc, argv, "n:")) != -1) {
- switch(ch) {
- case 'n':
- num = strtol(optarg, &cp, 0);
- if (cp == optarg) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "bad key index '%s'", optarg);
- return(CMD_ERROR);
- }
- break;
- case '?':
- default:
- /* getopt has already reported an error */
- return(CMD_OK);
+ return (error == 0 ? CMD_OK : CMD_CRIT);
+ }
+ /*
+ * Looks like a request for a module.
+ */
+ error = mod_load(argv[1], NULL, argc - 2, argv + 2);
+ if (error == EEXIST) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: module '%s' already loaded", argv[1]);
+ return (CMD_WARN);
}
- }
- argv += (optind - 1);
- argc -= (optind - 1);
- sprintf(typestr, "%s:geli_keyfile%d", argv[1], num);
- return (file_loadraw(argv[2], typestr, 0, NULL, 1) ? CMD_OK : CMD_ERROR);
+
+ return (error == 0 ? CMD_OK : CMD_CRIT);
}
-#endif /* __FreeBSD__ */
void
unload(void)
{
- struct preloaded_file *fp;
-
- while (preloaded_files != NULL) {
- fp = preloaded_files;
- preloaded_files = preloaded_files->f_next;
- file_discard(fp);
- }
- loadaddr = 0;
- unsetenv("kernelname");
+ struct preloaded_file *fp;
+
+ while (preloaded_files != NULL) {
+ fp = preloaded_files;
+ preloaded_files = preloaded_files->f_next;
+ file_discard(fp);
+ }
+ loadaddr = 0;
+ unsetenv("kernelname");
}
COMMAND_SET(unload, "unload", "unload all modules", command_unload);
static int
-command_unload(int argc __attribute((unused)),
- char *argv[] __attribute((unused)))
+command_unload(int argc __unused, char *argv[] __unused)
{
- unload();
- return(CMD_OK);
+ unload();
+ return (CMD_OK);
}
COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
@@ -260,85 +222,91 @@ COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
static int
command_lsmod(int argc, char *argv[])
{
- struct preloaded_file *fp;
- struct kernel_module *mp;
- struct file_metadata *md;
- char lbuf[80];
- int ch, verbose, hash, ret = 0;
-
- verbose = 0;
- hash = 0;
- optind = 1;
- optreset = 1;
- while ((ch = getopt(argc, argv, "vs")) != -1) {
- switch(ch) {
- case 'v':
- verbose = 1;
- break;
- case 's':
- hash = 1;
- break;
- case '?':
- default:
- /* getopt has already reported an error */
- return(CMD_OK);
+ struct preloaded_file *fp;
+ struct kernel_module *mp;
+ struct file_metadata *md;
+ char lbuf[80];
+ int ch, verbose, hash, ret = 0;
+
+ verbose = 0;
+ hash = 0;
+ optind = 1;
+ optreset = 1;
+ while ((ch = getopt(argc, argv, "vs")) != -1) {
+ switch (ch) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 's':
+ hash = 1;
+ break;
+ case '?':
+ default:
+ /* getopt has already reported an error */
+ return (CMD_OK);
+ }
}
- }
-
- pager_open();
- for (fp = preloaded_files; fp; fp = fp->f_next) {
- sprintf(lbuf, " %p: ", (void *) fp->f_addr);
- pager_output(lbuf);
- pager_output(fp->f_name);
- sprintf(lbuf, " (%s, 0x%lx)\n", fp->f_type, (long)fp->f_size);
- if (pager_output(lbuf))
- break;
- if (fp->f_args != NULL) {
- pager_output(" args: ");
- pager_output(fp->f_args);
- if (pager_output("\n"))
- break;
- if (strcmp(fp->f_type, "hash") == 0) {
- pager_output(" contents: ");
- strncpy(lbuf, PTOV(fp->f_addr), fp->f_size);
+
+ pager_open();
+ for (fp = preloaded_files; fp; fp = fp->f_next) {
+ sprintf(lbuf, " %p: ", (void *) fp->f_addr);
+ pager_output(lbuf);
+ pager_output(fp->f_name);
+ sprintf(lbuf, " (%s, 0x%lx)\n", fp->f_type, (long)fp->f_size);
if (pager_output(lbuf))
break;
- }
- }
+ if (fp->f_args != NULL) {
+ pager_output(" args: ");
+ pager_output(fp->f_args);
+ if (pager_output("\n"))
+ break;
+ if (strcmp(fp->f_type, "hash") == 0) {
+ pager_output(" contents: ");
+ strncpy(lbuf, PTOV(fp->f_addr), fp->f_size);
+ if (pager_output(lbuf))
+ break;
+ }
+ }
- if (hash == 1) {
- void *ptr = PTOV(fp->f_addr);
+ if (hash == 1) {
+ void *ptr = PTOV(fp->f_addr);
- pager_output(" hash: ");
- sha1(ptr, fp->f_size, (uint8_t *)lbuf);
- for (int i = 0; i < SHA1_DIGEST_LENGTH; i++)
- printf("%02x", (int)(lbuf[i] & 0xff));
- if (pager_output("\n"))
- break;
- }
+ pager_output(" hash: ");
+ sha1(ptr, fp->f_size, (uint8_t *)lbuf);
+ for (int i = 0; i < SHA1_DIGEST_LENGTH; i++)
+ printf("%02x", (int)(lbuf[i] & 0xff));
+ if (pager_output("\n"))
+ break;
+ }
- if (fp->f_modules) {
- pager_output(" modules: ");
- for (mp = fp->f_modules; mp; mp = mp->m_next) {
- sprintf(lbuf, "%s.%d ", mp->m_name, mp->m_version);
- pager_output(lbuf);
- }
- if (pager_output("\n"))
- break;
- }
- if (verbose) {
- /* XXX could add some formatting smarts here to display some better */
- for (md = fp->f_metadata; md != NULL; md = md->md_next) {
- sprintf(lbuf, " 0x%04x, 0x%lx\n", md->md_type, (long) md->md_size);
- if ((ret = pager_output(lbuf)))
- break;
- }
+ if (fp->f_modules) {
+ pager_output(" modules: ");
+ for (mp = fp->f_modules; mp; mp = mp->m_next) {
+ sprintf(lbuf, "%s.%d ", mp->m_name,
+ mp->m_version);
+ pager_output(lbuf);
+ }
+ if (pager_output("\n"))
+ break;
+ }
+ if (verbose) {
+ /*
+ * XXX could add some formatting smarts here to
+ * display some better
+ */
+ for (md = fp->f_metadata; md != NULL;
+ md = md->md_next) {
+ sprintf(lbuf, " 0x%04x, 0x%lx\n",
+ md->md_type, (long)md->md_size);
+ if ((ret = pager_output(lbuf)))
+ break;
+ }
+ }
+ if (ret != 0)
+ break;
}
- if (ret)
- break;
- }
- pager_close();
- return(CMD_OK);
+ pager_close();
+ return (CMD_OK);
}
/*
@@ -347,89 +315,93 @@ command_lsmod(int argc, char *argv[])
int
file_load(char *filename, vm_offset_t dest, struct preloaded_file **result)
{
- static int last_file_format = 0;
- struct preloaded_file *fp;
- int error;
- int i;
-
- if (preloaded_files == NULL)
- last_file_format = 0;
-
- if (archsw.arch_loadaddr != NULL)
- dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
-
- error = EFTYPE;
- for (i = last_file_format, fp = NULL;
- file_formats[i] && fp == NULL; i++) {
- error = (file_formats[i]->l_load)(filename, dest, &fp);
- if (error == 0) {
- fp->f_loader = last_file_format = i; /* remember the loader */
- *result = fp;
- break;
- } else if (last_file_format == i && i != 0) {
- /* Restart from the beginning */
- i = -1;
- last_file_format = 0;
- fp = NULL;
- continue;
- }
- if (error == EFTYPE)
- continue; /* Unknown to this handler? */
- if (error) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "can't load file '%s': %s", filename, strerror(error));
- break;
+ static int last_file_format = 0;
+ struct preloaded_file *fp;
+ int error;
+ int i;
+
+ if (preloaded_files == NULL)
+ last_file_format = 0;
+
+ if (archsw.arch_loadaddr != NULL)
+ dest = archsw.arch_loadaddr(LOAD_RAW, filename, dest);
+
+ error = EFTYPE;
+ for (i = last_file_format, fp = NULL;
+ file_formats[i] && fp == NULL; i++) {
+ error = (file_formats[i]->l_load)(filename, dest, &fp);
+ if (error == 0) {
+ /* remember the loader */
+ fp->f_loader = last_file_format = i;
+ *result = fp;
+ break;
+ } else if (last_file_format == i && i != 0) {
+ /* Restart from the beginning */
+ i = -1;
+ last_file_format = 0;
+ fp = NULL;
+ continue;
+ }
+ if (error == EFTYPE)
+ continue; /* Unknown to this handler? */
+ if (error) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't load file '%s': %s", filename,
+ strerror(error));
+ break;
+ }
}
- }
- return (error);
+ return (error);
}
static int
file_load_dependencies(struct preloaded_file *base_file)
{
- struct file_metadata *md;
- struct preloaded_file *fp;
- struct mod_depend *verinfo;
- struct kernel_module *mp;
- char *dmodname;
- int error;
-
- md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
- if (md == NULL)
- return (0);
- error = 0;
- do {
- verinfo = (struct mod_depend*)md->md_data;
- dmodname = (char *)(verinfo + 1);
- if (file_findmodule(NULL, dmodname, verinfo) == NULL) {
- printf("loading required module '%s'\n", dmodname);
- error = mod_load(dmodname, verinfo, 0, NULL);
- if (error)
- break;
- /*
- * If module loaded via kld name which isn't listed
- * in the linker.hints file, we should check if it have
- * required version.
- */
- mp = file_findmodule(NULL, dmodname, verinfo);
- if (mp == NULL) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "module '%s' exists but with wrong version", dmodname);
- error = ENOENT;
- break;
- }
+ struct file_metadata *md;
+ struct preloaded_file *fp;
+ struct mod_depend *verinfo;
+ struct kernel_module *mp;
+ char *dmodname;
+ int error;
+
+ md = file_findmetadata(base_file, MODINFOMD_DEPLIST);
+ if (md == NULL)
+ return (0);
+ error = 0;
+ do {
+ verinfo = (struct mod_depend *)md->md_data;
+ dmodname = (char *)(verinfo + 1);
+ if (file_findmodule(NULL, dmodname, verinfo) == NULL) {
+ printf("loading required module '%s'\n", dmodname);
+ error = mod_load(dmodname, verinfo, 0, NULL);
+ if (error)
+ break;
+ /*
+ * If module loaded via kld name which isn't listed
+ * in the linker.hints file, we should check if it have
+ * required version.
+ */
+ mp = file_findmodule(NULL, dmodname, verinfo);
+ if (mp == NULL) {
+ snprintf(command_errbuf,
+ sizeof (command_errbuf),
+ "module '%s' exists but with wrong version",
+ dmodname);
+ error = ENOENT;
+ break;
+ }
+ }
+ md = metadata_next(md, MODINFOMD_DEPLIST);
+ } while (md);
+ if (!error)
+ return (0);
+ /* Load failed; discard everything */
+ while (base_file != NULL) {
+ fp = base_file;
+ base_file = base_file->f_next;
+ file_discard(fp);
}
- md = metadata_next(md, MODINFOMD_DEPLIST);
- } while (md);
- if (!error)
- return (0);
- /* Load failed; discard everything */
- while (base_file != NULL) {
- fp = base_file;
- base_file = base_file->f_next;
- file_discard(fp);
- }
- return (error);
+ return (error);
}
/*
@@ -642,105 +614,108 @@ build_font_module(void)
struct preloaded_file *
file_loadraw(const char *fname, char *type, int argc, char **argv, int insert)
{
- struct preloaded_file *fp;
- char *name;
- int fd, got;
- vm_offset_t laddr;
- struct stat st;
-
- /* We can't load first */
- if ((file_findfile(NULL, NULL)) == NULL) {
- command_errmsg = "can't load file before kernel";
- return(NULL);
- }
-
- /* locate the file on the load path */
- name = file_search(fname, NULL);
- if (name == NULL) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "can't find '%s'", fname);
- return(NULL);
- }
-
- if ((fd = open(name, O_RDONLY)) < 0) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "can't open '%s': %s", name, strerror(errno));
- free(name);
- return(NULL);
- }
- if (fstat(fd, &st) < 0) {
- close(fd);
- snprintf(command_errbuf, sizeof (command_errbuf),
- "stat error '%s': %s", name, strerror(errno));
- free(name);
- return(NULL);
- }
-
- if (archsw.arch_loadaddr != NULL)
- loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
- if (loadaddr == 0) {
- close(fd);
- snprintf(command_errbuf, sizeof (command_errbuf),
- "no memory to load %s", name);
- free(name);
- return(NULL);
- }
-
- laddr = loadaddr;
- for (;;) {
- /* read in 4k chunks; size is not really important */
- got = archsw.arch_readin(fd, laddr, 4096);
- if (got == 0) /* end of file */
- break;
- if (got < 0) { /* error */
- snprintf(command_errbuf, sizeof (command_errbuf),
- "error reading '%s': %s", name, strerror(errno));
- free(name);
- close(fd);
- if (archsw.arch_free_loadaddr != NULL)
- archsw.arch_free_loadaddr(loadaddr,
- (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12));
- return(NULL);
+ struct preloaded_file *fp;
+ char *name;
+ int fd, got;
+ vm_offset_t laddr;
+ struct stat st;
+
+ /* We can't load first */
+ if ((file_findfile(NULL, NULL)) == NULL) {
+ command_errmsg = "can't load file before kernel";
+ return (NULL);
}
- laddr += got;
- }
-
- /* Looks OK so far; create & populate control structure */
- fp = file_alloc();
- if (fp == NULL) {
- if (archsw.arch_free_loadaddr != NULL)
- archsw.arch_free_loadaddr(loadaddr,
- (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12));
- snprintf(command_errbuf, sizeof (command_errbuf),
- "no memory to load %s", name);
- free(name);
- close(fd);
- return (NULL);
- }
- fp->f_name = name;
- fp->f_args = unargv(argc, argv);
- fp->f_type = strdup(type);
- fp->f_metadata = NULL;
- fp->f_loader = -1;
- fp->f_addr = loadaddr;
- fp->f_size = laddr - loadaddr;
-
- if (fp->f_type == NULL ||
- (argc != 0 && fp->f_args == NULL)) {
- close(fd);
- snprintf(command_errbuf, sizeof (command_errbuf),
- "no memory to load %s", name);
- file_discard(fp);
- return (NULL);
- }
- /* recognise space consumption */
- loadaddr = laddr;
- /* Add to the list of loaded files */
- if (insert != 0)
- file_insert_tail(fp);
- close(fd);
- return(fp);
+ /* locate the file on the load path */
+ name = file_search(fname, NULL);
+ if (name == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", fname);
+ return (NULL);
+ }
+
+ if ((fd = open(name, O_RDONLY)) < 0) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't open '%s': %s", name, strerror(errno));
+ free(name);
+ return (NULL);
+ }
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "stat error '%s': %s", name, strerror(errno));
+ free(name);
+ return (NULL);
+ }
+
+ if (archsw.arch_loadaddr != NULL)
+ loadaddr = archsw.arch_loadaddr(LOAD_RAW, name, loadaddr);
+ if (loadaddr == 0) {
+ close(fd);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no memory to load %s", name);
+ free(name);
+ return (NULL);
+ }
+
+ laddr = loadaddr;
+ for (;;) {
+ /* read in 4k chunks; size is not really important */
+ got = archsw.arch_readin(fd, laddr, 4096);
+ if (got == 0) /* end of file */
+ break;
+ if (got < 0) { /* error */
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "error reading '%s': %s", name, strerror(errno));
+ free(name);
+ close(fd);
+ if (archsw.arch_free_loadaddr != NULL) {
+ archsw.arch_free_loadaddr(loadaddr,
+ (uint64_t)
+ (roundup2(st.st_size, PAGE_SIZE) >> 12));
+ }
+ return (NULL);
+ }
+ laddr += got;
+ }
+
+ /* Looks OK so far; create & populate control structure */
+ fp = file_alloc();
+ if (fp == NULL) {
+ if (archsw.arch_free_loadaddr != NULL)
+ archsw.arch_free_loadaddr(loadaddr,
+ (uint64_t)(roundup2(st.st_size, PAGE_SIZE) >> 12));
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no memory to load %s", name);
+ free(name);
+ close(fd);
+ return (NULL);
+ }
+
+ fp->f_name = name;
+ fp->f_args = unargv(argc, argv);
+ fp->f_type = strdup(type);
+ fp->f_metadata = NULL;
+ fp->f_loader = -1;
+ fp->f_addr = loadaddr;
+ fp->f_size = laddr - loadaddr;
+
+ if (fp->f_type == NULL ||
+ (argc != 0 && fp->f_args == NULL)) {
+ close(fd);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no memory to load %s", name);
+ file_discard(fp);
+ return (NULL);
+ }
+ /* recognise space consumption */
+ loadaddr = laddr;
+
+ /* Add to the list of loaded files */
+ if (insert != 0)
+ file_insert_tail(fp);
+ close(fd);
+ return (fp);
}
/*
@@ -751,33 +726,34 @@ file_loadraw(const char *fname, char *type, int argc, char **argv, int insert)
int
mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
{
- struct kernel_module *mp;
- int err;
- char *filename;
-
- if (file_havepath(modname)) {
- printf("Warning: mod_load() called instead of mod_loadkld() for module '%s'\n", modname);
- return (mod_loadkld(modname, argc, argv));
- }
- /* see if module is already loaded */
- mp = file_findmodule(NULL, modname, verinfo);
- if (mp) {
- free(mp->m_args);
- mp->m_args = unargv(argc, argv);
- snprintf(command_errbuf, sizeof (command_errbuf),
- "warning: module '%s' already loaded", mp->m_name);
- return (0);
- }
- /* locate file with the module on the search path */
- filename = mod_searchmodule(modname, verinfo);
- if (filename == NULL) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "can't find '%s'", modname);
- return (ENOENT);
- }
- err = mod_loadkld(filename, argc, argv);
- free(filename);
- return (err);
+ struct kernel_module *mp;
+ int err;
+ char *filename;
+
+ if (file_havepath(modname)) {
+ printf("Warning: mod_load() called instead of mod_loadkld() "
+ "for module '%s'\n", modname);
+ return (mod_loadkld(modname, argc, argv));
+ }
+ /* see if module is already loaded */
+ mp = file_findmodule(NULL, modname, verinfo);
+ if (mp != NULL) {
+ free(mp->m_args);
+ mp->m_args = unargv(argc, argv);
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: module '%s' already loaded", mp->m_name);
+ return (0);
+ }
+ /* locate file with the module on the search path */
+ filename = mod_searchmodule(modname, verinfo);
+ if (filename == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", modname);
+ return (ENOENT);
+ }
+ err = mod_loadkld(filename, argc, argv);
+ free(filename);
+ return (err);
}
/*
@@ -787,57 +763,57 @@ mod_load(char *modname, struct mod_depend *verinfo, int argc, char *argv[])
int
mod_loadkld(const char *kldname, int argc, char *argv[])
{
- struct preloaded_file *fp, *last_file;
- int err;
- char *filename;
-
- /*
- * Get fully qualified KLD name
- */
- filename = file_search(kldname, kld_ext_list);
- if (filename == NULL) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "can't find '%s'", kldname);
- return (ENOENT);
- }
- /*
- * Check if KLD already loaded
- */
- fp = file_findfile(filename, NULL);
- if (fp) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "warning: KLD '%s' already loaded", filename);
- free(filename);
- return (0);
- }
- for (last_file = preloaded_files;
- last_file != NULL && last_file->f_next != NULL;
- last_file = last_file->f_next)
- ;
-
- do {
- err = file_load(filename, loadaddr, &fp);
- if (err)
- break;
- fp->f_args = unargv(argc, argv);
- loadaddr = fp->f_addr + fp->f_size;
- file_insert_tail(fp); /* Add to the list of loaded files */
- if (file_load_dependencies(fp) != 0) {
- err = ENOENT;
- last_file->f_next = NULL;
- loadaddr = last_file->f_addr + last_file->f_size;
- fp = NULL;
- break;
+ struct preloaded_file *fp, *last_file;
+ int err;
+ char *filename;
+
+ /*
+ * Get fully qualified KLD name
+ */
+ filename = file_search(kldname, kld_ext_list);
+ if (filename == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "can't find '%s'", kldname);
+ return (ENOENT);
}
- } while(0);
- if (err == EFTYPE) {
- snprintf(command_errbuf, sizeof (command_errbuf),
- "don't know how to load module '%s'", filename);
- }
- if (err)
- file_discard(fp);
- free(filename);
- return (err);
+ /*
+ * Check if KLD already loaded
+ */
+ fp = file_findfile(filename, NULL);
+ if (fp != NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "warning: KLD '%s' already loaded", filename);
+ free(filename);
+ return (0);
+ }
+ for (last_file = preloaded_files;
+ last_file != NULL && last_file->f_next != NULL;
+ last_file = last_file->f_next)
+ ;
+
+ do {
+ err = file_load(filename, loadaddr, &fp);
+ if (err)
+ break;
+ fp->f_args = unargv(argc, argv);
+ loadaddr = fp->f_addr + fp->f_size;
+ file_insert_tail(fp); /* Add to the list of loaded files */
+ if (file_load_dependencies(fp) != 0) {
+ err = ENOENT;
+ last_file->f_next = NULL;
+ loadaddr = last_file->f_addr + last_file->f_size;
+ fp = NULL;
+ break;
+ }
+ } while (0);
+ if (err == EFTYPE) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "don't know how to load module '%s'", filename);
+ }
+ if (err)
+ file_discard(fp);
+ free(filename);
+ return (err);
}
/*
@@ -847,14 +823,14 @@ mod_loadkld(const char *kldname, int argc, char *argv[])
struct preloaded_file *
file_findfile(const char *name, const char *type)
{
- struct preloaded_file *fp;
-
- for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
- if (((name == NULL) || !strcmp(name, fp->f_name)) &&
- ((type == NULL) || !strcmp(type, fp->f_type)))
- break;
- }
- return (fp);
+ struct preloaded_file *fp;
+
+ for (fp = preloaded_files; fp != NULL; fp = fp->f_next) {
+ if (((name == NULL) || strcmp(name, fp->f_name) == 0) &&
+ ((type == NULL) || strcmp(type, fp->f_type) == 0))
+ break;
+ }
+ return (fp);
}
/*
@@ -863,37 +839,37 @@ file_findfile(const char *name, const char *type)
*/
struct kernel_module *
file_findmodule(struct preloaded_file *fp, char *modname,
- struct mod_depend *verinfo)
+ struct mod_depend *verinfo)
{
- struct kernel_module *mp, *best;
- int bestver, mver;
-
- if (fp == NULL) {
- for (fp = preloaded_files; fp; fp = fp->f_next) {
- mp = file_findmodule(fp, modname, verinfo);
- if (mp)
- return (mp);
+ struct kernel_module *mp, *best;
+ int bestver, mver;
+
+ if (fp == NULL) {
+ for (fp = preloaded_files; fp; fp = fp->f_next) {
+ mp = file_findmodule(fp, modname, verinfo);
+ if (mp != NULL)
+ return (mp);
+ }
+ return (NULL);
}
- return (NULL);
- }
- best = NULL;
- bestver = 0;
- for (mp = fp->f_modules; mp; mp = mp->m_next) {
- if (strcmp(modname, mp->m_name) == 0) {
- if (verinfo == NULL)
- return (mp);
- mver = mp->m_version;
- if (mver == verinfo->md_ver_preferred)
- return (mp);
- if (mver >= verinfo->md_ver_minimum &&
- mver <= verinfo->md_ver_maximum &&
- mver > bestver) {
- best = mp;
- bestver = mver;
- }
+ best = NULL;
+ bestver = 0;
+ for (mp = fp->f_modules; mp; mp = mp->m_next) {
+ if (strcmp(modname, mp->m_name) == 0) {
+ if (verinfo == NULL)
+ return (mp);
+ mver = mp->m_version;
+ if (mver == verinfo->md_ver_preferred)
+ return (mp);
+ if (mver >= verinfo->md_ver_minimum &&
+ mver <= verinfo->md_ver_maximum &&
+ mver > bestver) {
+ best = mp;
+ bestver = mver;
+ }
+ }
}
- }
- return (best);
+ return (best);
}
/*
* Make a copy of (size) bytes of data from (p), and associate them as
@@ -921,23 +897,24 @@ file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p)
struct file_metadata *
file_findmetadata(struct preloaded_file *fp, int type)
{
- struct file_metadata *md;
+ struct file_metadata *md;
- for (md = fp->f_metadata; md != NULL; md = md->md_next)
- if (md->md_type == type)
- break;
- return(md);
+ for (md = fp->f_metadata; md != NULL; md = md->md_next)
+ if (md->md_type == type)
+ break;
+ return (md);
}
struct file_metadata *
metadata_next(struct file_metadata *md, int type)
{
- if (md == NULL)
- return (NULL);
- while((md = md->md_next) != NULL)
- if (md->md_type == type)
- break;
- return (md);
+
+ if (md == NULL)
+ return (NULL);
+ while ((md = md->md_next) != NULL)
+ if (md->md_type == type)
+ break;
+ return (md);
}
static const char *emptyextlist[] = { "", NULL };
@@ -946,38 +923,39 @@ static const char *emptyextlist[] = { "", NULL };
* Check if the given file is in place and return full path to it.
*/
static char *
-file_lookup(const char *path, const char *name, int namelen, const char **extlist)
+file_lookup(const char *path, const char *name, int namelen,
+ const char **extlist)
{
- struct stat st;
- char *result, *cp;
- const char **cpp;
- int pathlen, extlen, len;
-
- pathlen = strlen(path);
- extlen = 0;
- if (extlist == NULL)
- extlist = emptyextlist;
- for (cpp = extlist; *cpp; cpp++) {
- len = strlen(*cpp);
- if (len > extlen)
- extlen = len;
- }
- result = malloc(pathlen + namelen + extlen + 2);
- if (result == NULL)
+ struct stat st;
+ char *result, *cp;
+ const char **cpp;
+ int pathlen, extlen, len;
+
+ pathlen = strlen(path);
+ extlen = 0;
+ if (extlist == NULL)
+ extlist = emptyextlist;
+ for (cpp = extlist; *cpp; cpp++) {
+ len = strlen(*cpp);
+ if (len > extlen)
+ extlen = len;
+ }
+ result = malloc(pathlen + namelen + extlen + 2);
+ if (result == NULL)
+ return (NULL);
+ bcopy(path, result, pathlen);
+ if (pathlen > 0 && result[pathlen - 1] != '/')
+ result[pathlen++] = '/';
+ cp = result + pathlen;
+ bcopy(name, cp, namelen);
+ cp += namelen;
+ for (cpp = extlist; *cpp; cpp++) {
+ strcpy(cp, *cpp);
+ if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
+ return (result);
+ }
+ free(result);
return (NULL);
- bcopy(path, result, pathlen);
- if (pathlen > 0 && result[pathlen - 1] != '/')
- result[pathlen++] = '/';
- cp = result + pathlen;
- bcopy(name, cp, namelen);
- cp += namelen;
- for (cpp = extlist; *cpp; cpp++) {
- strcpy(cp, *cpp);
- if (stat(result, &st) == 0 && S_ISREG(st.st_mode))
- return result;
- }
- free(result);
- return NULL;
}
/*
@@ -986,10 +964,10 @@ file_lookup(const char *path, const char *name, int namelen, const char **extlis
static int
file_havepath(const char *name)
{
- const char *cp;
+ const char *cp;
- archsw.arch_getdev(NULL, name, &cp);
- return (cp != name || strchr(name, '/') != NULL);
+ archsw.arch_getdev(NULL, name, &cp);
+ return (cp != name || strchr(name, '/') != NULL);
}
/*
@@ -1005,104 +983,108 @@ file_havepath(const char *name)
static char *
file_search(const char *name, const char **extlist)
{
- struct moduledir *mdp;
- struct stat sb;
- char *result;
- int namelen;
-
- /* Don't look for nothing */
- if (name == NULL)
- return(NULL);
-
- if (*name == 0)
- return(strdup(name));
-
- if (file_havepath(name)) {
- /* Qualified, so just see if it exists */
- if (stat(name, &sb) == 0)
- return(strdup(name));
- return(NULL);
- }
- moduledir_rebuild();
- result = NULL;
- namelen = strlen(name);
- STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
- result = file_lookup(mdp->d_path, name, namelen, extlist);
- if (result)
- break;
- }
- return(result);
+ struct moduledir *mdp;
+ struct stat sb;
+ char *result;
+ int namelen;
+
+ /* Don't look for nothing */
+ if (name == NULL)
+ return (NULL);
+
+ if (*name == '\0')
+ return (strdup(name));
+
+ if (file_havepath(name)) {
+ /* Qualified, so just see if it exists */
+ if (stat(name, &sb) == 0)
+ return (strdup(name));
+ return (NULL);
+ }
+ moduledir_rebuild();
+ result = NULL;
+ namelen = strlen(name);
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ result = file_lookup(mdp->d_path, name, namelen, extlist);
+ if (result != NULL)
+ break;
+ }
+ return (result);
}
#define INT_ALIGN(base, ptr) ptr = \
- (base) + (((ptr) - (base) + sizeof(int) - 1) & ~(sizeof(int) - 1))
+ (base) + (((ptr) - (base) + sizeof (int) - 1) & ~(sizeof (int) - 1))
static char *
mod_search_hints(struct moduledir *mdp, const char *modname,
- struct mod_depend *verinfo)
+ struct mod_depend *verinfo)
{
- u_char *cp, *recptr, *bufend, *best;
- char *result;
- int *intp, bestver, blen, clen, found, ival, modnamelen, reclen;
-
- moduledir_readhints(mdp);
- modnamelen = strlen(modname);
- found = 0;
- result = NULL;
- bestver = 0;
- if (mdp->d_hints == NULL)
- goto bad;
- recptr = mdp->d_hints;
- bufend = recptr + mdp->d_hintsz;
- clen = blen = 0;
- best = cp = NULL;
- while (recptr < bufend && !found) {
- intp = (int*)recptr;
- reclen = *intp++;
- ival = *intp++;
- cp = (u_char*)intp;
- switch (ival) {
- case MDT_VERSION:
- clen = *cp++;
- if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
- break;
- cp += clen;
- INT_ALIGN(mdp->d_hints, cp);
- ival = *(int*)cp;
- cp += sizeof(int);
- clen = *cp++;
- if (verinfo == NULL || ival == verinfo->md_ver_preferred) {
- found = 1;
- break;
- }
- if (ival >= verinfo->md_ver_minimum &&
- ival <= verinfo->md_ver_maximum &&
- ival > bestver) {
- bestver = ival;
- best = cp;
- blen = clen;
- }
- break;
- default:
- break;
+ uchar_t *cp, *recptr, *bufend, *best;
+ char *result;
+ int *intp, bestver, blen, clen, ival, modnamelen, reclen;
+ bool found;
+
+ moduledir_readhints(mdp);
+ modnamelen = strlen(modname);
+ found = false;
+ result = NULL;
+ bestver = 0;
+ if (mdp->d_hints == NULL)
+ goto bad;
+ recptr = mdp->d_hints;
+ bufend = recptr + mdp->d_hintsz;
+ clen = blen = 0;
+ best = cp = NULL;
+ while (recptr < bufend && !found) {
+ intp = (int *)recptr;
+ reclen = *intp++;
+ ival = *intp++;
+ cp = (uchar_t *)intp;
+ switch (ival) {
+ case MDT_VERSION:
+ clen = *cp++;
+ if (clen != modnamelen || bcmp(cp, modname, clen) != 0)
+ break;
+ cp += clen;
+ INT_ALIGN(mdp->d_hints, cp);
+ ival = *(int *)cp;
+ cp += sizeof (int);
+ clen = *cp++;
+ if (verinfo == NULL ||
+ ival == verinfo->md_ver_preferred) {
+ found = true;
+ break;
+ }
+ if (ival >= verinfo->md_ver_minimum &&
+ ival <= verinfo->md_ver_maximum &&
+ ival > bestver) {
+ bestver = ival;
+ best = cp;
+ blen = clen;
+ }
+ break;
+ default:
+ break;
+ }
+ recptr += reclen + sizeof (int);
}
- recptr += reclen + sizeof(int);
- }
- /*
- * Finally check if KLD is in the place
- */
- if (found)
- result = file_lookup(mdp->d_path, (char *)cp, clen, NULL);
- else if (best)
- result = file_lookup(mdp->d_path, (char *)best, blen, NULL);
+ /*
+ * Finally check if KLD is in the place
+ */
+ if (found)
+ result = file_lookup(mdp->d_path, (char *)cp, clen, NULL);
+ else if (best)
+ result = file_lookup(mdp->d_path, (char *)best, blen, NULL);
bad:
- /*
- * If nothing found or hints is absent - fallback to the old way
- * by using "kldname[.ko]" as module name.
- */
- if (!found && !bestver && result == NULL)
- result = file_lookup(mdp->d_path, modname, modnamelen, kld_ext_list);
- return result;
+ /*
+ * If nothing found or hints is absent - fallback to the old way
+ * by using "kldname[.ko]" as module name.
+ */
+ if (!found && bestver == 0 && result == NULL) {
+ result = file_lookup(mdp->d_path, modname, modnamelen,
+ kld_ext_list);
+ }
+ return (result);
}
/*
@@ -1111,50 +1093,50 @@ bad:
static char *
mod_searchmodule(char *name, struct mod_depend *verinfo)
{
- struct moduledir *mdp;
- char *result;
-
- moduledir_rebuild();
- /*
- * Now we ready to lookup module in the given directories
- */
- result = NULL;
- STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
- result = mod_search_hints(mdp, name, verinfo);
- if (result)
- break;
- }
-
- return(result);
+ struct moduledir *mdp;
+ char *result;
+
+ moduledir_rebuild();
+ /*
+ * Now we ready to lookup module in the given directories
+ */
+ result = NULL;
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ result = mod_search_hints(mdp, name, verinfo);
+ if (result != NULL)
+ break;
+ }
+
+ return (result);
}
int
file_addmodule(struct preloaded_file *fp, char *modname, int version,
- struct kernel_module **newmp)
+ struct kernel_module **newmp)
{
- struct kernel_module *mp;
- struct mod_depend mdepend;
-
- bzero(&mdepend, sizeof(mdepend));
- mdepend.md_ver_preferred = version;
- mp = file_findmodule(fp, modname, &mdepend);
- if (mp)
- return (EEXIST);
- mp = calloc(1, sizeof(struct kernel_module));
- if (mp == NULL)
- return (ENOMEM);
- mp->m_name = strdup(modname);
- if (mp->m_name == NULL) {
- free(mp);
- return (ENOMEM);
- }
- mp->m_version = version;
- mp->m_fp = fp;
- mp->m_next = fp->f_modules;
- fp->f_modules = mp;
- if (newmp)
- *newmp = mp;
- return (0);
+ struct kernel_module *mp;
+ struct mod_depend mdepend;
+
+ bzero(&mdepend, sizeof (mdepend));
+ mdepend.md_ver_preferred = version;
+ mp = file_findmodule(fp, modname, &mdepend);
+ if (mp != NULL)
+ return (EEXIST);
+ mp = calloc(1, sizeof (struct kernel_module));
+ if (mp == NULL)
+ return (ENOMEM);
+ mp->m_name = strdup(modname);
+ if (mp->m_name == NULL) {
+ free(mp);
+ return (ENOMEM);
+ }
+ mp->m_version = version;
+ mp->m_fp = fp;
+ mp->m_next = fp->f_modules;
+ fp->f_modules = mp;
+ if (newmp)
+ *newmp = mp;
+ return (0);
}
/*
@@ -1163,32 +1145,34 @@ file_addmodule(struct preloaded_file *fp, char *modname, int version,
void
file_discard(struct preloaded_file *fp)
{
- struct file_metadata *md, *md1;
- struct kernel_module *mp, *mp1;
- if (fp == NULL)
- return;
+ struct file_metadata *md, *md1;
+ struct kernel_module *mp, *mp1;
+
+ if (fp == NULL)
+ return;
+
+ if (archsw.arch_free_loadaddr != NULL && fp->f_addr) {
+ archsw.arch_free_loadaddr(fp->f_addr,
+ (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12));
+ }
- if (archsw.arch_free_loadaddr != NULL && fp->f_addr)
- archsw.arch_free_loadaddr(fp->f_addr,
- (uint64_t)(roundup2(fp->f_size, PAGE_SIZE) >> 12));
-
- md = fp->f_metadata;
- while (md) {
- md1 = md;
- md = md->md_next;
- free(md1);
- }
- mp = fp->f_modules;
- while (mp) {
- free(mp->m_name);
- mp1 = mp;
- mp = mp->m_next;
- free(mp1);
- }
- free(fp->f_name);
- free(fp->f_type);
- free(fp->f_args);
- free(fp);
+ md = fp->f_metadata;
+ while (md != NULL) {
+ md1 = md;
+ md = md->md_next;
+ free(md1);
+ }
+ mp = fp->f_modules;
+ while (mp != NULL) {
+ free(mp->m_name);
+ mp1 = mp;
+ mp = mp->m_next;
+ free(mp1);
+ }
+ free(fp->f_name);
+ free(fp->f_type);
+ free(fp->f_args);
+ free(fp);
}
/*
@@ -1199,7 +1183,7 @@ struct preloaded_file *
file_alloc(void)
{
- return (calloc(1, sizeof (struct preloaded_file)));
+ return (calloc(1, sizeof (struct preloaded_file)));
}
/*
@@ -1208,31 +1192,31 @@ file_alloc(void)
static void
file_insert_tail(struct preloaded_file *fp)
{
- struct preloaded_file *cm;
-
- /* Append to list of loaded file */
- fp->f_next = NULL;
- if (preloaded_files == NULL) {
- preloaded_files = fp;
- } else {
- for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
- ;
- cm->f_next = fp;
- }
+ struct preloaded_file *cm;
+
+ /* Append to list of loaded file */
+ fp->f_next = NULL;
+ if (preloaded_files == NULL) {
+ preloaded_files = fp;
+ } else {
+ for (cm = preloaded_files; cm->f_next != NULL; cm = cm->f_next)
+ ;
+ cm->f_next = fp;
+ }
}
static char *
moduledir_fullpath(struct moduledir *mdp, const char *fname)
{
- char *cp;
-
- cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
- if (cp == NULL)
- return NULL;
- strcpy(cp, mdp->d_path);
- strcat(cp, "/");
- strcat(cp, fname);
- return (cp);
+ char *cp;
+
+ cp = malloc(strlen(mdp->d_path) + strlen(fname) + 2);
+ if (cp == NULL)
+ return (NULL);
+ strcpy(cp, mdp->d_path);
+ strcat(cp, "/");
+ strcat(cp, fname);
+ return (cp);
}
/*
@@ -1241,39 +1225,39 @@ moduledir_fullpath(struct moduledir *mdp, const char *fname)
static void
moduledir_readhints(struct moduledir *mdp)
{
- struct stat st;
- char *path;
- int fd, size, version;
+ struct stat st;
+ char *path;
+ int fd, size, version;
- if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
- return;
- path = moduledir_fullpath(mdp, "linker.hints");
- if (stat(path, &st) != 0 ||
- st.st_size < (ssize_t)(sizeof(version) + sizeof(int)) ||
- st.st_size > LINKER_HINTS_MAX || (fd = open(path, O_RDONLY)) < 0) {
+ if (mdp->d_hints != NULL || (mdp->d_flags & MDIR_NOHINTS))
+ return;
+ path = moduledir_fullpath(mdp, "linker.hints");
+ if (stat(path, &st) != 0 ||
+ st.st_size < (ssize_t)(sizeof (version) + sizeof (int)) ||
+ st.st_size > LINKER_HINTS_MAX ||
+ (fd = open(path, O_RDONLY)) < 0) {
+ free(path);
+ mdp->d_flags |= MDIR_NOHINTS;
+ return;
+ }
free(path);
- mdp->d_flags |= MDIR_NOHINTS;
+ size = read(fd, &version, sizeof (version));
+ if (size != sizeof (version) || version != LINKER_HINTS_VERSION)
+ goto bad;
+ size = st.st_size - size;
+ mdp->d_hints = malloc(size);
+ if (mdp->d_hints == NULL)
+ goto bad;
+ if (read(fd, mdp->d_hints, size) != size)
+ goto bad;
+ mdp->d_hintsz = size;
+ close(fd);
return;
- }
- free(path);
- size = read(fd, &version, sizeof(version));
- if (size != sizeof(version) || version != LINKER_HINTS_VERSION)
- goto bad;
- size = st.st_size - size;
- mdp->d_hints = malloc(size);
- if (mdp->d_hints == NULL)
- goto bad;
- if (read(fd, mdp->d_hints, size) != size)
- goto bad;
- mdp->d_hintsz = size;
- close(fd);
- return;
bad:
- close(fd);
- free(mdp->d_hints);
- mdp->d_hints = NULL;
- mdp->d_flags |= MDIR_NOHINTS;
- return;
+ close(fd);
+ free(mdp->d_hints);
+ mdp->d_hints = NULL;
+ mdp->d_flags |= MDIR_NOHINTS;
}
/*
@@ -1282,62 +1266,63 @@ bad:
static void
moduledir_rebuild(void)
{
- struct moduledir *mdp, *mtmp;
- const char *path, *cp, *ep;
- size_t cplen;
-
- path = getenv("module_path");
- if (path == NULL)
- path = default_searchpath;
- /*
- * Rebuild list of module directories if it changed
- */
- STAILQ_FOREACH(mdp, &moduledir_list, d_link)
- mdp->d_flags |= MDIR_REMOVED;
-
- for (ep = path; *ep != 0; ep++) {
- cp = ep;
- for (; *ep != 0 && *ep != ';'; ep++)
- ;
+ struct moduledir *mdp, *mtmp;
+ const char *path, *cp, *ep;
+ size_t cplen;
+
+ path = getenv("module_path");
+ if (path == NULL)
+ path = default_searchpath;
/*
- * Ignore trailing slashes
+ * Rebuild list of module directories if it changed
*/
- for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/'; cplen--)
- ;
- STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
- if (strlen(mdp->d_path) != cplen || bcmp(cp, mdp->d_path, cplen) != 0)
- continue;
- mdp->d_flags &= ~MDIR_REMOVED;
- break;
- }
- if (mdp == NULL) {
- mdp = malloc(sizeof(*mdp) + cplen + 1);
- if (mdp == NULL)
- return;
- mdp->d_path = (char*)(mdp + 1);
- bcopy(cp, mdp->d_path, cplen);
- mdp->d_path[cplen] = 0;
- mdp->d_hints = NULL;
- mdp->d_flags = 0;
- STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link)
+ mdp->d_flags |= MDIR_REMOVED;
+
+ for (ep = path; *ep != 0; ep++) {
+ cp = ep;
+ for (; *ep != 0 && *ep != ';'; ep++)
+ ;
+ /*
+ * Ignore trailing slashes
+ */
+ for (cplen = ep - cp; cplen > 1 && cp[cplen - 1] == '/';
+ cplen--)
+ ;
+ STAILQ_FOREACH(mdp, &moduledir_list, d_link) {
+ if (strlen(mdp->d_path) != cplen ||
+ bcmp(cp, mdp->d_path, cplen) != 0)
+ continue;
+ mdp->d_flags &= ~MDIR_REMOVED;
+ break;
+ }
+ if (mdp == NULL) {
+ mdp = malloc(sizeof (*mdp) + cplen + 1);
+ if (mdp == NULL)
+ return;
+ mdp->d_path = (char *)(mdp + 1);
+ bcopy(cp, mdp->d_path, cplen);
+ mdp->d_path[cplen] = 0;
+ mdp->d_hints = NULL;
+ mdp->d_flags = 0;
+ STAILQ_INSERT_TAIL(&moduledir_list, mdp, d_link);
+ }
+ if (*ep == '\0')
+ break;
}
- if (*ep == 0)
- break;
- }
- /*
- * Delete unused directories if any
- */
- mdp = STAILQ_FIRST(&moduledir_list);
- while (mdp) {
- if ((mdp->d_flags & MDIR_REMOVED) == 0) {
- mdp = STAILQ_NEXT(mdp, d_link);
- } else {
- free(mdp->d_hints);
- mtmp = mdp;
- mdp = STAILQ_NEXT(mdp, d_link);
- STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
- free(mtmp);
+ /*
+ * Delete unused directories if any
+ */
+ mdp = STAILQ_FIRST(&moduledir_list);
+ while (mdp) {
+ if ((mdp->d_flags & MDIR_REMOVED) == 0) {
+ mdp = STAILQ_NEXT(mdp, d_link);
+ } else {
+ free(mdp->d_hints);
+ mtmp = mdp;
+ mdp = STAILQ_NEXT(mdp, d_link);
+ STAILQ_REMOVE(&moduledir_list, mtmp, moduledir, d_link);
+ free(mtmp);
+ }
}
- }
- return;
}
diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common
index 79b49c8ce2..4fc3f3d317 100644
--- a/usr/src/cmd/mdb/Makefile.common
+++ b/usr/src/cmd/mdb/Makefile.common
@@ -22,7 +22,7 @@
#
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2016 Joyent, Inc.
-# Copyright 2017 Nexenta Systems, Inc.
+# Copyright 2018 Nexenta Systems, Inc.
#
#
@@ -38,6 +38,7 @@ COMMON_MODULES_PROC = \
libfknsmb \
libfksmbfs \
libfksmbsrv \
+ libmlsvc \
libnvpair \
libproc \
libpython \
diff --git a/usr/src/cmd/mdb/common/modules/libmlsvc/mlsvc.c b/usr/src/cmd/mdb/common/modules/libmlsvc/mlsvc.c
new file mode 100644
index 0000000000..fdd7fc86e4
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/libmlsvc/mlsvc.c
@@ -0,0 +1,197 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * mdb module for libmlsvc, which contains interesting data structures
+ * including: the share cache
+ */
+
+#include <mdb/mdb_modapi.h>
+#include <mdb/mdb_ks.h>
+#include <mdb/mdb_ctf.h>
+
+#include <synch.h>
+#include <smbsrv/hash_table.h>
+#include <smbsrv/libsmb.h>
+#include <smbsrv/smb_share.h>
+
+#define MLSVC_OBJNAME "libmlsvc.so.1"
+#define MLSVC_SCOPE MLSVC_OBJNAME "`"
+
+#define AFLAG 1
+#define VFLAG 2
+
+typedef struct dump_shr_args {
+ uint_t dsa_opts;
+ uintptr_t dsa_hdl;
+ smb_share_t dsa_shr;
+} dump_shr_args_t;
+
+/*ARGSUSED*/
+static int
+dump_shr_cb(uintptr_t addr, const void *data, void *varg)
+{
+ dump_shr_args_t *args = varg;
+ const HT_ITEM *hi = data;
+ smb_share_t *shr = &args->dsa_shr;
+
+ if (hi->hi_data == NULL)
+ return (WALK_NEXT);
+
+ if ((hi->hi_flags & HT_DELETE) != 0 &&
+ (args->dsa_opts & AFLAG) == 0)
+ return (WALK_NEXT);
+
+ if (args->dsa_opts & VFLAG) {
+ mdb_arg_t argv;
+ int flags = DCMD_ADDRSPEC;
+
+ argv.a_type = MDB_TYPE_STRING;
+ argv.a_un.a_str = MLSVC_SCOPE "smb_share_t";
+ /* Don't fail the walk if this fails. */
+ mdb_printf("%-?p ", hi->hi_data);
+ mdb_call_dcmd("print", (uintptr_t)hi->hi_data,
+ flags, 1, &argv);
+ } else {
+ if (mdb_vread(shr, sizeof (*shr),
+ (uintptr_t)hi->hi_data) == -1) {
+ mdb_warn("failed to read %s at %p",
+ "smb_share_t", hi->hi_data);
+ return (WALK_NEXT);
+ }
+
+ mdb_printf("%-?p ", hi->hi_data);
+ mdb_printf("name=%s path=%s desc=\"%s\"\n",
+ shr->shr_name, shr->shr_path, shr->shr_cmnt);
+ }
+
+ return (WALK_NEXT);
+}
+
+
+/*
+ * *************************** Top level dcmds ****************************
+ */
+
+typedef struct mdb_smb_shr_cache {
+ HT_HANDLE *sc_cache;
+ rwlock_t sc_cache_lck;
+ mutex_t sc_mtx;
+ cond_t sc_cv;
+ uint32_t sc_state;
+ uint32_t sc_nops;
+} mdb_smb_shr_cache_t;
+
+
+static void
+smb_shr_cache_help(void)
+{
+ mdb_printf(
+ "Displays the list of shares in the smbd smb_shr_cache.\n"
+ "With -a, also show deleted entries.\n"
+ "With -v, print full smb_share_t objects.\n\n");
+}
+
+/*
+ * ::smb_shr_cache
+ */
+/*ARGSUSED*/
+static int
+smb_shr_cache_dcmd(uintptr_t addr, uint_t flags, int argc,
+ const mdb_arg_t *argv)
+{
+ dump_shr_args_t *args;
+ mdb_smb_shr_cache_t *ssc;
+
+ args = mdb_zalloc(sizeof (*args), UM_SLEEP | UM_GC);
+
+ if (mdb_getopts(argc, argv,
+ 'a', MDB_OPT_SETBITS, AFLAG, &args->dsa_opts,
+ 'v', MDB_OPT_SETBITS, VFLAG, &args->dsa_opts,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ if (!(flags & DCMD_ADDRSPEC)) {
+ GElf_Sym sym;
+
+ /* Locate the shr hash head. */
+ if (mdb_lookup_by_obj(MLSVC_OBJNAME, "smb_shr_cache", &sym)) {
+ mdb_warn("failed to lookup `smb_shr_cache'\n");
+ return (DCMD_ERR);
+ }
+ addr = sym.st_value;
+ }
+
+ ssc = mdb_zalloc(sizeof (*ssc), UM_SLEEP | UM_GC);
+ if (mdb_ctf_vread(ssc, MLSVC_SCOPE "smb_shr_cache_t",
+ "mdb_smb_shr_cache_t", addr, 0) < 0) {
+ mdb_warn("failed to read smb_shr_cache at %p", addr);
+ return (DCMD_ERR);
+ }
+
+ /* Now walk HT_HANDLE *sc_cache */
+ args->dsa_hdl = (uintptr_t)ssc->sc_cache;
+
+ if (mdb_pwalk(MLSVC_SCOPE "smb_ht_walker",
+ dump_shr_cb, args, args->dsa_hdl) == -1) {
+ mdb_warn("cannot walk smb_shr_cache list");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+}
+
+
+
+/*
+ * MDB module linkage information:
+ *
+ * We declare a list of structures describing our dcmds, a list of structures
+ * describing our walkers and a function named _mdb_init to return a pointer
+ * to our module information.
+ */
+static const mdb_dcmd_t dcmds[] = {
+
+ /* Avoiding name conflict with smbsrv`smb_shr_cache */
+ { "smbd_shr_cache",
+ "[-av]",
+ "print SMB share cache",
+ smb_shr_cache_dcmd,
+ smb_shr_cache_help },
+
+ { NULL }
+};
+
+int smb_ht_walk_init(mdb_walk_state_t *wsp);
+int smb_ht_walk_step(mdb_walk_state_t *wsp);
+
+static const mdb_walker_t walkers[] = {
+ { "smb_ht_walker",
+ "walk an smb_hash_t structure",
+ smb_ht_walk_init,
+ smb_ht_walk_step,
+ NULL,
+ NULL },
+ { NULL }
+};
+
+static const mdb_modinfo_t modinfo = {
+ MDB_API_VERSION, dcmds, walkers
+};
+
+const mdb_modinfo_t *
+_mdb_init(void)
+{
+ return (&modinfo);
+}
diff --git a/usr/src/cmd/mdb/common/modules/libmlsvc/smb_ht.c b/usr/src/cmd/mdb/common/modules/libmlsvc/smb_ht.c
new file mode 100644
index 0000000000..a060d9f0e4
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/libmlsvc/smb_ht.c
@@ -0,0 +1,106 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * walker for libsmb : smb_ht.c (hash tables)
+ */
+
+#include <mdb/mdb_modapi.h>
+#include <mdb/mdb_ks.h>
+#include <mdb/mdb_ctf.h>
+
+#include <smbsrv/hash_table.h>
+
+/* smb_ht_walk info */
+struct hw_info {
+ HT_HANDLE hw_handle; /* struct ht_handle being walked */
+ HT_TABLE_ENTRY hw_tblent;
+ HT_ITEM hw_item;
+ int hw_idx;
+};
+
+/*
+ * Walker for libsmb/smb_ht.c code. Calls the call-back function with
+ * each HT_ITEM object. Top-level is HT_HANDLE, passed to _walk_init.
+ */
+int
+smb_ht_walk_init(mdb_walk_state_t *wsp)
+{
+ struct hw_info *hw;
+ uintptr_t addr = wsp->walk_addr;
+ HT_HANDLE *ht;
+
+ if (addr == NULL) {
+ mdb_printf("require address of an HT_HANDLE\n");
+ return (WALK_ERR);
+ }
+
+ /*
+ * allocate the AVL walk data
+ */
+ wsp->walk_data = hw = mdb_zalloc(sizeof (*hw), UM_GC|UM_SLEEP);
+
+ /*
+ * get an mdb copy of the HT_HANDLE being walked
+ */
+ ht = &hw->hw_handle;
+ if (mdb_vread(ht, sizeof (*ht), wsp->walk_addr) == -1) {
+ mdb_warn("failed to read %s at %#lx",
+ "HT_HANDLE", wsp->walk_addr);
+ return (WALK_ERR);
+ }
+
+ hw->hw_idx = -1;
+ wsp->walk_addr = NULL;
+ wsp->walk_data = hw;
+
+ return (WALK_NEXT);
+}
+
+int
+smb_ht_walk_step(mdb_walk_state_t *wsp)
+{
+ struct hw_info *hw = wsp->walk_data;
+ HT_TABLE_ENTRY *he = &hw->hw_tblent;
+ HT_ITEM *hi = &hw->hw_item;
+ uintptr_t he_addr;
+ int rv;
+
+ while (wsp->walk_addr == NULL) {
+ if (++hw->hw_idx >= hw->hw_handle.ht_table_size)
+ return (WALK_DONE);
+ he_addr = (uintptr_t)hw->hw_handle.ht_table +
+ (hw->hw_idx * sizeof (HT_TABLE_ENTRY));
+ if (mdb_vread(he, sizeof (*he), he_addr) == -1) {
+ mdb_warn("failed to read %s at %p",
+ "HT_TABLE_ENTRY", wsp->walk_addr);
+ return (WALK_ERR);
+ }
+ wsp->walk_addr = (uintptr_t)he->he_head;
+ }
+
+ if (mdb_vread(hi, sizeof (*hi), wsp->walk_addr) == -1) {
+ mdb_warn("failed to read %s at %p",
+ "HT_ITEM", wsp->walk_addr);
+ return (WALK_ERR);
+ }
+
+ rv = wsp->walk_callback(wsp->walk_addr, hi,
+ wsp->walk_cbdata);
+
+ wsp->walk_addr = (uintptr_t)hi->hi_next;
+
+ return (rv);
+}
diff --git a/usr/src/cmd/mdb/intel/amd64/libmlsvc/Makefile b/usr/src/cmd/mdb/intel/amd64/libmlsvc/Makefile
new file mode 100644
index 0000000000..33157930f7
--- /dev/null
+++ b/usr/src/cmd/mdb/intel/amd64/libmlsvc/Makefile
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 http://www.opensolaris.org/os/licensing.
+# 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 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+#
+
+MODULE = libmlsvc.so
+MDBTGT = proc
+
+MODSRCS = mlsvc.c smb_ht.c
+
+include ../../../../Makefile.cmd
+include ../../../../Makefile.cmd.64
+include ../../Makefile.amd64
+include ../../../Makefile.module
+
+MODSRCS_DIR = ../../../common/modules/libmlsvc
+
+# CPPFLAGS += -I$(SRC)/lib/smbsrv/libmlsvc
+CPPFLAGS += -I$(SRC)/uts/common
+
+CSTD= $(CSTD_GNU99)
+C99MODE= -xc99=%all
+C99LMODE= -Xc99=%all
diff --git a/usr/src/cmd/mdb/intel/ia32/libmlsvc/Makefile b/usr/src/cmd/mdb/intel/ia32/libmlsvc/Makefile
new file mode 100644
index 0000000000..0d889ab4ab
--- /dev/null
+++ b/usr/src/cmd/mdb/intel/ia32/libmlsvc/Makefile
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 http://www.opensolaris.org/os/licensing.
+# 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 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+#
+
+MODULE = libmlsvc.so
+MDBTGT = proc
+
+MODSRCS = mlsvc.c smb_ht.c
+
+include ../../../../Makefile.cmd
+include ../../Makefile.ia32
+include ../../../Makefile.module
+
+MODSRCS_DIR = ../../../common/modules/libmlsvc
+
+# CPPFLAGS += -I$(SRC)/lib/smbsrv/libmlsvc
+CPPFLAGS += -I$(SRC)/uts/common
+
+CSTD= $(CSTD_GNU99)
+C99MODE= -xc99=%all
+C99LMODE= -Xc99=%all
diff --git a/usr/src/cmd/smbsrv/fksmbd/fksmbd_shr.c b/usr/src/cmd/smbsrv/fksmbd/fksmbd_shr.c
index dea6e3fa00..23038f1641 100644
--- a/usr/src/cmd/smbsrv/fksmbd/fksmbd_shr.c
+++ b/usr/src/cmd/smbsrv/fksmbd/fksmbd_shr.c
@@ -123,3 +123,13 @@ smb_shr_load(void *args)
return (NULL);
}
+
+void
+smb_shr_load_execinfo()
+{
+}
+
+void
+smb_shr_unload()
+{
+}
diff --git a/usr/src/cmd/smbsrv/smbadm/smbadm.c b/usr/src/cmd/smbsrv/smbadm/smbadm.c
index f181d45556..f1c1fa800f 100644
--- a/usr/src/cmd/smbsrv/smbadm/smbadm.c
+++ b/usr/src/cmd/smbsrv/smbadm/smbadm.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -1406,13 +1406,14 @@ smbadm_group_add_del_member(char *gname, char *mname,
/*
* We are given a SID. Just use it.
*
- * We'e like the real account type if we can get it,
+ * We'd like the real account type if we can get it,
* but don't want to error out if we can't get it.
+ * Lacking other info, assume it's a group.
*/
sidstr = mname;
rc = smb_lookup_sid(sidstr, &acct);
if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS))
- acct.a_sidtype = SidTypeUnknown;
+ acct.a_sidtype = SidTypeGroup;
} else {
rc = smb_lookup_name(mname, SidTypeUnknown, &acct);
if ((rc != 0) || (acct.a_status != NT_STATUS_SUCCESS)) {
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_main.c b/usr/src/cmd/smbsrv/smbd/smbd_main.c
index 21dc7a20d1..d976c4ac16 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_main.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_main.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -630,7 +630,9 @@ smbd_refresh_handler()
/* This reloads the in-kernel config. */
(void) smbd_kernel_bind();
- smbd_load_shares();
+ /* On refresh load share properties only, not the shares themselves */
+ smb_shr_load_execinfo();
+
smbd_load_printers();
smbd_spool_start();
}
@@ -689,7 +691,7 @@ static int
smbd_already_running(void)
{
door_info_t info;
- char *door_name;
+ char *door_name;
int door;
door_name = getenv("SMBD_DOOR_NAME");
@@ -833,6 +835,10 @@ smbd_load_shares(void)
smbd_report("unable to load disk shares: %s", strerror(errno));
}
+/*
+ * This wrapper function is used to avoid casting smb_shr_load() in
+ * pthread_create() above. It is called very infrequently.
+ */
static void *
smbd_share_loader(void *args)
{
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c
index 1d3b04cf9a..79703b90ea 100644
--- a/usr/src/lib/libshare/smb/libshare_smb.c
+++ b/usr/src/lib/libshare/smb/libshare_smb.c
@@ -98,7 +98,7 @@ static sa_group_t smb_get_defaultgrp(sa_handle_t);
static int interface_validator(int, char *);
static int smb_update_optionset_props(sa_handle_t, sa_resource_t, nvlist_t *);
-static boolean_t smb_saprop_getbool(sa_optionset_t, char *);
+static boolean_t smb_saprop_getbool(sa_optionset_t, char *, boolean_t);
static boolean_t smb_saprop_getstr(sa_optionset_t, char *, char *, size_t);
static struct {
@@ -178,6 +178,7 @@ struct option_defs optdefs[] = {
{ SHOPT_GUEST, OPT_TYPE_BOOLEAN },
{ SHOPT_DFSROOT, OPT_TYPE_BOOLEAN },
{ SHOPT_DESCRIPTION, OPT_TYPE_STRING },
+ { SHOPT_QUOTAS, OPT_TYPE_BOOLEAN },
{ NULL, NULL }
};
@@ -2147,18 +2148,23 @@ smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si)
if (opts == NULL)
return (SA_OK);
- if (smb_saprop_getbool(opts, SHOPT_CATIA))
+ if (smb_saprop_getbool(opts, SHOPT_CATIA, B_FALSE))
si->shr_flags |= SMB_SHRF_CATIA;
- if (smb_saprop_getbool(opts, SHOPT_ABE))
+ if (smb_saprop_getbool(opts, SHOPT_ABE, B_FALSE))
si->shr_flags |= SMB_SHRF_ABE;
- if (smb_saprop_getbool(opts, SHOPT_GUEST))
+ if (smb_saprop_getbool(opts, SHOPT_GUEST, B_FALSE))
si->shr_flags |= SMB_SHRF_GUEST_OK;
- if (smb_saprop_getbool(opts, SHOPT_DFSROOT))
+ if (smb_saprop_getbool(opts, SHOPT_DFSROOT, B_FALSE))
si->shr_flags |= SMB_SHRF_DFSROOT;
+ /* Quotas are enabled by default. */
+ si->shr_flags |= SMB_SHRF_QUOTAS;
+ if (!smb_saprop_getbool(opts, SHOPT_QUOTAS, B_TRUE))
+ si->shr_flags &= ~SMB_SHRF_QUOTAS;
+
(void) smb_saprop_getstr(opts, SHOPT_AD_CONTAINER, si->shr_container,
sizeof (si->shr_container));
@@ -2423,20 +2429,29 @@ smb_update_optionset_props(sa_handle_t handle, sa_resource_t resource,
}
static boolean_t
-smb_saprop_getbool(sa_optionset_t opts, char *propname)
+smb_saprop_getbool(sa_optionset_t opts, char *propname, boolean_t def)
{
sa_property_t prop;
char *val;
- boolean_t propval = B_FALSE;
+ boolean_t ret = def;
prop = sa_get_property(opts, propname);
if ((val = sa_get_property_attr(prop, "value")) != NULL) {
- if ((strcasecmp(val, "true") == 0) || (strcmp(val, "1") == 0))
- propval = B_TRUE;
+ if (def) {
+ /* Default is true, ret false if... */
+ if ((strcasecmp(val, "false") == 0) ||
+ (strcmp(val, "0") == 0))
+ ret = B_FALSE;
+ } else {
+ /* Default is false, ret true if... */
+ if ((strcasecmp(val, "true") == 0) ||
+ (strcmp(val, "1") == 0))
+ ret = B_TRUE;
+ }
free(val);
}
- return (propval);
+ return (ret);
}
static boolean_t
diff --git a/usr/src/lib/smbclnt/libfknsmb/common/llib-lfknsmb b/usr/src/lib/smbclnt/libfknsmb/common/llib-lfknsmb
deleted file mode 100644
index 8ba9f62607..0000000000
--- a/usr/src/lib/smbclnt/libfknsmb/common/llib-lfknsmb
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source. A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*LINTLIBRARY*/
-/*PROTOLIB1*/
-
-#include <libfknsmb.h>
diff --git a/usr/src/lib/smbclnt/libfksmbfs/common/llib-lfksmbfs b/usr/src/lib/smbclnt/libfksmbfs/common/llib-lfksmbfs
deleted file mode 100644
index 6e7f55f31d..0000000000
--- a/usr/src/lib/smbclnt/libfksmbfs/common/llib-lfksmbfs
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source. A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
- */
-
-/*LINTLIBRARY*/
-/*PROTOLIB1*/
-
-#include <libfksmbfs.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
index 4354bbc7d4..14f67bf9fa 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
@@ -20,7 +20,7 @@
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2018 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -72,6 +72,7 @@ SYMBOL_VERSION SUNWprivate {
smb_shr_iterinit;
smb_shr_list;
smb_shr_load;
+ smb_shr_load_execinfo;
smb_shr_modify;
smb_shr_remove;
smb_shr_rename;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
index 0a60a1a8fc..af6ab58a1d 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
@@ -59,8 +59,8 @@ static void netr_setup_identity(ndr_heap_t *, smb_logon_t *,
static boolean_t netr_isadmin(struct netr_validation_info3 *);
static uint32_t netr_setup_domain_groups(struct netr_validation_info3 *,
smb_ids_t *);
-static uint32_t netr_setup_token_info3(struct netr_validation_info3 *,
- smb_token_t *);
+static uint32_t netr_setup_krb5res_groups(struct krb5_validation_info *,
+ smb_ids_t *);
static uint32_t netr_setup_token_wingrps(struct netr_validation_info3 *,
smb_token_t *);
@@ -82,6 +82,7 @@ smb_decode_krb5_pac(smb_token_t *token, char *data, uint_t len)
{
struct krb5_validation_info info;
ndr_buf_t *nbuf;
+ smb_sid_t *domsid;
uint32_t status = NT_STATUS_NO_MEMORY;
int rc;
@@ -99,56 +100,53 @@ smb_decode_krb5_pac(smb_token_t *token, char *data, uint_t len)
goto out;
}
- status = netr_setup_token_info3(&info.info3, token);
-
- /* Deal with the "resource groups"? */
-
-
-out:
- if (nbuf != NULL)
- ndr_buf_fini(nbuf);
-
- return (status);
-}
-
-/*
- * Code factored out of netr_setup_token()
- */
-static uint32_t
-netr_setup_token_info3(struct netr_validation_info3 *info3,
- smb_token_t *token)
-{
- smb_sid_t *domsid;
-
- domsid = (smb_sid_t *)info3->LogonDomainId;
+ /*
+ * Copy the decoded info into the token,
+ * similar to netr_setup_token()
+ */
+ domsid = (smb_sid_t *)info.info3.LogonDomainId;
token->tkn_user.i_sid = smb_sid_splice(domsid,
- info3->UserId);
+ info.info3.UserId);
if (token->tkn_user.i_sid == NULL)
- goto errout;
+ goto out;
token->tkn_primary_grp.i_sid = smb_sid_splice(domsid,
- info3->PrimaryGroupId);
+ info.info3.PrimaryGroupId);
if (token->tkn_primary_grp.i_sid == NULL)
- goto errout;
+ goto out;
- if (info3->EffectiveName.str) {
+ if (info.info3.EffectiveName.str) {
token->tkn_account_name =
- strdup((char *)info3->EffectiveName.str);
+ strdup((char *)info.info3.EffectiveName.str);
if (token->tkn_account_name == NULL)
- goto errout;
+ goto out;
}
- if (info3->LogonDomainName.str) {
+ if (info.info3.LogonDomainName.str) {
token->tkn_domain_name =
- strdup((char *)info3->LogonDomainName.str);
+ strdup((char *)info.info3.LogonDomainName.str);
if (token->tkn_domain_name == NULL)
- goto errout;
+ goto out;
}
- return (netr_setup_token_wingrps(info3, token));
-errout:
- return (NT_STATUS_INSUFF_SERVER_RESOURCES);
+ status = netr_setup_domain_groups(&info.info3, &token->tkn_win_grps);
+ if (status != NT_STATUS_SUCCESS)
+ goto out;
+
+ if (info.rg_rid_cnt != 0) {
+ status = netr_setup_krb5res_groups(&info, &token->tkn_win_grps);
+ if (status != NT_STATUS_SUCCESS)
+ goto out;
+ }
+
+ status = netr_setup_token_wingrps(&info.info3, token);
+
+out:
+ if (nbuf != NULL)
+ ndr_buf_fini(nbuf);
+
+ return (status);
}
/*
@@ -423,6 +421,10 @@ netr_setup_token(struct netr_validation_info3 *info3, smb_logon_t *user_info,
if (token->tkn_account_name == NULL || token->tkn_domain_name == NULL)
return (NT_STATUS_NO_MEMORY);
+ status = netr_setup_domain_groups(info3, &token->tkn_win_grps);
+ if (status != NT_STATUS_SUCCESS)
+ return (status);
+
status = netr_setup_token_wingrps(info3, token);
if (status != NT_STATUS_SUCCESS)
return (status);
@@ -812,44 +814,24 @@ netr_setup_identity(ndr_heap_t *heap, smb_logon_t *user_info,
}
/*
- * Sets up domain, local and well-known group membership for the given
- * token. Two assumptions have been made here:
- *
- * a) token already contains a valid user SID so that group
- * memberships can be established
- *
- * b) token belongs to a domain user
+ * Add local and well-known group membership to the given
+ * token. Called after domain groups have been added.
*/
static uint32_t
netr_setup_token_wingrps(struct netr_validation_info3 *info3,
smb_token_t *token)
{
- smb_ids_t tkn_grps;
uint32_t status;
- tkn_grps.i_cnt = 0;
- tkn_grps.i_ids = NULL;
-
- status = netr_setup_domain_groups(info3, &tkn_grps);
- if (status != NT_STATUS_SUCCESS) {
- smb_ids_free(&tkn_grps);
- return (status);
- }
-
- status = smb_sam_usr_groups(token->tkn_user.i_sid, &tkn_grps);
- if (status != NT_STATUS_SUCCESS) {
- smb_ids_free(&tkn_grps);
+ status = smb_sam_usr_groups(token->tkn_user.i_sid,
+ &token->tkn_win_grps);
+ if (status != NT_STATUS_SUCCESS)
return (status);
- }
if (netr_isadmin(info3))
token->tkn_flags |= SMB_ATF_ADMIN;
- status = smb_wka_token_groups(token->tkn_flags, &tkn_grps);
- if (status == NT_STATUS_SUCCESS)
- token->tkn_win_grps = tkn_grps;
- else
- smb_ids_free(&tkn_grps);
+ status = smb_wka_token_groups(token->tkn_flags, &token->tkn_win_grps);
return (status);
}
@@ -912,6 +894,37 @@ netr_setup_domain_groups(struct netr_validation_info3 *info3, smb_ids_t *gids)
}
/*
+ * Converts additional "resource" groups (from krb5_validation_info)
+ * into the internal representation (gids), appending to the list
+ * already put in place by netr_setup_domain_groups().
+ */
+static uint32_t netr_setup_krb5res_groups(struct krb5_validation_info *info,
+ smb_ids_t *gids)
+{
+ smb_sid_t *domain_sid;
+ smb_id_t *ids;
+ int i, total_cnt;
+
+ total_cnt = gids->i_cnt + info->rg_rid_cnt;
+
+ gids->i_ids = realloc(gids->i_ids, total_cnt * sizeof (smb_id_t));
+ if (gids->i_ids == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ domain_sid = (smb_sid_t *)info->rg_dom_sid;
+
+ ids = gids->i_ids + gids->i_cnt;
+ for (i = 0; i < info->rg_rid_cnt; i++, gids->i_cnt++, ids++) {
+ ids->i_sid = smb_sid_splice(domain_sid, info->rg_rids[i].rid);
+ if (ids->i_sid == NULL)
+ return (NT_STATUS_NO_MEMORY);
+ ids->i_attrs = info->rg_rids[i].attributes;
+ }
+
+ return (0);
+}
+
+/*
* Determines if the given user is the domain Administrator or a
* member of Domain Admins
*/
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
index cbbb86adc2..e94938684c 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -389,6 +389,7 @@ smb_shr_add(smb_share_t *si)
struct stat st;
smb_share_t *cached_si;
nvlist_t *shrlist;
+ boolean_t created_zfs = B_FALSE;
uint32_t status;
int rc;
@@ -416,8 +417,34 @@ smb_shr_add(smb_share_t *si)
/*
* If share type is STYPE_DISKTREE then the path to the
* share should exist so that we can add the share to cache.
+ * If path is ZFS, add the .zfs/shares/<share> entry.
+ *
+ * Both actions may require privileges that main dropped,
+ * so we need to temporarily make those effective.
*/
- rc = stat(si->shr_path, &st);
+ if (smb_proc_takesem() == 0) {
+
+ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ rc = stat(si->shr_path, &st);
+ if (rc == 0) {
+ smb_shr_zfs_add(si);
+ created_zfs = B_TRUE;
+ }
+
+ (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+ smb_proc_givesem();
+ } else {
+ rc = NERR_InternalError;
+ }
if (rc != 0) {
smb_shr_cache_unlock();
return (NERR_ItemNotFound);
@@ -425,6 +452,7 @@ smb_shr_add(smb_share_t *si)
}
if ((status = smb_shr_cache_addent(si)) != NERR_Success) {
+ /* This error should be impossible after findent above. */
smb_shr_cache_unlock();
return (status);
}
@@ -440,9 +468,6 @@ smb_shr_add(smb_share_t *si)
if (rc == 0) {
smb_shr_publish(si->shr_name, si->shr_container);
- /* If path is ZFS, add the .zfs/shares/<share> entry. */
- smb_shr_zfs_add(si);
-
if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
dfs_namespace_load(si->shr_name);
@@ -450,11 +475,34 @@ smb_shr_add(smb_share_t *si)
}
}
+ /*
+ * Error code path, i.e. when the kernel could not accept
+ * the new share for some reason.
+ */
if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
smb_shr_cache_delent(si->shr_name);
smb_shr_cache_unlock();
}
+ if (created_zfs && smb_proc_takesem() == 0) {
+
+ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_shr_zfs_remove(si);
+
+ (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_proc_givesem();
+ }
+
/*
* rc == ENOENT means the shared directory doesn't exist
*/
@@ -505,9 +553,28 @@ smb_shr_remove(char *sharename)
/*
* If path is ZFS, remove the .zfs/shares/<share> entry. Need
- * to remove before cleanup of cache occurs.
+ * to remove before cleanup of cache occurs. These actions
+ * require temporary elevation of privileges.
*/
- smb_shr_zfs_remove(si);
+ if (smb_proc_takesem() == 0) {
+
+ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_shr_zfs_remove(si);
+
+ (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_proc_givesem();
+ }
+
(void) smb_shr_encode(si, &shrlist);
(void) strlcpy(container, si->shr_container, sizeof (container));
@@ -570,9 +637,25 @@ smb_shr_rename(char *from_name, char *to_name)
bcopy(from_si, &to_si, sizeof (smb_share_t));
(void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name));
-
/* If path is ZFS, rename the .zfs/shares/<share> entry. */
- smb_shr_zfs_rename(from_si, &to_si);
+ if (smb_proc_takesem() == 0) {
+
+ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_shr_zfs_rename(from_si, &to_si);
+
+ (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_proc_givesem();
+ }
if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) {
smb_shr_cache_unlock();
@@ -628,14 +711,15 @@ smb_shr_get(char *sharename, smb_share_t *si)
* o comment
* o AD container
* o host access
- * o abe
+ * o flags
*/
uint32_t
smb_shr_modify(smb_share_t *new_si)
{
+ smb_share_t old_si;
smb_share_t *si;
boolean_t adc_changed = B_FALSE;
- char old_container[MAXPATHLEN];
+ boolean_t quota_flag_changed = B_FALSE;
uint32_t access, flag;
nvlist_t *shrlist;
@@ -655,16 +739,20 @@ smb_shr_modify(smb_share_t *new_si)
return (ERROR_ACCESS_DENIED);
}
+ /*
+ * Keep a copy of what the share entry looks like before we
+ * modify it. We need this for things like unpublishing
+ * from the old share container, removing the quota dir.
+ */
+ bcopy(si, &old_si, sizeof (old_si));
+
+ /* Share comment */
(void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt));
- adc_changed = (strcmp(new_si->shr_container, si->shr_container) != 0);
- if (adc_changed) {
- /* save current container - needed for unpublishing */
- (void) strlcpy(old_container, si->shr_container,
- sizeof (old_container));
- (void) strlcpy(si->shr_container, new_si->shr_container,
- sizeof (si->shr_container));
- }
+ /* Container */
+ (void) strlcpy(si->shr_container, new_si->shr_container,
+ sizeof (si->shr_container));
+ adc_changed = (strcmp(old_si.shr_container, si->shr_container) != 0);
flag = (new_si->shr_flags & SMB_SHRF_ABE);
si->shr_flags &= ~SMB_SHRF_ABE;
@@ -682,6 +770,12 @@ smb_shr_modify(smb_share_t *new_si)
si->shr_flags &= ~SMB_SHRF_DFSROOT;
si->shr_flags |= flag;
+ flag = (new_si->shr_flags & SMB_SHRF_QUOTAS);
+ si->shr_flags &= ~SMB_SHRF_QUOTAS;
+ si->shr_flags |= flag;
+ if ((old_si.shr_flags ^ si->shr_flags) & SMB_SHRF_QUOTAS)
+ quota_flag_changed = B_TRUE;
+
flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK);
si->shr_flags &= ~SMB_SHRF_CSC_MASK;
si->shr_flags |= flag;
@@ -715,10 +809,31 @@ smb_shr_modify(smb_share_t *new_si)
}
if (adc_changed) {
- smb_shr_unpublish(new_si->shr_name, old_container);
+ smb_shr_unpublish(old_si.shr_name, old_si.shr_container);
smb_shr_publish(new_si->shr_name, new_si->shr_container);
}
+ /* The following required privileges we dropped. */
+ if (quota_flag_changed && smb_proc_takesem() == 0) {
+
+ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_shr_zfs_remove(&old_si);
+ smb_shr_zfs_add(si);
+
+ (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ,
+ PRIV_FILE_DAC_SEARCH,
+ PRIV_FILE_DAC_WRITE,
+ NULL);
+
+ smb_proc_givesem();
+ }
+
return (NERR_Success);
}
@@ -1447,10 +1562,7 @@ smb_shr_load(void *args)
char *gstate;
boolean_t gdisabled;
- (void) mutex_lock(&smb_shr_exec_mtx);
- (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
- MAXPATHLEN);
- (void) mutex_unlock(&smb_shr_exec_mtx);
+ smb_shr_load_execinfo();
if ((handle = smb_shr_sa_enter()) == NULL) {
syslog(LOG_ERR, "smb_shr_load: load failed");
@@ -1481,6 +1593,15 @@ smb_shr_load(void *args)
return (NULL);
}
+void
+smb_shr_load_execinfo()
+{
+ (void) mutex_lock(&smb_shr_exec_mtx);
+ (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
+ MAXPATHLEN);
+ (void) mutex_unlock(&smb_shr_exec_mtx);
+}
+
/*
* Load the shares contained in the specified group.
*
@@ -1648,6 +1769,16 @@ smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si)
free(val);
}
+ val = smb_shr_sa_getprop(opts, SHOPT_QUOTAS);
+ if (val != NULL) {
+ /* Turn the flag on or off */
+ smb_shr_sa_setflag(val, si, SMB_SHRF_QUOTAS);
+ free(val);
+ } else {
+ /* Default for this is enabled. */
+ si->shr_flags |= SMB_SHRF_QUOTAS;
+ }
+
val = smb_shr_sa_getprop(opts, SHOPT_CSC);
if (val != NULL) {
smb_shr_sa_csc_option(val, si);
@@ -2023,8 +2154,8 @@ smb_shr_publisher_flush(list_t *lst)
/*
* If the share path refers to a ZFS file system, add the
- * .zfs/shares/<share> object and call smb_quota_add_fs()
- * to initialize quota support for the share.
+ * .zfs/shares/<share> object and add or remove the special
+ * directory and file telling clients about quota support.
*/
static void
smb_shr_zfs_add(smb_share_t *si)
@@ -2051,26 +2182,31 @@ smb_shr_zfs_add(smb_share_t *si)
syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n",
si->shr_name, strerror(errno));
- if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
- NULL, NULL, 0, B_FALSE) == 0) {
- smb_quota_add_fs(buf);
+ ret = zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT,
+ buf, MAXPATHLEN, NULL, NULL, 0, B_FALSE);
+ if (ret != 0) {
+ syslog(LOG_INFO, "share: failed to get mountpoint: "
+ "%s\n", si->shr_name);
+ } else {
+ if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) {
+ smb_quota_add_fs(buf);
+ } else {
+ smb_quota_remove_fs(buf);
+ }
}
-
zfs_close(zfshd);
libzfs_fini(libhd);
}
/*
* If the share path refers to a ZFS file system, remove the
- * .zfs/shares/<share> object, and call smb_quota_remove_fs()
- * to end quota support for the share.
+ * .zfs/shares/<share> object.
*/
static void
smb_shr_zfs_remove(smb_share_t *si)
{
libzfs_handle_t *libhd;
- zfs_handle_t *zfshd;
int ret;
char buf[MAXPATHLEN]; /* dataset or mountpoint */
@@ -2080,23 +2216,18 @@ smb_shr_zfs_remove(smb_share_t *si)
if ((libhd = libzfs_init()) == NULL)
return;
- if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
- libzfs_fini(libhd);
- return;
- }
-
errno = 0;
ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name);
if (ret != 0 && errno != EAGAIN)
syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n",
si->shr_name, strerror(errno));
- if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
- NULL, NULL, 0, B_FALSE) == 0) {
- smb_quota_remove_fs(buf);
- }
+ /*
+ * We could remove the quotas directory here, but that adds
+ * significantly to the time required for a zpool export,
+ * so just leave it here and fixup when we share next.
+ */
- zfs_close(zfshd);
libzfs_fini(libhd);
}
@@ -2415,9 +2546,11 @@ smb_shr_encode(smb_share_t *si, nvlist_t **nvlist)
rc |= nvlist_add_string(smb, SHOPT_GUEST, "true");
if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true");
+ if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0)
+ rc |= nvlist_add_string(smb, SHOPT_QUOTAS, "true");
if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
- rc |= nvlist_add_string(smb, "Autohome", "true");
+ rc |= nvlist_add_string(smb, SHOPT_AUTOHOME, "true");
rc |= nvlist_add_uint32(smb, "uid", si->shr_uid);
rc |= nvlist_add_uint32(smb, "gid", si->shr_gid);
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
index 3cab135341..ebd261b95d 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
@@ -20,9 +20,9 @@
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 RackTop Systems.
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdlib.h>
@@ -142,8 +142,12 @@ typedef struct smb_lgmid {
uint16_t m_type;
} smb_lgmid_t;
+/* Buffer size to hold hex form of the above (>24). */
#define SMB_LGRP_MID_HEXSZ 32
+/* Size of idx,rid parts of above, in hex form. */
+#define SMB_LGRP_IDXRID_LEN 16
+
/* Member list */
typedef struct smb_lgmlist {
uint32_t m_cnt;
@@ -2039,6 +2043,10 @@ smb_lgrp_mlist_add(smb_lgmlist_t *in_members, smb_lgmid_t *newm,
* memory for out_members by calling free().
*
* in_members and out_members are hex strings.
+ *
+ * Note that we ignore the SID "type" when matching because
+ * we always want to delete when the SID part matches.
+ * The "type" part can be fiction.
*/
static int
smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
@@ -2073,7 +2081,8 @@ smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
in_list = in_members->m_ids;
for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
- if (strncmp(in_list, mid_hex, mid_hexsz)) {
+ /* Keep only those NOT matching in IDX,RID */
+ if (strncmp(in_list, mid_hex, SMB_LGRP_IDXRID_LEN)) {
(void) strncat(out_list, in_list, mid_hexsz);
out_cnt++;
}
diff --git a/usr/src/pkg/manifests/service-file-system-smb.mf b/usr/src/pkg/manifests/service-file-system-smb.mf
index bb8f384499..6a9242b816 100644
--- a/usr/src/pkg/manifests/service-file-system-smb.mf
+++ b/usr/src/pkg/manifests/service-file-system-smb.mf
@@ -21,7 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2018 Nexenta Systems, Inc. All rights reserved.
#
set name=pkg.fmri value=pkg:/service/file-system/smb@$(PKGVERS)
@@ -49,6 +49,7 @@ dir path=usr/lib/fs/smb/$(ARCH64) group=sys
dir path=usr/lib/mdb group=sys
dir path=usr/lib/mdb/kvm group=sys
dir path=usr/lib/mdb/kvm/$(ARCH64) group=sys
+dir path=usr/lib/mdb/proc group=sys
dir path=usr/lib/reparse
dir path=usr/lib/security
dir path=usr/lib/smbsrv
@@ -74,6 +75,7 @@ file path=usr/kernel/kmdb/$(ARCH64)/smbsrv group=sys mode=0555
file path=usr/lib/fs/smb/$(ARCH64)/libshare_smb.so.1
file path=usr/lib/fs/smb/libshare_smb.so.1
file path=usr/lib/mdb/kvm/$(ARCH64)/smbsrv.so group=sys mode=0555
+file path=usr/lib/mdb/proc/libmlsvc.so group=sys mode=0555
file path=usr/lib/reparse/libreparse_smb.so.1
file path=usr/lib/security/pam_smb_passwd.so.1
file path=usr/lib/smbsrv/dtrace/smbd-all.d mode=0555
diff --git a/usr/src/tools/quick/make-smbsrv b/usr/src/tools/quick/make-smbsrv
index d5809420d2..45a6f2d178 100755
--- a/usr/src/tools/quick/make-smbsrv
+++ b/usr/src/tools/quick/make-smbsrv
@@ -216,16 +216,14 @@ done
# mdb_arch is both 32-bit & 64-bit
for a in $mdb_arch
do
- (cd $SRC/cmd/mdb/$x/$a/libfksmbsrv &&
- $make $1 )
+ # We build these libraries (to the proto area), so we need to
+ # build the mdb modules for all dependent libraries too.
-# We build these libraries (to the proto area), so we need to
-# build the mdb modules too so mdb will load them.
- (cd $SRC/cmd/mdb/$x/$a/libcmdutils &&
- $make $1 )
- (cd $SRC/cmd/mdb/$x/$a/libavl &&
- $make $1 )
+ for lib in libfksmbsrv libmlsvc libcmdutils libavl
+ do
+ (cd $SRC/cmd/mdb/$x/$a/$lib && $make $1 )
+ done
done
}
@@ -272,6 +270,7 @@ usr/lib/fs/smb/$arch64/libshare_smb.so.1
usr/lib/fs/smb/libshare_smb.so.1
usr/lib/libsmbfs.so.1
usr/lib/mdb/kvm/$arch64/smbsrv.so
+usr/lib/mdb/proc/libmlsvc.so
usr/lib/reparse/libreparse_smb.so.1
usr/lib/security/pam_smb_passwd.so.1
usr/lib/smbsrv/dtrace
diff --git a/usr/src/uts/common/fs/smbsrv/smb_kshare.c b/usr/src/uts/common/fs/smbsrv/smb_kshare.c
index 62d2c080b6..b344f7a944 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_kshare.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_kshare.c
@@ -890,7 +890,9 @@ smb_kshare_decode(nvlist_t *share)
SMB_SHRF_GUEST_OK);
tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_DFSROOT,
SMB_SHRF_DFSROOT);
- tmp.shr_flags |= smb_kshare_decode_bool(smb, "Autohome",
+ tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_QUOTAS,
+ SMB_SHRF_QUOTAS);
+ tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_AUTOHOME,
SMB_SHRF_AUTOHOME);
if ((tmp.shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME) {
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c
index 0628997b9d..6e86e491d6 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c
@@ -1205,6 +1205,13 @@ smb_tree_get_flags(const smb_kshare_t *si, vfs_t *vfsp, smb_tree_t *tree)
flags |= mtype->mt_flags;
}
+ /*
+ * SMB_TREE_QUOTA will be on here if the FS is ZFS. We want to
+ * turn it OFF when the share property says false.
+ */
+ if ((si->shr_flags & SMB_SHRF_QUOTAS) == 0)
+ flags &= ~SMB_TREE_QUOTA;
+
(void) strlcpy(tree->t_typename, name, SMB_TYPENAMELEN);
(void) smb_strupr((char *)tree->t_typename);
diff --git a/usr/src/uts/common/smbsrv/smb_share.h b/usr/src/uts/common/smbsrv/smb_share.h
index b8cfba779a..d8bb0d6519 100644
--- a/usr/src/uts/common/smbsrv/smb_share.h
+++ b/usr/src/uts/common/smbsrv/smb_share.h
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
*/
@@ -57,23 +57,25 @@ extern "C" {
* name Advertised name of the share
*
* ad-container Active directory container in which the share
- * will be published
+ * will be published
*
* abe Determines whether Access Based Enumeration is applied
* to a share
*
* csc Client-side caching (CSC) options applied to this share
- * disabled The client MUST NOT cache any files
- * manual The client should not automatically cache every file
- * that it opens
- * auto The client may cache every file that it opens
- * vdo The client may cache every file that it opens
+ * disabled The client MUST NOT cache any files
+ * manual The client should not automatically cache every file
+ * that it opens
+ * auto The client may cache every file that it opens
+ * vdo The client may cache every file that it opens
* and satisfy file requests from its local cache.
*
* catia CATIA character substitution
*
* guestok Determines whether guest access is allowed
*
+ * quotas SMB quotas presented & supported (T/F)
+ *
* next three properties use access-list a al NFS
*
* ro list of hosts that will have read-only access
@@ -91,6 +93,8 @@ extern "C" {
#define SHOPT_NONE "none"
#define SHOPT_DFSROOT "dfsroot"
#define SHOPT_DESCRIPTION "description"
+#define SHOPT_QUOTAS "quotas"
+#define SHOPT_AUTOHOME "Autohome"
#define SMB_DEFAULT_SHARE_GROUP "smb"
#define SMB_PROTOCOL_NAME "smb"
@@ -170,6 +174,8 @@ extern "C" {
#define SMB_SHRF_ACC_RW 0x0400
#define SMB_SHRF_ACC_ALL 0x0F00
+#define SMB_SHRF_QUOTAS 0x1000
+
/*
* Runtime flags
*/
@@ -241,6 +247,8 @@ typedef struct smb_shr_execinfo {
int smb_shr_start(void);
void smb_shr_stop(void);
void *smb_shr_load(void *);
+void smb_shr_load_execinfo(void);
+void smb_shr_unload(void);
void smb_shr_iterinit(smb_shriter_t *);
smb_share_t *smb_shr_iterate(smb_shriter_t *);
void smb_shr_list(int, smb_shrlist_t *);