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));