Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
NEX-16818 Add fksmbcl development tool
NEX-17264 SMB client test tp_smbutil_013 fails after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (fix ref leaks)
@@ -29,10 +29,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: rcfile.c,v 1.1.1.2 2001/07/06 22:38:43 conrad Exp $
*/
+/*
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ */
#include <fcntl.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/stat.h>
@@ -55,11 +58,10 @@
#if 0 /* before SMF */
#define SMB_CFG_FILE "/etc/nsmb.conf"
#define OLD_SMB_CFG_FILE "/usr/local/etc/nsmb.conf"
#endif
-#define SMBFS_SHARECTL_CMD "/usr/sbin/sharectl get smbfs"
extern int smb_debug;
static struct rcfile *rc_cachelookup(const char *filename);
static struct rcsection *rc_findsect(struct rcfile *rcp, const char *sectname);
@@ -145,49 +147,92 @@
fclose(f);
return (0);
}
/*
- * Like rc_open, but does popen of command:
- * sharectl get smbfs
+ * Like rc_open, but creates a temporary file and
+ * reads the sharectl settings into it.
+ * The file is deleted when we close it.
*/
static int
-rc_popen_cmd(const char *command, struct rcfile **rcfile)
+rc_open_sharectl(struct rcfile **rcfile)
{
- struct rcfile *rcp;
- FILE *f;
+ static char template[24] = "/tmp/smbfsXXXXXX";
+ struct rcfile *rcp = NULL;
+ FILE *fp = NULL;
+ int err;
+ int fd = -1;
assert(MUTEX_HELD(&rcfile_mutex));
- f = popen(command, "r");
- if (f == NULL)
- return (errno);
- insecure_nsmbrc = 0;
+ fd = mkstemp(template);
+ if (fd < 0) {
+ err = errno;
+ goto errout;
+ }
+ fp = fdopen(fd, "w+");
+ if (fp == NULL) {
+ err = errno;
+ close(fd);
+ goto errout;
+ }
+ fd = -1; /* The fp owns this fd now. */
+
+ /*
+ * Get smbfs sharectl settings into the file.
+ */
+ if ((err = rc_scf_get_sharectl(fp)) != 0)
+ goto errout;
+
rcp = malloc(sizeof (struct rcfile));
if (rcp == NULL) {
- fclose(f);
- return (ENOMEM);
+ err = ENOMEM;
+ goto errout;
}
bzero(rcp, sizeof (struct rcfile));
- rcp->rf_name = strdup(command);
- rcp->rf_f = f;
+
+ rcp->rf_name = strdup(template);
+ if (rcp->rf_name == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ rcp->rf_f = fp;
+ rcp->rf_flags = RCFILE_DELETE_ON_CLOSE;
+
SLIST_INSERT_HEAD(&pf_head, rcp, rf_next);
+ insecure_nsmbrc = 0;
rc_parse(rcp);
*rcfile = rcp;
/* fclose(f) in rc_close */
return (0);
+
+errout:
+ if (rcp != NULL)
+ free(rcp);
+ if (fp != NULL) {
+ fclose(fp);
+ fd = -1;
+ }
+ if (fd != -1)
+ close(fd);
+
+ return (err);
}
+
static int
rc_close(struct rcfile *rcp)
{
struct rcsection *p, *n;
mutex_lock(&rcfile_mutex);
fclose(rcp->rf_f);
+ if (rcp->rf_flags & RCFILE_DELETE_ON_CLOSE)
+ (void) unlink(rcp->rf_name);
+
for (p = SLIST_FIRST(&rcp->rf_sect); p; ) {
n = p;
p = SLIST_NEXT(p, rs_next);
rc_freesect(rcp, n);
}
@@ -341,15 +386,14 @@
set_value(struct rcfile *rcp, struct rcsection *rsp, struct rckey *rkp,
char *ptr)
{
int now, new;
#ifdef DEBUG
- char *from;
+ char *from = "SMF";
- if (smb_debug)
- from = (home_nsmbrc) ?
- "user file" : "SMF";
+ if (home_nsmbrc != 0)
+ from = "user file";
#endif
if (strcmp(rkp->rk_name, "minauth") == 0) {
now = eval_minauth(rkp->rk_value);
new = eval_minauth(ptr);
@@ -659,12 +703,12 @@
smb_rc = NULL;
#if 0 /* before SMF */
fn = SMB_CFG_FILE;
error = rc_open(fn, &smb_rc);
#else
- fn = SMBFS_SHARECTL_CMD;
- error = rc_popen_cmd(fn, &smb_rc);
+ fn = "(sharectl get smbfs)";
+ error = rc_open_sharectl(&smb_rc);
#endif
if (error != 0 && error != ENOENT) {
/* Error from fopen. strerror is OK. */
fprintf(stderr, dgettext(TEXT_DOMAIN,
"Can't open %s: %s\n"), fn, strerror(errno));